如何将基于 Firebase Remote Config 闭包的代码重写为异步/等待版本

问题描述 投票:0回答:0

我需要将访问 firebase 中的远程配置的基于闭包的旧代码重写为其异步等待版本。我是 SwiftUI 异步/等待的新手。所以我有:

final class RemoteConfigService {

    private let isDebugEnabled: Bool
    private let semaphore = DispatchSemaphore(value: 1)
    private let concurrentQueue = DispatchQueue.global(qos: .background)

    init(isDebugEnabled: Bool) {
        self.isDebugEnabled = isDebugEnabled
    }

    func fetch(
        defaultValuesPlistFile: PlistFile,
        expirationDuration: TimeInterval,
        onComplete: @escaping (RemoteConfig) -> Void,
        onError: @escaping (Error?) -> Void
    ) {
        concurrentQueue.async { [weak self] in
            guard let strongSelf = self else { return }
            
            strongSelf.semaphore.wait()

            let expirationDuration = !strongSelf.isDebugEnabled ? expirationDuration : 0
            let defaultValues = defaultValuesPlistFile.plist?.dictionary as? [String: NSObject]
            let remoteConfig = RemoteConfig.remoteConfig()
            remoteConfig.setDefaults(defaultValues)
            remoteConfig.fetch(withExpirationDuration: expirationDuration) { [remoteConfig] status, error in
                strongSelf.semaphore.signal()
                
                if status == .success || status == .throttled {
                    remoteConfig.activate { _, _ in
                        DispatchQueue.main.async {
                            onComplete(remoteConfig)
                        }
                    }
                } else {
                    DispatchQueue.main.async {
                        onError(error)
                    }
                }
            }
        }
    }

正如我所见,Xcode 自动生成了基于 FirebaseRemoteConfig 的闭包方法的异步版本。我可以用它们

然而我的问题在这里

  1. 我已经使用信号量来同步对此 RemoteConfig 的访问(我不记得为什么需要它,但我想在异步等待版本中保证它的安全)
  2. 有后台队列,所以这个配置是在后台获取的。如何在后台执行异步代码
  3. 使用 DispatchQueue.main.async 在主线程上返回结果

我已经尝试编写它并实现了类似的东西,但我认为我错过了信号量和同步并且我不确定代码是否在后台执行并且我几乎确定它不会在主线程上返回结果。

func fetch(defaultValuesPlistFile: PlistFile, expirationDuration: TimeInterval) async throws -> RemoteConfig {
        try await Task.detached(priority: .background) { [isDebugEnabled] in
            let expirationDuration = !isDebugEnabled ? expirationDuration : 0
            let defaultValues = defaultValuesPlistFile.plist?.dictionary as? [String: NSObject]
            let remoteConfig = RemoteConfig.remoteConfig()
            remoteConfig.setDefaults(defaultValues)
            
            let status = try await remoteConfig.fetch(withExpirationDuration: expirationDuration)
            
            guard status == .success || status == .throttled else {
                throw FeatureStatusError.unsupported
            }
            
            _ = try await remoteConfig.activate()
            
            return remoteConfig
        }.value
    }
swift asynchronous async-await firebase-remote-config
© www.soinside.com 2019 - 2024. All rights reserved.