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

cli*_*ver 51 url swift ios8

尝试使应用程序启动默认浏览器到URL,但仅当输入的URL有效时,否则会显示一条消息,指出URL无效.

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

336*_*784 86

如果您的目标是验证您的应用程序是否可以打开网址,那么您可以执行此操作.虽然safari可以打开Url,但网站可能不存在或者可能已关闭.

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.sharedApplication().canOpenURL(url)
        }
    }
    return false
}
Run Code Online (Sandbox Code Playgroud)

  • 如果让urlString = urlString,URL = NSURL(字符串:urlString),其中UIApplication.sharedApplication()canOpenURL(URL){返回true}. (3认同)

Mil*_*sáľ 35

Swift 4优雅解决方案使用NSDataDetector:

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.utf16.count)) {
            // it is a link, if the match covers the whole string
            return match.range.length == self.utf16.count
        } else {
            return false
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

let string = "https://www.fs.blog/2017/02/naval-ravikant-reading-decision-making/"
if string.isValidURL {
    // TODO
}
Run Code Online (Sandbox Code Playgroud)


Dou*_*mos 21

对于接受答案的快速3版本:

func verifyUrl(urlString: String?) -> Bool {
    if let urlString = urlString {
        if let url = URL(string: urlString) {
            return UIApplication.shared.canOpenURL(url)
        }
    }
    return false
}
Run Code Online (Sandbox Code Playgroud)

或者更多Swifty解决方案:

func verifyUrl(urlString: String?) -> Bool {
    guard let urlString = urlString,
          let url = URL(string: urlString) else { 
        return false 
    }

    return UIApplication.shared.canOpenURL(url)
}
Run Code Online (Sandbox Code Playgroud)


Ash*_*hok 15

我发现这一个干净(在Swift中):

func canOpenURL(string: String?) -> Bool {
    guard let urlString = string else {return false}
    guard let url = NSURL(string: urlString) else {return false}
    if !UIApplication.sharedApplication().canOpenURL(url) {return false}

    //
    let regEx = "((https|http)://)((\\w|-)+)(([.]|[/])((\\w|-)+))+"
    let predicate = NSPredicate(format:"SELF MATCHES %@", argumentArray:[regEx])
    return predicate.evaluateWithObject(string)
}
Run Code Online (Sandbox Code Playgroud)

用法:

if canOpenURL("abc") {
    print("valid url.")
} else {
    print("invalid url.")
}
Run Code Online (Sandbox Code Playgroud)

===

对于Swift 4.1:

func canOpenURL(_ string: String?) -> Bool {
    guard let urlString = string,
        let url = URL(string: urlString)
        else { return false }

    if !UIApplication.shared.canOpenURL(url) { return false }

    let regEx = "((https|http)://)((\\w|-)+)(([.]|[/])((\\w|-)+))+"
    let predicate = NSPredicate(format:"SELF MATCHES %@", argumentArray:[regEx])
    return predicate.evaluate(with: string)
}

// Usage
if canOpenURL("abc") {
    print("valid url.")
} else {
    print("invalid url.") // This line executes
}

if canOpenURL("https://www.google.com") {
    print("valid url.") // This line executes
} else {
    print("invalid url.")
}
Run Code Online (Sandbox Code Playgroud)


Sha*_*har 14

使用'canOpenUrl'对我的用例来说太贵了,我发现这种方法更快

func isStringLink(string: String) -> Bool {
    let types: NSTextCheckingResult.CheckingType = [.link]
    let detector = try? NSDataDetector(types: types.rawValue)
    guard (detector != nil && string.characters.count > 0) else { return false }
    if detector!.numberOfMatches(in: string, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, string.characters.count)) > 0 {
        return true
    }
    return false
}
Run Code Online (Sandbox Code Playgroud)

  • 对于Swift 4:“ string.characters.count”成为“ string.count” (2认同)

Gle*_*enn 13

2020 年,我的任务是修复在字符串中为字符串链接添加下划线的方法的错误。这里的大多数答案都无法正常工作(尝试:aaa.com.bd 或 aaa.bd)这些链接应该有效。然后我偶然发现了这个的正则表达式字符串。

