在Guard中定义的变量在使用后仍需要立即解开

时间:2019-02-08 17:15:33

标签: ios swift optional

if(stringToURL?.isValidURL)! <-不知道为什么在Guard语句中安全声明了编译器时, stringToURL 上需要编译器链接。另外, isValidURL:Bool 的字符串扩展名总是返回Bool,但是编译器仍然希望解包。

在此示例中, annotation.subtitle 应该已经是URL格式的字符串,但是我想确认。

尝试使用在guard中定义的变量比预期的要复杂得多,因为需要进一步展开。现在,我觉得我正在编写几行代码,这些代码过于复杂,以至于无法跟上/阅读我的实现。

func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
    let backupURL = URL(string: "https://www.google.com")!
    guard let currentAnnotation = view.annotation, var stringToURL = currentAnnotation.subtitle else {
        // currentAnnotation has blank subtitle.  Handle by opening up any website.
        UIApplication.shared.open(backupURL, options: [:])
        return
    }
    if (stringToURL?.isValidURL)!{
        stringToURL = stringToURL?.prependHTTPifNeeded()
        if let url = URL(string: stringToURL!){
            UIApplication.shared.open(url, options: [:])
        } else {
            UIApplication.shared.open(backupURL, options: [:])
        }
    }
}

extension String {
var isValidURL: Bool {
    let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
    if let match = detector.firstMatch(in: self, options: [], range: NSRange(location: 0, length: self.endIndex.encodedOffset)) {
        // it is a link, if the match covers the whole string
        return match.range.length == self.endIndex.encodedOffset
    } else {
        return false
    }
}

func prependHTTPifNeeded()-> String{
    let first4 = self.prefix(4)
    if first4 != "http" {
        return "http://" + self
    } else {
        return self
    }
}

}

代码块正确执行。
注解。subtitle=“ https://www.yahoo.com” <---雅虎打开

annotation.subtitle =“ www.yahoo.com” <---雅虎打开

annotation.subtitle =“ yahoo” <-google.com之所以打开,是因为我们没有有效的URL字符串

1 个答案:

答案 0 :(得分:1)

问题在于currentAnnotation.subtitleString??,因为subtitle不仅是String?本身,而且还是{{1}的可选属性} 协议。因此,简单的拆包仅可验证已实现可选协议MKAnnotation,而不是验证生成的subtitle不是String?。您也必须拆开包装。

但是您可以执行nil,它将正确地解包为guard var stringToURL = view.annotation?.subtitle as? String else { ... }

String

请注意,如果未提供任何字符串,则会打开func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { let backupURL = URL(string: "https://www.google.com”)! guard var stringToURL = view.annotation?.subtitle as? String else { UIApplication.shared.open(backupURL) return } if stringToURL.isValidURL { stringToURL = stringToURL.prependHTTPifNeeded() let url = URL(string: stringToURL) ?? backupURL UIApplication.shared.open(url) } } ,但是如果提供的字符串不是有效的URL,它将不会执行任何操作。因此,也许您的意思是以下内容,如果无法打开backupURL,则会打开backupURL

stringToURL

位置:

func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
    let backupURL = URL(string: "https://www.google.com")!

    guard var stringToURL = view.annotation?.subtitle as? String,
        stringToURL.isValidURL else {
            UIApplication.shared.open(backupURL)
            return
    }

    stringToURL = stringToURL.prependHTTPifNeeded()
    let url = URL(string: stringToURL) ?? backupURL
    UIApplication.shared.open(url)
}