1

I have the iOS app i am coding with SwiftUI . And part of the code is from Kotlin multiplatform (kmm) I need to do some work with async code, it must be executed in separate Thread. But also i have callbacks to run during the Thread execution and that callbacks fails, because of mutability restrictions (kotlin prevents share of objects from one thread to other) The task is to read file by url line by line . And send lines to callback object The problem is that callback object is created outside.

The code is similar to this

class URlDownloadWithCallback {
    let callback: DataDownloadProgressBar
    
    init(cb:DataDownloadProgressBar) {
        self.callback = cb
    }
    
    func download(url:String) {
        
        let semaphore = DispatchSemaphore(value: 0)
        
        Task {
            defer {
                semaphore.signal()
            }
            
            do {
                let (bytes, response) = try await URLSession.shared.bytes(from: URL(string: url)!)
                
                guard let httpResponse = response as? HTTPURLResponse else {
                    self.callback.OnFail(reason: "Failed to get http response code")
                    return
                }
                
                var size:Int64 = 0
                
                if let sizeStr = httpResponse.value(forHTTPHeaderField: "X-Lines-Count") {
                    size = Int64(sizeStr) ?? 0
                }
                
                self.callback.OnStart(totalLines: size)
                
                for try await line in bytes.lines {
                    //print(line)
                    self.callback.LineReceive(data: line)
                }
                self.callback.OnSuccess()
            } catch {
                //print("Error: \(error)")
                self.callback.OnFail(reason: "\(error)")
            }
        }
        
        semaphore.wait(timeout: .distantFuture)
    }
}

I start new thread Thread {} and when i do self.callback.OnStart(totalLines: size) there is the error "Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: illegal attempt to access non-shared"

I can not freeze that object as it has some counters inside, it must be mutable.

So, my question is : is there any way to execute my callback calls in the "external thread"? In the thread that was active before i called Thread {} in my function.

Note, i am using Thread here only because URLSession.shared.bytes is async and it is required to run in thread. I call thread and wait with semaphore anyway.

Maybe something like let originalThread = Thread.current before to call Thread {} . And then somehow use that value to access previous thread?

Also, i know about DispatchQueue . But i do not know if my function was called from main swift thread so i will not try to do DispatchQueue.main.async { } because original thread can be different. Maybe DispatchQueue can be used for original thread i catched with Thread.current?

Do you have any ideas for me?

0 Answers0