参考:https: //urlregex.com/

所以基于该正则表达式

"((?:http|https)://)?(?:www\\.)?[\\w\\d\\-_]+\\.\\w{2,3}(\\.\\w{2})?(/(?<=/)(?:[\\w\\d\\-./_]+)?)?"
Run Code Online (Sandbox Code Playgroud)

我们可以写一个函数。

环球银行金融电信协会 5.x

extension String {
    var validURL: Bool {
        get {
            let regEx = "((?:http|https)://)?(?:www\\.)?[\\w\\d\\-_]+\\.\\w{2,3}(\\.\\w{2})?(/(?<=/)(?:[\\w\\d\\-./_]+)?)?"
            let predicate = NSPredicate(format: "SELF MATCHES %@", argumentArray: [regEx])
            return predicate.evaluate(with: self)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

OBJECTIVE-C(无论你想写什么,无论是否属于类别)。

- (BOOL)stringIsValidURL:(NSString *)string
{
    NSString *regEx = @"((?:http|https)://)?(?:www\\.)?[\\w\\d\\-_]+\\.\\w{2,3}(\\.\\w{2})?(/(?<=/)(?:[\\w\\d\\-./_]+)?)?";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@" argumentArray:@[regEx]];
    return [predicate evaluateWithObject:string];
}
Run Code Online (Sandbox Code Playgroud)


Vit*_*lii 6

在某些情况下,检查 url 是否满足 RFC 1808 就足够了。有多种方法可以做到这一点。一个例子:

if let url = URL(string: urlString), url.host != nil {
  // This is a correct url
}
Run Code Online (Sandbox Code Playgroud)

这是因为如果 url 不符合 RFC 1808,.host 以及 .path、.fragment 和其他一些方法将返回 nil。

如果不检查,控制台日志中可能会出现此类消息:

Task <DF46917D-1A04-4E76-B54E-876423224DF7>.<72> finished with error - code: -1002
Run Code Online (Sandbox Code Playgroud)


小智 6

斯威夫特 5.1 解决方案

extension String {
    func canOpenUrl() -> Bool {
        guard let url = URL(string: self), UIApplication.shared.canOpenURL(url) else { return false }
        let regEx = "((https|http)://)((\\w|-)+)(([.]|[/])((\\w|-)+))+"
        let predicate = NSPredicate(format:"SELF MATCHES %@", argumentArray:[regEx])
        return predicate.evaluate(with: self)
    }
}
Run Code Online (Sandbox Code Playgroud)


Che*_*ati 5

var url:NSURL = NSURL(string: "tel://000000000000")!
if UIApplication.sharedApplication().canOpenURL(url) {
    UIApplication.sharedApplication().openURL(url)
} else {
     // Put your error handler code...
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*hal 5

我个人比较喜欢使用扩展名来实现这一点,因为我喜欢直接在字符串对象上调用该方法。

extension String {

    private func matches(pattern: String) -> Bool {
        let regex = try! NSRegularExpression(
            pattern: pattern,
            options: [.caseInsensitive])
        return regex.firstMatch(
            in: self,
            options: [],
            range: NSRange(location: 0, length: utf16.count)) != nil
    }

    func isValidURL() -> Bool {
        guard let url = URL(string: self) else { return false }
        if !UIApplication.shared.canOpenURL(url) {
            return false
        }

        let urlPattern = "^(http|https|ftp)\\://([a-zA-Z0-9\\.\\-]+(\\:[a-zA-Z0-9\\.&amp;%\\$\\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9\\-]+\\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\\:[0-9]+)*(/($|[a-zA-Z0-9\\.\\,\\?\\'\\\\\\+&amp;%\\$#\\=~_\\-]+))*$"
        return self.matches(pattern: urlPattern)
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,它也是可扩展的另一种使用情况,如isValidEmailisValidName或任何你的应用需要。


小智 5

对于 Swift 4 版本

static func isValidUrl (urlString: String?) -> Bool {
    if let urlString = urlString {
        if let url = URL(string: urlString) {
            return UIApplication.shared.canOpenURL(url)
        }
    }
    return false
}
Run Code Online (Sandbox Code Playgroud)