Hello, I'm trying to connect to internet with Kotl...
# kotlin-native
k
Hello, I'm trying to connect to internet with Kotlin/Native (macOS), but it doesn't work. Could anyone tell me where is wrong? https://stackoverflow.com/questions/55349254/how-can-i-connect-through-http-in-kotlin-native-ios-development https://github.com/KenjiOhtsuka/macos_kotln_native
Copy code
object WebGateway {
    fun get(urlString: String): String {
        val semaphore = dispatch_semaphore_create(0)

        val components = NSURLComponents(urlString)
        val url = components.URL
        var result: String = ""
        val config = NSURLSessionConfiguration.defaultSessionConfiguration()
        config.waitsForConnectivity = true
        config.timeoutIntervalForResource = 300.0

        val request = NSURLRequest.requestWithURL(url!!)
        val session = NSURLSession.sessionWithConfiguration(
            config, null, NSOperationQueue.mainQueue()
        )

        val task =
            session.dataTaskWithRequest(request) { nsData: NSData?, nsurlResponse: NSURLResponse?, nsError: NSError? ->
                nsData?.run { result = toString() }
                println(nsData)
                dispatch_semaphore_signal(semaphore);
            }

        task.resume()
        session.finishTasksAndInvalidate()
        NSOperationQueue.mainQueue().waitUntilAllOperationsAreFinished()
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
        return result
    }
}
when i execute
main.kexe
, any meaningful output doesn't appear but the program doesn't finish.
s
Hello. You don’t have run loop in your main thread, so tasks pushed to
NSOperationQueue.mainQueue
won’t run.
k
@svyatoslav.scherbina how can I do that? Would you tell me sample code or some document for it?
s
You can run
NSApplication
, see e.g. https://github.com/JetBrains/kotlin-native/blob/31892bd82eee7995db1f0524401242ffb624f446/samples/objc/src/objcMain/kotlin/Window.kt#L30 Alternatively you can run main event loop manually, please refer to the documentation.
k
@svyatoslav.scherbina I tried as follows but it doesn't work 🤔
Copy code
fun main(args: Array<String>) {
    autoreleasepool {
        val app = NSApplication.sharedApplication()
        app.delegate = MyAppDelegate()
        app.setActivationPolicy(NSApplicationActivationPolicy.NSApplicationActivationPolicyRegular)
        app.activateIgnoringOtherApps(true)
        app.run()
    }
}

private class MyAppDelegate() : NSObject(), NSApplicationDelegateProtocol {
    fun get(urlString: String): String {
        val semaphore = dispatch_semaphore_create(0)

        val components = NSURLComponents(urlString)
        val url = components.URL
        var result: String = ""
        val config = NSURLSessionConfiguration.defaultSessionConfiguration()
        config.waitsForConnectivity = true
        config.timeoutIntervalForResource = 300.0

        val request = NSURLRequest.requestWithURL(url!!)
        val session = NSURLSession.sessionWithConfiguration(
            config, null, NSOperationQueue.mainQueue()
        )

        val task =
            session.dataTaskWithRequest(request) { nsData: NSData?, nsurlResponse: NSURLResponse?, nsError: NSError? ->
                nsData?.run { result = WebGateway.toString() }
                println(nsData)
                dispatch_semaphore_signal(semaphore);
            }

        task.resume()
        session.finishTasksAndInvalidate()
        NSOperationQueue.mainQueue().waitUntilAllOperationsAreFinished()
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
        return result
    }

    init {
        println(get("<https://www.google.com/>"))
    }
}
s
Copy code
NSOperationQueue.mainQueue().waitUntilAllOperationsAreFinished()
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
This code is executed on main queue too, so your data task completion handler can’t start before you return.