KMM Cocoapods Export (M1) Mac - kotlin-multiplatform

So i am trying to export my KMM project as iOS framework
here is my build.gradle.kts
kotlin {
android()
ios()
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.0-RC")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.2.1")
implementation("com.soywiz.korlibs.klock:klock:2.2.2")
implementation("com.ionspin.kotlin:bignum:0.3.2")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val androidMain by getting
val androidTest by getting {
dependencies {
implementation(kotlin("test-junit"))
implementation("junit:junit:4.13.2")
}
}
val iosX64Main by getting
val iosArm64Main by getting
val iosMain by getting {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
}
val iosTest by getting
}
cocoapods {
framework {
summary = "Some description for a Kotlin/Native module"
homepage = "Link to a Kotlin/Native module homepage"
baseName = "sharedCode"
isStatic = false
export(project(":sharedCode"))
transitiveExport = true
}
podfile = project.file("/Users/user/Developments/SampleApp/Podfile")
ios.deploymentTarget = "14.0"
}
}
here is my Podfile
platform :ios, '14.0'
use_frameworks!
target 'Sample App' do
pod 'sharedCode', :path => '/Users/User/Developments/KotlinMultiplatform/sharedCode'
end
Whenever i run the gradle sync from Android Studio it will throw this error
Executing of 'pod install' failed with code 1.
Error message:
Please, check that file "/Users/User/Developments/SampleApp/Podfile" contains following lines in header:
source 'https://cdn.cocoapods.org'
Please, check that each target depended on sharedCode contains following dependencies:
And then i tried to run the pod install command from my terminal and it successfully installed the cocoapods. however during build I encounter this another problem
* What went wrong:
Execution failed for task ':sharedCode:linkPodDebugFrameworkIosArm64'.
Following dependencies exported in the podDebugFramework binary are not specified as API-dependencies of a corresponding source set:
Project :sharedCode
Please add them in the API-dependencies and rerun the build.
What am I missing here? Thank you

i had the same issue.
open terminal and run vim .zshrc. add LANG=en_US.UTF-8 then save it.
This resolved problem for me.

Related

Creating Flutter Rust FFI Plugin with an XCFramework for macOS/iOS

