如果(stringToURL?.isValidURL)! 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”
注解。subtitle=“www.yahoo.com”
注解。subtitle=“yahoo”
最佳答案
问题在于currentAnnotation.subtitle
是String??
,因为subtitle
不仅是String?
本身,而且还是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)
}
}
请注意,如果未提供任何字符串,则将打开
backupURL
,但是如果提供了字符串且该字符串不是有效的URL,它将不会执行任何操作。因此,也许您的意思是以下内容,如果无法打开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)
}
哪里:
extension String {
var isValidURL: Bool {
let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
let range = NSRange(startIndex..., in: self)
return detector.firstMatch(in: self, range: range)?.range == range
}
func prependHTTPifNeeded() -> String{
if prefix(4) != "http" {
return "http://" + self
} else {
return self
}
}
}