Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add thirdparty iOS pod library into kotlin native project ? getting error "SharedCode:cinteropAFNetworkingIos failed"

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)```




like image 900
Saood Avatar asked Feb 08 '20 11:02

Saood


People also ask

Can I code in kotlin for iOS?

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.

What are Kotlin/native libraries?

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.

Can I use Kotlin for iOS development?

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).

How to add a pod dependency in a Kotlin project?

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.

Can I use multiple Kotlin/native frameworks in one swift application?

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.


1 Answers

I just tried these steps and managed to extend this sample with working interop of AFNetworking framework using CocoaPods plugin. These are my steps:

  1. After cloning the project and checking out the 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")
    }
  1. Then, execute Gradle task 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.
  2. When the podspec is ready, we can use it from the Xcode project. To do it, open the /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).

  1. Now open generated 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.
  2. Now, execute Build from the Xcode. After that, in your Kotlin IDE the AFNetworking package should become available. To import it, use 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.

like image 138
Artyom Degtyarev Avatar answered Oct 12 '22 22:10

Artyom Degtyarev