Overview
I am trying to:
Create an FFI plugin for Flutter with flutter_rust_bridge
For iOS/macOS, use an XCFramework (seems to be the better option right now over universal libraries)
In short, I am having a really hard time getting my example project (using my flutter ffi plugin) to build.
What I've Done
Created one XCFramework from the generated rust static libraries (includes macOS, iOS, and iOS simulator static libraries). This alone was quite the headache.
Created the following flutter_mimir.podspec file in my ios and macos folders:
Pod::Spec.new do |spec|
spec.name = 'flutter_mimir'
spec.version = '0.0.1'
spec.license = { :file => '../LICENSE' }
spec.homepage = 'https://github.com/GregoryConrad/mimir'
spec.authors = { 'Gregory Conrad' => 'gregorysconrad#gmail.com' }
spec.summary = 'Embedded instance of milli'
spec.ios.deployment_target = '9.0'
spec.osx.deployment_target = '10.11'
spec.source = { :path => '.' }
spec.preserve_paths = 'EmbeddedMilli.xcframework/**/*'
spec.vendored_frameworks = 'EmbeddedMilli.xcframework'
spec.xcconfig = { 'OTHER_LDFLAGS' => '-framework EmbeddedMilli' }
# TODO clean up following (not sure if these are actually needed here?)
# Flutter.framework does not contain a i386 slice.
spec.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
spec.static_framework = true
end
Moved my created EmbeddedMilli.xcframework into the ios and macos directories.
pod install runs fine.
The Problem
When building for macOS:
Launching lib/main.dart on macOS in debug mode...
lib/main.dart:1
--- xcodebuild: WARNING: Using the first of multiple matching destinations:
{ platform:macOS, arch:arm64, id:00006000-0004695C0C06801E }
{ platform:macOS, arch:x86_64, id:00006000-0004695C0C06801E }
ld: framework not found EmbeddedMilli
clang: error: linker command failed with exit code 1 (use -v to see invocation)
How can I modify my library's podspec/project build settings to allow the example project to build?
Related
My project, and the PR I am using to add the FFI support to my library.
How to manually add a .xcframework to a Flutter iOS Plugin? (helped a lot for the podspec, but did not get my project working)
Flutter Plugin with xcframework only works with device not in ios simulator
The answer to my question arose from this GitHub thread. Here's a copy of my comment:
In case anyone else stumbles into this, I got FFI working with my cross-platform XCFramework using ffiPlugin: true (thanks to #leisim's great example with Isar!). I can't believe I didn't realize this, but my XCFramework was getting tree-shaken. Here's how I fixed it (same exact code for macOS and iOS, but cannot be symbolically linked unfortunately):
my_package.podspec
Pod::Spec.new do |spec|
spec.name = 'my_package'
spec.version = '0.0.1'
spec.license = { :file => '../LICENSE' }
spec.homepage = ''
spec.authors = { 'Your Name' => 'blabla#example.com' }
spec.summary = 'Some summary'
spec.source = { :path => '.' }
spec.source_files = 'Classes/**/*'
spec.public_header_files = 'Classes/**/*.h'
spec.vendored_frameworks = 'Frameworks/MyPackage.xcframework'
spec.ios.deployment_target = '11.0'
spec.osx.deployment_target = '10.11'
end
Classes/binding.h
void enforce_binding();
Classes/EnforceBinding.swift
public func dummyMethodToEnforceBundling() {
enforce_binding() // disable tree shaking
}
Frameworks/MyPackage.xcframework needs to have a void enforce_binding() {} function. I did this in Rust with:
/// Enforce the binding for this library (to prevent tree-shaking)
#[no_mangle]
pub extern "C" fn enforce_binding() {}

Azure DevOps Pipeline iOS Error - Kotlin multiplatform

I'm trying to build a CI/CD pipeline for my KMM project at Azure DevOps. I added the pipelines for iOS and Android. But I'm facing an error for iOS pipeline during executing the Xcode#5 task.
FYI :- I'm currently using a library called "SwiftUIFormValidator" for textField validations.
Error:- ▸
Running script '[CP-User] Build shared'
▸ Processing SwiftUIFormValidator-Info.plist
** BUILD FAILED **
The following build commands failed:
PhaseScriptExecution [CP-User]\ Build\ shared /Users/runner/Library/Developer/Xcode/DerivedData/iosApp-dongzyrxhgtfzxexzqjllvyjwgcu/Build/Intermediates.noindex/Pods.build/Release-iphoneos/shared.build/Script-4552119A071AC6BAB7327E6434237EC3.sh (in target 'shared' from project 'Pods')
My shared build.gradle file code:-
kotlin {
android()
iosX64()
cocoapods {
summary = "Some description for the Shared Module"
homepage = "Link to the Shared Module homepage"
ios.deploymentTarget = "14.1"
podfile = project.file("../iosApp/Podfile")
framework {
baseName = "shared"
}
}
Here's my pod file:-
target 'iosApp' do
source 'https://cdn.cocoapods.org'
use_frameworks!
platform :ios, '14.1'
pod 'shared', :path => '../shared'
pod 'SwiftUIFormValidator'
end
Can anyone help me where I'm doing wrong? . Thank you.

React Native - Unable to resolve module from #react-navigation. None of these files exist: node_modules/nanoid/non-secure/index.cjs

I have a React Native app that fails to build on both Android and iOS apps, (XCode, Android Studio, on a physical device). I have not changed anything inside package.json.
The error is being caused by a file (useReigsterNavigator.js) inside of the #react-navigation node_module:
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = useRegisterNavigator;
var _nonSecure = require("nanoid/non-secure");
This is the error message that comes up in the iOS simulator:
Unable to resolve module ../../../../nanoid/non-secure/index.cjs from /Users/username/Code/my-app/node_modules/#react-navigation/core/lib/commonjs/useRegisterNavigator.js:
None of these files exist:
* node_modules/nanoid/non-secure/index.cjs(.native|.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)
* node_modules/nanoid/non-secure/index.cjs/index(.native|.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)
> 1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
Why am I getting this error? The nanoid folder and the react-navigation folders exists in node_modules.
screenshot of the nanoid folder inside node_modules
screenshot of the react-navigation folder inside node_modules
I've tried a few things that have not worked:
Added a resolver to the metro.config.js file that looks for 'cjs' source extensions:
resolver: {
sourceExts: [...sourceExts, 'cjs'],
},
Have checked github issues of the following repos: nanoid, facebook metro, react-navigation to see there are no reported issues.
Deleted Pods folder and Podfile.lock and then re-installed pods with the command pod install.
Cleaned the pod cache with the command pod cache clean --all
Reset the React-native packager cache npx react-native start --reset-cache
Deleted CocoaPods, Pods, XCode DerivedData, and have performed
pod deintegration and then restarted everything with pod set up and pod install:
rm -rf ~/Library/Caches/CocoaPods; rm -rf Podsl; rm -rf ~/Library/Developer/Xcode/DerivedData/*; pod deintegrate; pod setup; pod install;
I was facing this issue while using #react-navigation with nx monorepo and fixed by adding cjs extension to resolver.sourceExts property of metro.config.js. This enables metro to read commonjs nanoid/non-secure/index.cjs file.
const { withNxMetro } = require('#nrwl/react-native');
const { getDefaultConfig } = require('metro-config');
const exclusionList = require('metro-config/src/defaults/exclusionList');
module.exports = (async () => {
const {
resolver: { sourceExts, assetExts },
} = await getDefaultConfig();
return withNxMetro(
{
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
babelTransformerPath: require.resolve('react-native-svg-transformer'),
},
resolver: {
assetExts: assetExts.filter((ext) => ext !== 'svg'),
sourceExts: [...sourceExts, 'svg', 'cjs'], // cjs added here
resolverMainFields: ['sbmodern', 'browser', 'main'],
blacklistRE: exclusionList([/\.\/dist\/.*/]),
},
},
{
// Change this to true to see debugging info.
// Useful if you have issues resolving modules
debug: false,
// all the file extensions used for imports other than 'ts', 'tsx', 'js', 'jsx'
extensions: [],
}
);
})();

