Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS Module Generation #3

Merged
merged 1 commit into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ jobs:
java-version: "17"
- run: ./gradlew build
working-directory: example
build-ios-example-flutter-plugin-example-app:
name: Build example iOS app for the Flutter plugin of the example KMP project
runs-on: macos-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
- run: ./gradlew :generateDummyFramework
working-directory: example
- run: flutter build ios --no-codesign
working-directory: example/flutter/example
build-android-example-flutter-plugin-example-app:
name: Build example Android app for the Flutter plugin of the example KMP project
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.kotlin
.gradle
.idea
build
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
## unreleased

- Update Kotlin to 2.1.0 and KSP to 2.0.21-1.0.25
- Add support for iOS module generation
- Make generated Android modules subclass MethodChannel to enable teardown

## v0.1.0-rc.0

Expand Down
54 changes: 54 additions & 0 deletions example/FlutterKmpExample.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
Pod::Spec.new do |spec|
spec.name = 'FlutterKmpExample'
spec.version = '0.1.0'
spec.homepage = 'https://github.com/voize-gmbh/flutter-kmp'
spec.source = { :http=> ''}
spec.authors = ''
spec.license = ''
spec.summary = 'Shared Kotlin code for flutter-kmp example'
spec.vendored_frameworks = 'build/cocoapods/framework/flutterkmpexample.framework'
spec.libraries = 'c++'
spec.ios.deployment_target = '11.0'
spec.dependency 'Flutter'

if !Dir.exist?('build/cocoapods/framework/flutterkmpexample.framework') || Dir.empty?('build/cocoapods/framework/flutterkmpexample.framework')
raise "

Kotlin framework 'flutterkmpexample' doesn't exist yet, so a proper Xcode project can't be generated.
'pod install' should be executed after running ':generateDummyFramework' Gradle task:

./gradlew :generateDummyFramework

Alternatively, proper pod installation is performed during Gradle sync in the IDE (if Podfile location is set)"
end

spec.xcconfig = {
'ENABLE_USER_SCRIPT_SANDBOXING' => 'NO',
}

spec.pod_target_xcconfig = {
'KOTLIN_PROJECT_PATH' => '',
'PRODUCT_MODULE_NAME' => 'flutterkmpexample',
}

spec.script_phases = [
{
:name => 'Build FlutterKmpExample',
:execution_position => :before_compile,
:shell_path => '/bin/sh',
:script => <<-SCRIPT
if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then
echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\""
exit 0
fi
set -ev
REPO_ROOT="$PODS_TARGET_SRCROOT"
"$REPO_ROOT/gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \
-Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \
-Pkotlin.native.cocoapods.archs="$ARCHS" \
-Pkotlin.native.cocoapods.configuration="$CONFIGURATION"
SCRIPT
}
]

end
35 changes: 34 additions & 1 deletion example/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.kotlinCocoapods)
alias(libs.plugins.androidLibrary)
alias(libs.plugins.ksp)
alias(libs.plugins.kotlinSerialization)
Expand All @@ -8,7 +9,6 @@ plugins {
val flutterKmpVersion = "0.1.0-rc.0"

kotlin {
targetHierarchy.default()
jvm()
androidTarget {
publishLibraryVariants("release")
Expand All @@ -18,10 +18,33 @@ kotlin {
}
}
}

iosX64()
iosArm64()
iosSimulatorArm64()

applyDefaultHierarchyTemplate()

cocoapods {
name = "FlutterKmpExample"
version = "0.1.0"

framework {
homepage = "https://github.com/voize-gmbh/flutter-kmp"
summary = "Shared Kotlin code for flutter-kmp example"
baseName = "flutterkmpexample"
}

// We can not use a specific version here, because the podspec generated by this KMP project
// will be referenced by the Flutter plugin podspec and therefore the Flutter target app.
// The target app also depends on Flutter but the Flutter.podspec it uses has a stub version (1.0.0).
// So specifying a version here will create a conflict and instead we have to rely on the assumption
// that the interop for the Flutter in the Cocoapods registry is compatible with the Flutter version used in the target app.
pod("Flutter")

ios.deploymentTarget = "11.0"
}

sourceSets {
val androidMain by getting {
dependencies {
Expand All @@ -41,6 +64,16 @@ kotlin {
implementation(libs.kotlin.test)
}
}

val iosX64Main by getting {
kotlin.srcDir("build/generated/ksp/iosX64/iosX64Main/kotlin")
}
val iosArm64Main by getting {
kotlin.srcDir("build/generated/ksp/iosArm64/iosArm64Main/kotlin")
}
val iosSimulatorArm64Main by getting {
kotlin.srcDir("build/generated/ksp/iosSimulatorArm64/iosSimulatorArm64Main/kotlin")
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,16 @@
package com.example.flutterkmpexample

import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import kotlinx.coroutines.GlobalScope

/** FlutterKmpExamplePlugin */
class FlutterKmpExamplePlugin: FlutterPlugin, MethodCallHandler {
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private lateinit var channel : MethodChannel
class FlutterKmpExamplePlugin: FlutterPlugin {
private val methodChannels = mutableListOf<MethodChannel>()

override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
MyTestClassAndroid(flutterPluginBinding.binaryMessenger, GlobalScope)

channel = MethodChannel(flutterPluginBinding.binaryMessenger, "flutter_kmp_example")
channel.setMethodCallHandler(this)
}

override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "getPlatformVersion") {
result.success("Android ${android.os.Build.VERSION.RELEASE}")
} else {
result.notImplemented()
}
methodChannels += MyTestClassAndroid(flutterPluginBinding.binaryMessenger, SharedCoroutineScope)
}

override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
methodChannels.forEach { it.setMethodCallHandler(null) }
}
}
2 changes: 2 additions & 0 deletions example/flutter/example/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/

# IntelliJ related
Expand Down
4 changes: 4 additions & 0 deletions example/flutter/example/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

# References the local FlutterKmpExample KMP project podspec.
# In a normal setup this is not needed, because the podspec should be published to a Cocoapods repository.
pod 'FlutterKmpExample', :path => '../../../FlutterKmpExample.podspec'

flutter_ios_podfile_setup

target 'Runner' do
Expand Down
35 changes: 35 additions & 0 deletions example/flutter/example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
PODS:
- Flutter (1.0.0)
- flutter_kmp_example (0.0.1):
- Flutter
- FlutterKmpExample
- FlutterKmpExample (0.1.0):
- Flutter
- integration_test (0.0.1):
- Flutter

DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_kmp_example (from `.symlinks/plugins/flutter_kmp_example/ios`)
- FlutterKmpExample (from `../../../FlutterKmpExample.podspec`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)

EXTERNAL SOURCES:
Flutter:
:path: Flutter
flutter_kmp_example:
:path: ".symlinks/plugins/flutter_kmp_example/ios"
FlutterKmpExample:
:path: "../../../FlutterKmpExample.podspec"
integration_test:
:path: ".symlinks/plugins/integration_test/ios"

SPEC CHECKSUMS:
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_kmp_example: cef86282548c3343df655b50da93fb23981c5cfd
FlutterKmpExample: 602f302c485b58e590be3d655f462b4962cdc4e3
integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e

PODFILE CHECKSUM: e7404f0a25823bf8f7692369a15b9da345aa36ad

COCOAPODS: 1.16.2
Loading