Как я могу подключиться через HTTP в Kotlin / Native iOS development?

#ios #kotlin

#iOS #kotlin

Вопрос:

Я пытался получить веб-страницу на Kotlin / Native с платформой iOS, но это не сработало. Пожалуйста, скажите мне, в чем проблема.

Я создал проект с помощью Gradle и build.gradle содержит:

 plugins {
    id 'kotlin-multiplatform' version '1.3.21'
}
  

Вот коды.

 package sample

fun main(args: Array<String>) {
    println(WebGateway.get("https://www.google.com/"))
}
  
 package sample

import platform.Foundation.*
import platform.darwin.*

actual object WebGateway {
    actual fun get(urlString: String): String {
        val semaphore = dispatch_semaphore_create(0)

        var components = NSURLComponents(urlString)
        val url = components.URL
        var result: String = ""
        val config = NSURLSessionConfiguration.defaultSessionConfiguration()
        config.waitsForConnectivity = true
        config.timeoutIntervalForResource = 300.0
        val session = NSURLSession.sessionWithConfiguration(
            config, null, NSOperationQueue.mainQueue()
        )

        val task = session
            .dataTaskWithURL(url!!) { 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
    }
}
  

После сборки приложения main.kexe было создано.

Я ожидал, что HTML веб-страницы Google будет напечатан в стандартном выводе при выполнении приложения. Но на самом деле:

  % ./main.kexe

  

Он ничего не показывает.
Программа останавливается на dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) .

После выполнения приложения task.state стало NSURLSessionTaskStateCompleted , но программа ничего не показывает и не завершается.

Когда я изменил session на NSURLSession.sessionWithConfiguration(config) , я получил следующий результат.

  % ./main.kexe
Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: illegal attempt to access non-shared sample.WebGateway.$<anonymous>$FUNCTION_REFERENCE$0@f6f058e8 from other thread
        at 0   main.kexe                           0x000000010039c3c3 ThrowIllegalObjectSharingException   595
        at 1   main.kexe                           0x00000001003b9d6d -[KotlinObjectHolder ref]   141
        at 2   main.kexe                           0x00000001003c9524 platform_Foundation_kniBridge11046   148
        at 3   main.kexe                           0x00000001003ca18c __platform_Foundation_kniBridge11045_block_invoke   108
        at 4   CFNetwork                           0x00007fff4cd80763 __75-[__NSURLSessionLocal taskForClass:request:uploadFile:bodyData:completion:]_block_invoke   19
        at 5   CFNetwork                           0x00007fff4cd8016c __49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke   172
        at 6   Foundation                          0x00007fff50243a47 __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__   7
        at 7   Foundation                          0x00007fff5024394e -[NSBlockOperation main]   68
        at 8   Foundation                          0x00007fff50218f7a -[__NSOperationInternal _start:]   686
        at 9   Foundation                          0x00007fff5024367f __NSOQSchedule_f   227
        at 10  libdispatch.dylib                   0x00007fff7aef3d4f _dispatch_call_block_and_release   12
        at 11  libdispatch.dylib                   0x00007fff7aef4dcb _dispatch_client_callout   8
        at 12  libdispatch.dylib                   0x00007fff7aef75d8 _dispatch_continuation_pop   427
        at 13  libdispatch.dylib                   0x00007fff7aef6c7a _dispatch_async_redirect_invoke   718
        at 14  libdispatch.dylib                   0x00007fff7af02d1a _dispatch_root_queue_drain   325
        at 15  libdispatch.dylib                   0x00007fff7af034b1 _dispatch_worker_thread2   90
        at 16  libsystem_pthread.dylib             0x00007fff7b1346ee _pthread_wqthread   619
        at 17  libsystem_pthread.dylib             0x00007fff7b134415 start_wqthread   13
zsh: abort      ./main.kexe
  

Когда я изменил session на NSURLSession.sharedSession() , появилась та же ошибка.

Комментарии:

1. Есть какие-либо успехи в этом?

2. Есть новости по этому поводу?

Ответ №1:

Kotlin native ожидает, что обратный вызов будет вызван в основном потоке. Вот как собственный HTTP-запрос реализован в приложении Kotlin conf spinner.

https://github.com/Kotlin/kotlinconf-spinner/blob/master/clients/ios/src/iosMain/kotlin/platformUtils.kt

Комментарии:

1. Также можно вызвать put запрос внутри NSOperationQueue.mainQueue.addOperationWithBlock { }