Swift 4 - 使用 PromiseKit 调用嵌套

Posted

技术标签:

【中文标题】Swift 4 - 使用 PromiseKit 调用嵌套【英文标题】:Swift 4 - Call nests with PromiseKit 【发布时间】:2018-11-06 13:12:58 【问题描述】:

大家早上好!

我正在使用带有 Xcode10 的 Swift 4.2 和我使用 Alomofire 和 PromiseKit 管理的调用。

有一次我需要在应用程序的开头加载一个带有使用条款的屏幕,但前提是他们已经更新了它。如果版本已更改,则相同的调用具有带有新端点的 URL。该端点包含要显示的文本。因此,在最后一种情况下。我们必须打两个电话。

然后我解释我想做什么:

要知道他们是否更新了版本号,我进行了第一次调用并检查了我保存在设备中的最后一个版本号 (NSUSserDefaults)。第一次调用返回以下内容:

"legal_version": "1", "legal_URL": "http://statics.....html"

如果是相同版本,我不显示屏幕。

如果版本已更改,我想进行第二次调用(使用带有第一次调用“legal_URL”答案的 URL)

他的问题是我不知道如何使双重呼叫阻塞。所以不要在不检查版本号的情况下加载主屏幕。而且不知道我是否必须再次显示法律条款的屏幕。 而这一切都是 PromiseKit 和嵌套调用。

非常感谢您的帮助。

[代码更新]

let legalWarningRepository = LegalWarningRepository()
        firstly 
            legalWarningRepository.get(endpoint: "http://myserver.com/version")
            .then  json in
                if let remoteVersion = json["version"] as? String, let 
                    legalUrl = json["legal_URL"] as? String, 
                    remoteVersion != localVersion 
                        return legalWarningRepository.get(endpoint: legalUrl)
            
        .done  json in
            if json == nil 
                // display main screen
            
            else 
                // display legal terms
            
        .catch  err in
            print(err)
    

在“legalWarningViewController”里面我有你传给我的get方法:

func get(endpoint: String) -> Promise<[String: Any]> 
  return Promise  seal in
    Alamofire.request(endpoint)
      .validate()
      .responseJSON  response in
        switch response.result 
        case .success(let json):
          guard let json = json  as? [String: Any] else 
            return seal.reject(AFError.responseValidationFailed(reason: 
.dataFileNil))
          
          seal.fulfill(json)
          case .failure(let error):
            seal.reject(error)
          
       
  

【问题讨论】:

【参考方案1】:

在您的第一个屏幕上,您可以在等待响应时显示活动指示器。收到回复后,您可以显示相应的视图。

为了简单起见,您可以创建一个“承诺”Alamofire 调用的通用方法:

func get(endpoint: String) -> Promise<[String: Any]> 
  return Promise  seal in
    Alamofire.request(endpoint)
      .validate()
      .responseJSON  response in
        switch response.result 
        case .success(let json):
          guard let json = json  as? [String: Any] else 
            return seal.reject(AFError.responseValidationFailed(reason: .dataFileNil))
          
          seal.fulfill(json)
          case .failure(let error):
            seal.reject(error)
          
       
  

然后在您的主屏幕的viewDidLoadviewWillAppear 中,您可以执行这种逻辑:

firstly 
  get(endpoint: "http://myserver.com/version")
.then  json in
  if let remoteVersion = json["version"] as? String, let legalUrl = json["legal_URL"] as? String, remoteVersion != localVersion 
    return get(endpoint: legalUrl)
  
.done  json in
  if json == nil 
    // display main screen
  
  else 
    // display legal terms
  
.catch  err in
   print(error.localizedDescription)

在您的情况下,如果您在 WKWebView 中显示法律术语,则可能会进行一次通话。

firstly 
  get(endpoint: "http://myserver.com/version")
.done  json in
  if let remoteVersion = json["version"] as? String, let legalUrl = json["legal_URL"] as? String, remoteVersion != localVersion 
    // display legal terms in a web view
  
  // display main screen
.catch  err in
   print(error.localizedDescription)

【讨论】:

感谢@YannickLoriot 的回答,现在我更好地看到了解决方案。但是我在“首先”中收到一个错误,上面写着:-对成员的模糊引用“首先(执行:)”我正在使用 PromiseKit 6.0 为什么会这样? 对于这些情况,您可以查看 PromiseKit 的故障排除页面:github.com/mxcl/PromiseKit/blob/master/Documentation/…。也许你应该添加一个退货声明?

以上是关于Swift 4 - 使用 PromiseKit 调用嵌套的主要内容,如果未能解决你的问题,请参考以下文章

PromiseKit O-C 指南

使用 PromiseKit 从 Objective C 到 Swift 的桥接

如何使用 Combine + Swift 复制 PromiseKit 风格的链式异步流

如何在 Swift 中使用 PromiseKit 和 Firebase?

PromiseKit 和 CloudKit 保存(使用 Swift)

PromiseKit 语法链 swift