I created Kotlin native project to shared code between iOS and android.I did integration for cocoapods in-order to use in iOS project using POD file, Project successfully run on iOS and Android but when I tried to used iOS pod library in Kotlin native project, I start getting errors below.
I know that I have to run pod install first from Xcode in-order to compile library in Kotlin native project.
SO iOS pod library should be converted via cinterop, to use in Kotlin Native Project.
I run below command just to check either framework compile successfully or not.
./gradlew :SharedCode:packForXCode
got this error
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':SharedCode:cinteropAFNetworkingIos'.
> Cannot perform cinterop processing for AFNetworking: cannot determine headers location.
Probably the build is executed from command line.
Note that a Kotlin/Native module using CocoaPods dependencies can be built only from Xcode.
please find below Gradle file.
build.Gradle.kts
plugins {
kotlin("multiplatform")
kotlin("native.cocoapods")
}
kotlin {
//select iOS target platform depending on the Xcode environment variables
val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
::iosArm64
else
::iosX64
iOSTarget("ios") {
binaries {
framework("Shared") {
baseName = "SharedCode"
}
}
}
jvm("android")
sourceSets["commonMain"].dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
}
sourceSets["androidMain"].dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib")
}
version = "1.0.0"
cocoapods {
summary = "This is sample Summary"
homepage = "Home URL"
pod("AFNetworking", "~> 3.2.0")
}
}
val packForXcode by tasks.creating(Sync::class) {
group = "build"
//selecting the right configuration for the iOS framework depending on the Xcode environment variables
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
val framework = kotlin.targets.getByName<KotlinNativeTarget>("ios").binaries.getFramework(mode)
inputs.property("mode", mode)
dependsOn(framework.linkTask)
val targetDir = File(buildDir, "xcode-frameworks")
from({ framework.outputDirectory })
into(targetDir)
doLast {
val gradlew = File(targetDir, "gradlew")
gradlew.writeText("#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n")
gradlew.setExecutable(true)
}
}
tasks.getByName("build").dependsOn(packForXcode)```
The Kotlin/Native compiler can produce a framework for macOS and iOS out of the Kotlin code. The created framework contains all declarations and binaries needed to use it with Objective-C and Swift. The best way to understand the techniques is to try it for ourselves.
Kotlin/Native libraries help to share Kotlin code between projects. POSIX, gzip, OpenGL, Metal, Foundation, and many other popular libraries and Apple frameworks are pre-imported and included as Kotlin/Native libraries into the compiler package.
Kotlin/Native for C and iOS Development. Kotlin/Native comes with a friendly API for the iOS platform, giving developers the ability to call pretty much all of the Cocoa Touch frameworks. This means that Kotlin developers can transfer their development skills over to creating iOS apps (assuming you have a spare macOS device lying around).
A Kotlin project requires the pod () function call in build.gradle.kts ( build.gradle) for adding a Pod dependency. Each dependency requires its separate function call. You can specify the parameters for the dependency in the configuration block of the function.
Since usage of several Kotlin/Native frameworks in one Swift application is limited, you can create a single umbrella framework and export all these modules to it.
I just tried these steps and managed to extend this sample with working interop of AFNetworking framework using CocoaPods plugin. These are my steps:
step-008
branch, edit build.gradle.kts that way: add CocoaPods plugin to the plugins
section as id("org.jetbrains.kotlin.native.cocoapods")
and delete whole binaries
block from the iOSTarget specification block. This should be done because the cocoaPods plugin creates framework on it's own, and we should avoid duplication (see discussion). Instead of that block, add cocoapods
specification. This part of the script should look like that:iOSTarget("ios") {}
version = "1.0.0"
cocoapods {
summary = "This is sample Summary"
homepage = "Home URL"
pod("AFNetworking", "~> 3.2.0")
}
podspec
to generate podspec for your framework. This should be done inside of the /SharedCode/
directory, as the previous one. If the task is not presented, it means that the CocoaPods plugin was not applied correctly./native/KotlinIOS/
directory, and create Podfile there. I used these contents for is:use_frameworks!
platform :ios, '9.0'
target 'KotlinIOS' do
pod 'SharedCode', :path => '../../SharedCode'
end
The important part here is that the name corresponds to our framework name, and the relative path points on the place containing build.gradle.kts
from the first step. After Podfile creation, install pods here using pod install
from the terminal(CocoaPods should be installed).
KotlinIOS.xcworkspace
with Xcode. There, one more thing should be fixed. At this moment the KotlinIOS project is set to search for frameworks only in /SharedCode/build/Xcode-frameworks/
directory, but CocoaPods won't put anything there. So, select KotlinIOS on the left panel, open Build Settings tab and find there Search Paths -> Framework Search Paths. Press + and add $(inherited) to the list, to make available frameworks that CocoaPods installed.import cocoapods.AFNetworking.*
. For the first time it might need to invalidate Caches and Restart, to make it see this package correctly.I hope this will help. Please comment if something is unclear in this instruction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With