ttypic / swift-klib-plugin

Gradle Plugin for injecting Swift code into Kotlin Multiplatform Mobile shared module
MIT License
187 stars 8 forks source link

error: cannot load underlying module for 'UIKit' #33

Closed stevdza-san closed 1 month ago

stevdza-san commented 1 month ago

First of all, thanks for creating such a useful plugin. :) I've been trying to create one simple function in swift that allows me to open up a messaging app and fill in sender/body fields. I'm planing to use that function in iosMain source-set inside the actual declaration. Chat GPT provided the following solution for that logic (Since I'm not that familiar with Swift):

import Foundation
import UIKit

@objc class SMSHandler: NSObject {
    @objc static func sendSms() {
        let sms = "sms:+1234567890&body=Hello World."
        let strURL = sms.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
        UIApplication.shared.open(URL(string: strURL)!, options: [:], completionHandler: nil)
    }
}

This file is placed inside iosApp/sms directory.

I've included the swiftklib plugin in my project, both composeApp-level and project-level build.gradle files. As far as I understood, in both of those create() functions, we need to pass a directory name inside which we have declared our Swift file that we're trying to call from Kotlin afterwards. Here's my composeApp-level build.gradle file:


listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "ComposeApp"
            isStatic = true
        }

        iosTarget.compilations {
            val main by getting {
                cinterops {
                    create("sms")
                }
            }
        }
    }

    ...

swiftklib {
    create("sms") {
        path = file("../iosApp/iosApp/sms")
        packageName("com.stevdza_san.sms")
    }
}

However, when I try to build the project, I do get this error:

> Task :composeApp:swiftklibSmsIosX64 FAILED
Building for production...
[0/4] Write sources
[1/4] Write swift-version--58304C5D6DBC2206.txt
[3/5] Compiling sms SmsManager.swift
<unknown>:0: warning: using sysroot for 'MacOSX' but targeting 'iPhone'
/Users/stevdza-san/AndroidStudioProjects/PlatiParking/composeApp/build/swiftklib/sms/iosX64/swiftBuild/sms/SmsManager.swift:2:8: error: cannot load underlying module for 'UIKit'
import UIKit
       ^
error: fatalError

fatalError
IlyaGulya commented 1 month ago

Hello, @stevdza-san! I've just made a 0.6.2 release which could possibly fix your issue. Please try the new version and let me know if the problem is fixed or not.

stevdza-san commented 1 month ago

@IlyaGulya Thanks for a quick response. I've updated the version and now I'm able to successfully rebuild the project. However, now when I try to import that package, and use the Swift class from Kotlin code, It's not recognized, instead I get some other, non-related properties and stuff:

Screenshot 2024-07-21 at 12 54 21
IlyaGulya commented 1 month ago

@stevdza-san you have to mark your declarations public to be able to access them from kotlin. For instance, in your case:

import Foundation
import UIKit

@objc public class SMSHandler: NSObject {
    @objc public static func sendSms() {
        let sms = "sms:+1234567890&body=Hello World."
        let strURL = sms.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
        UIApplication.shared.open(URL(string: strURL)!, options: [:], completionHandler: nil)
    }
}
stevdza-san commented 1 month ago

@IlyaGulya Hm, I've added the public keyword on both of them, however when I rebuild the project it's the same thing.

IlyaGulya commented 1 month ago

@stevdza-san

Can you provide a reproducer project? πŸ™‚

stevdza-san commented 1 month ago

Ah, I've invalidated and cleared the cache on my IDE. Now it works! Thanks again for your help, I'll probably do a video about this plugin, it's really helpful! Closing this issue now. πŸ™‚

santyas commented 4 weeks ago

@stevdza-san Hello! There is something strange here... I followed your video tutorial (a really well explained example πŸ‘πŸ» ) but my class function (both publics) cannot be used bc it isn't resolved. BUT if I add 'WithData' after fun name works fine πŸ₯Ή

Check my discussion post https://github.com/ttypic/swift-klib-plugin/discussions/41 with my example :)