我如何在 swift Kotlin 多平台上使用 Flow?

问题描述

我正在创建我的第一个 kotlin 多平台项目,但在 swift 上使用 kotlin 流程时遇到了一些困难。我使用 kotlin flow 和 ktor 创建了模型、服务器数据请求作为公共文件,我正在创建的视图模型和 ui 层作为本机创建。所以,我没有快速开发的经验,除此之外,我在快速视图模型上使用流时遇到很多麻烦。在寻找我的问题的答案时,我发现了一个被描述为 CommonFlow 的类,它旨在用作两种语言的通用代码(kotlin、swift,但我遇到了一个错误,让我几乎不知道为什么发生了,或者,可能只是我对 xcode 和 swift 编程缺乏控制:

所以这是xcode指出错误的代码部分:

enter image description here

Obs:对不起,我认为这次的图像可能更具描述性

这就是我从错误中得到的全部

Thread 1: EXC_BAD_ACCESS (code=2,address=0x7ffee5928ff8)

我的 Ios 视图模型:

class ProfileViewModel: ObservableObject {
    private let repository: ProfileRepository
    
    init(repository: ProfileRepository) {
        self.repository = repository
    }
    
    @Published var authentication: Authetication = Authetication.unauthenticated(false)
    @Published var TokenResponse: ResponseDTO<Token>? = nil
    @Published var loading: Bool = false
    
    func authenticate(email: String,password: String) {
        DispatchQueue.main.async {
            if(self.isValidForm(email: email,password: password)){
                self.repository.getTokenCFlow(email: email,password: password).watch{ response in
                    switch response?.status {
                    
                        case StatusDTO.success:
                            self.loading = false
                                let token: String = response!.data!.accessToken!
                                SecretStorage().saveToken(token: token)
                                self.authentication = Authetication.authenticated
                                break;
                            
                            case StatusDTO.loading:
                                self.loading = true
                            break;
                                
                            case StatusDTO.error:
                                print("Ninja request error \(String(describing: response!.error!))}")
                                break;
                                
                            default:
                                break
                    }
                }
            }
        }
    }
    
    private func isValidForm(email: String,password: String) -> Bool {
        var invalidFields = [Pair]()
        if(!isValidEmail(email)){
            invalidFields.append(Pair(first:"email invalido",second: "email invalido"))
        }
            
        if(password.isEmpty) {
            invalidFields.append(Pair(first:"senha invalida",second: "senha invalida"))
        }
            
        if(!invalidFields.isEmpty){
            self.authentication = Authetication.invalidAuthentication(invalidFields)
            return false
        }
        return true
    }
    
    private func isValidEmail(_ email: String) -> Bool {
        let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"

        let emailPred = NSPredicate(format:"SELF MATCHES %@",emailRegEx)
        return emailPred.evaluate(with: email)
    }
    
}

class Pair {
    let first: String
    let second: String
    init(first:String,second: String) {
        self.first = first
        self.second = second
    }
}
enum Authetication {
    case invalidAuthentication([Pair])
    case authenticated
    case persistentAuthentication
    case unauthenticated(Bool)
    case authenticationFailed(String)
    
}

存储库方法:

override fun getToken(email: String,password: String): Flow<ResponseDTO<Token>> = flow {
        emit(ResponseDTO.loading<Token>())
        try {
            val result = api.getToken(GetTokenBody(email,password))
            emit(ResponseDTO.success(result))
        } catch (e: Exception) {
            emit(ResponseDTO.error<Token>(e))
        }
    }

@InternalCoroutinesApi
    override fun getTokenCFlow(email: String,password: String): CFlow<ResponseDTO<Token>> {
        return wrapSwift(getToken(email,password))
    }

CFLOW 类:

@InternalCoroutinesApi
class CFlow<T>(private val origin: Flow<T>): Flow<T> by origin {
    fun watch(block: (T) -> Unit): Closeable {
        val job = Job()
        onEach {
            block(it)
        }.launchIn(CoroutineScope(Dispatchers.Main + job))

        return object: Closeable {
            override fun close() {
                job.cancel()
            }
        }
    }
}

@FlowPreview
@ExperimentalCoroutinesApi
@InternalCoroutinesApi
fun <T> ConflatedBroadcastChannel<T>.wrap(): CFlow<T> = CFlow(asFlow())

@InternalCoroutinesApi
fun <T> Flow<T>.wrap(): CFlow<T> = CFlow(this)

@InternalCoroutinesApi
fun <T> wrapSwift(flow: Flow<T>): CFlow<T> = CFlow(flow)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)