Can not start new kotlin multiplatform library with dependency on exposed library

I want to use jetbrains exposed library in a kotlin multiplatform library I am writing. How do I do this?
I am getting a gradle build error that it can not find everything it needs for exposed. Here is my gradle build
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.exposed:exposed-core:0.34.1")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val jvmMain by getting
val jvmTest by getting
val jsMain by getting
val jsTest by getting
val nativeMain by getting
val nativeTest by getting
}
and I get this in the build log
Failed building KotlinMPPGradleModel
org.gradle.internal.resolve.ArtifactNotFoundException: Could not find exposed-core-0.34.1-samplessources.jar (org.jetbrains.exposed:exposed-core:0.34.1).
Searched in the following locations:
https://repo.maven.apache.org/maven2/org/jetbrains/exposed/exposed-core/0.34.1/exposed-core-0.34.1-samplessources.jar
at org.gradle.internal.resolve.result.DefaultBuildableArtifactResolveResult.notFound(DefaultBuildableArtifactResolveResult.java:28)...
This library targets jvm only, since you have native targets it isn't compatible with your common source set

Importing GoogleWebRTC pod fails: module 'GoogleWebRTC' not found

I am currently working on a Kotlin multiplatform and am trying to interface with the GoogleWebRTC pod.
The pod exists, I was able to import it in a separate project (without Kotlin multiplatform). I can see the .framework is created in my build directory, however when doing a gradle sync or building from Xcode, I get the following error:
Exception in thread "main" java.lang.Error: /var/folders/hv/9cx28nxx4gz9hj_m86bp5rx40000gn/T/tmp362966650322311128.m:1:9: fatal error: module 'GoogleWebRTC' not found
at org.jetbrains.kotlin.native.interop.indexer.UtilsKt.ensureNoCompileErrors(Utils.kt:152)
at org.jetbrains.kotlin.native.interop.indexer.ModuleSupportKt.getModulesASTFiles(ModuleSupport.kt:67)
at org.jetbrains.kotlin.native.interop.indexer.ModuleSupportKt.getModulesInfo(ModuleSupport.kt:13)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.buildNativeLibrary(main.kt:499)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.processCLib(main.kt:264)
at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.interop(main.kt:72)
at org.jetbrains.kotlin.cli.utilities.InteropCompilerKt.invokeInterop(InteropCompiler.kt:45)
at org.jetbrains.kotlin.cli.utilities.MainKt.mainImpl(main.kt:19)
at org.jetbrains.kotlin.cli.utilities.MainKt.main(main.kt:37)
Execution failed for task ':shared:cinteropGoogleWebRTCIosArm64'.
> Process 'command '/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java'' finished with non-zero exit value 1
AFNetworking seems to work fine, but adding the WebRTC pod seems to break the project.
Am I missing a limitation of Kotlin multiplatform or something?
This is my build.gradle.kts:
cocoapods {
// Configure fields required by CocoaPods.
summary = "Some description for a Kotlin/Native module"
homepage = "Link to a Kotlin/Native module homepage"
// You can change the name of the produced framework.
// By default, it is the name of the Gradle project.
frameworkName = "shared"
ios.deploymentTarget = "10.0"
pod("GoogleWebRTC", "~> 1.1")
pod("AFNetworking", "~> 4.0.0")
}
I was able to reproduce this issue but I didn't figure out the reason why.
It seems a there's something wrong with GoogleWebRTC pod and the Kotlin-native/cocoapods integration.
I've opened an issue here.
We have an official help.
It seems that the frameworks name is different from the pod name. So a possible solution could be that:
kotlin {
cocoapods {
[...]
pod("GoogleWebRTC", moduleName = "WebRTC", version = "~> 1.1")
[...]
}
[...]
}
I tried it and it works.

Resources