async await - ShenYj/ShenYj.github.io GitHub Wiki

async/await

在 Swift 5.5 中引入了异步(async)函数,允许我们运行复杂的异步代码几乎是同步的。

这分两步完成:使用新的 async 关键字标记异步函数,然后使用 await 关键字调用它们,类似于 C# 和 JavaScript 等其他语言。

曾经在React-Native 中使用过,效果不错

我的第一次实践

14.0 引入了 App Tracking Transparency 后,当时没有细读文档,在15.0 上发现了bug,最终定位到是api 调用时机导致,正如文档中描述的那样:

Calls to the API only prompt when the application state is UIApplicationStateActive. The authorization prompt doesn’t display if another permission request is pending user confirmation. 

代码

  • ATTracking+Ex.swift, 简单的一层包装,提供第一层接口

    import AppTrackingTransparency
    
    @available(iOS 14, *)
    extension ATTrackingManager {
        
        public static func requestTrackingAuthorizationComplete( complete: @escaping (_ complete: Bool) -> Void ) {
            ATTrackingManager.requestTrackingAuthorization { status in
                switch status {
                case .notDetermined:    complete(false)
                default:                complete(true)
                }
            }
        }
        
        @available(iOS 15, *)
        public static func idfa_iOS_15_Complete() async -> Bool {
            let status = await ATTrackingManager.requestTrackingAuthorization()
            switch status {
            case .notDetermined:    return false
            default:                return true
            }
        }
    }
  • LaunchingViewController.swift内的第二层

    @available(iOS 15.0.0, *)
    fileprivate func idfaIOS15() {
        Task {
            let iOS15 = await ATTrackingManager.idfa_iOS_15_Complete()
            switch iOS15 {
            case true:  self.launchVM.trackingSetCompleteOB.onNext(true)
            case false: break
            }
        }
    }
        
    fileprivate func idfa() {
        if #available(iOS 14, *) {
            ATTrackingManager.requestTrackingAuthorizationComplete { [weak self] setComplete in
                switch setComplete {
                case true:  self?.launchVM.trackingSetCompleteOB.onNext(true)
                case false: break
                }
            }
        }
        else {
            launchVM.trackingSetCompleteOB.onNext(true)
        }
    }
  • LaunchingViewController.swift 内正式使用

    NotificationCenter.default.rx.notification(UIApplication.didBecomeActiveNotification)
        .withUnretained(self)
        .subscribe(onNext: { (owner, _) in
            if #available(iOS 15, *) { owner.idfaIOS15() }
            else { owner.idfa() }
        })
        .disposed(by: rx.disposeBag)

第一次的感受

依旧很苹果, 新api不向下兼容,新老同时使用时很痛苦

我的第二层包装是被迫的,因为关键词的成对要求(毕竟我是第一次在Swift上使用,即要尝鲜,又要照顾低版本)

RxSwift 6.5版本也开始支持了 async/await

外链

⚠️ **GitHub.com Fallback** ⚠️