我需要将访问 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 的闭包方法的异步版本。我可以用它们
然而我的问题在这里
我已经尝试编写它并实现了类似的东西,但我认为我错过了信号量和同步并且我不确定代码是否在后台执行并且我几乎确定它不会在主线程上返回结果。
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
}