无法解开 Promise<[CLPlacemark]>

Posted

技术标签:

【中文标题】无法解开 Promise<[CLPlacemark]>【英文标题】:Unable to unwrap Promise<[CLPlacemark]> 【发布时间】:2018-11-03 09:21:06 【问题描述】:

我有一个方法可以尝试更新我的授权状态。

使用 PromiseKit 6、Swift 4.2,我似乎无法让我的 Promise 成为 CLPlacemark。

这会导致一系列错误

Value of type 'Promise<[CLPlacemark]>' has no member 'foo'

看看我的代码:

func updateAuthStatus(status: CLAuthorizationStatus) 
    if status == .authorizedWhenInUse 
        titleLabel.isHidden = true
        bigIconView.isHidden = true
        descriptionLabel.isHidden = true
        grantBtn.isHidden = true
        titleLabel1.isHidden = false
        loaderView.isHidden = false
        loaderView.resumeSpinning()
        CLLocationManager.requestLocation().compactMapValues  location in
            return self.coder.reverseGeocode(location: location)
        .compactMapValues  placemark -> Void in
            if placemark.ISOcountryCode == "CA" 
                self.seal.fulfill(())
             else if placemark.ISOcountryCode == "US" 
                if self.allowedStates.contains(placemark.administrativeArea ?? "") 
                    self.seal.fulfill(())
                 else 
                        self.seal.reject(LocationError.InvalidState(placemark.administrativeArea ?? ""))
                
             else 
        self.seal.reject(LocationError.InvalidCountry(placemark.ISOcountryCode ?? ""))
            
        
    
    else if status == .denied || status == .restricted 
        if denied == false 
            self.seal.reject(LocationError.Unknown)
        
        denied = true
    

【问题讨论】:

【参考方案1】:

正如您所提到的,这个promise 正在返回一个CLPlacemark 对象数组,因此您需要从array 中获取特定的placemark,然后使用它。这是通过访问array 中的first placemark 的示例。

.compactMapValues  placemarks -> Void in
            guard let placemark = placemarks.first else  return 

            if placemark.ISOcountryCode == "CA" 
                self.seal.fulfill(())
             else if placemark.ISOcountryCode == "US" 
                if self.allowedStates.contains(placemark.administrativeArea ?? "") 
                    self.seal.fulfill(())
                 else 
                  self.seal.reject(LocationError.InvalidState(placemark.administrativeArea ?? ""))
                
             else 
        self.seal.reject(LocationError.InvalidCountry(placemark.ISOcountryCode ?? ""))
            
        

编辑

要处理美国和加拿大,可以提取该国家/地区的相关地标,如下所示,

.compactMapValues  placemarks -> Void in
       if let ca = placemarks.filter $0.ISOcountryCode == "CA".first 
            self.seal.fulfill(())
        else if let usa = placemarks.filter $0.ISOcountryCode == "US".first 
            if self.allowedStates.contains(usa.administrativeArea ?? "") 
                self.seal.fulfill(())
             else 
                let error = LocationError.InvalidState(usa.administrativeArea ?? "")
                self.seal.reject(error)
            
     else 
         let error = LocationError.InvalidCountry(placemarks.first?.ISOcountryCode ?? "")
         self.seal.reject(error)
     
 

【讨论】:

我通过使用 guard let placemark = placemarks.value?first else return 让警告静音了,你认为这样可以吗? @KonradWright 实际上我不确定array 中有多少元素,而且我不知道返回数组中多个元素的条件。我仍然可以通过查看此块中的代码来建议您更好的解决方案。我相信您只对CAUS 感兴趣,所以我会更新答案以处理这些情况。 @KonradWright 我用更好的修复更新了答案。

以上是关于无法解开 Promise<[CLPlacemark]>的主要内容,如果未能解决你的问题,请参考以下文章

PromiseKit 6:无法使用类型为“((String,String)-> Promise<Data>)”的参数列表调用“then”

无法将“Promise<[NSDictionary]>”类型的值转换为预期的参数类型“Guarantee<Void>”

更新 PromiseKit 后出错:无法将“PMKFinalizer”类型的值转换为预期的参数类型“Promise<Void>”

无法解开 NSError

无法强制解开非可选类型“UIImage”的值

无法从自定义域中解开 COM 实例