如何在Swift中检查URL的有效性?

101

尝试通过应用启动默认浏览器到一个URL,但仅在输入的URL有效时,否则显示一条消息,指示该URL无效。

我该如何使用Swift检查有效性?


发送一个NSURLRequest并检查返回? - chris
使用字符串来形成一个NSURL,然后检查它是否为nil? - matt
25个回答

0

这是针对最新的Swift 4版本,基于Doug Amos的回答(适用于Swift 3)

public static func verifyUrl (urlString: String?) -> Bool {
    //Check for nil
    if let urlString = urlString {
        // create NSURL instance
        if let url = NSURL(string: urlString) {
            // check if your application can open the NSURL instance
            return UIApplication.shared.canOpenURL(url as URL)
        }
    }
    return false
}

0

这里大多数答案都没有解决我的问题,所以我在这里发布了我是如何解决它的:

static func isValidDomain(domain: String?) -> Bool {
    guard let domain = domain else {
        return false
    }
    // Modified version of https://dev59.com/HF4c5IYBdhLWcg3wT4xO#49072718
    let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
    let domainWithScheme = "https://\(domain)"
    if let url = URL(string: domainWithScheme),
       let match = detector.firstMatch(in: domainWithScheme, options: [], range: NSRange(location: 0, length: domainWithScheme.utf16.count)) {
        // it is a link, if the match covers the whole string
        return match.range.length == domainWithScheme.utf16.count && url.host != nil
    } else {
        return false
    }
}
Milan Nosáľ的回答缺少的是,它没有针对这个特定的输入进行解释:
https://#view-?name=post&post.post_id=519&message.message_id=349

所以我只需添加host检查存在和未经计划的“URL”。


0
//Add in "extension String"
func verifyUrl()  -> Bool {
    var newString = self
    let index = self.index(self.startIndex, offsetBy: 4)
    let mySubstring = self.prefix(upTo: index)
    if mySubstring == "www." {
        newString = "https://" + newString
    }
    if let url = NSURL(string: newString) {
        return UIApplication.shared.canOpenURL(url as URL)
    }
    return false
}

注意:我是通过“晚回答”分类进行评论的。我不喜欢问题的提问方式(什么使URL有效或无效,你必须具体说明),否则,为什么不只看URL框架的错误消息呢?关于你的答案,我认为如果添加注释并明确指出你在逗弄什么以及原因,它会更好。例如,https://localhost是否无效,如果是,为什么? - benc

0
extension String {
  var isValidUrl: Bool {
    if let url = NSURL(string: self) {
      return UIApplication.shared.canOpenURL(url as URL)
    }
    return false
  }
}

用法:

let test1 = "abc"
let isValidUrl = test1.isValidUrl

// Result of isValidUrl will be False


let test1 = "https://www.google.com/"
let isValidUrl = test1.isValidUrl

// Result of isValidUrl will be True

-2

这个被接受的答案在我的情况下不起作用,因为URL错误且没有数据:https://debug-cdn.checkit4team.com/5/image/Y29tbW9uL2RlZmF1bHRfYXZhdGFyLnBuZw==

所以我编写了扩展来解决问题。

extension String {
    var verifyUrl: Bool {
        get {
            let url = URL(string: self)

            if url == nil || NSData(contentsOf: url!) == nil {
                return false
            } else {
                return true
            }
        }
    }
}

使用它:

if string. verifyUrl {
    // do something
}

希望这可以帮到你!


1
这在你的情况下可能有效,但仅当网络连接可用时。此外,我强烈不建议您调用同步网络请求来验证URL是否有效。除此之外,从变量定义中并不明显它执行了同步长时间运行的操作,当从主线程使用时,这可能会给您带来很多麻烦。请阅读https://developer.apple.com/documentation/foundation/nsdata/1547245-datawithcontentsofurl?language=objc - 5keeve
@5keeve 在代码的哪个部分进行了网络请求? - CyberMew
1
@CyberMew NSData(contentsOf: url!) 发起了一个同步(阻塞)请求,它应该用于(小型)本地文件,但是当你给它网络URL时,它也会这样做。我提到了这一点,因为答案中提到的URL是基于网络的。我还提到了文档中的黄色重要框,请去阅读一下 ;) - 5keeve
啊,好的,谢谢你提供的信息,今天学到了新东西! - CyberMew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接