簡體   English   中英

不使用方案驗證URL

[英]Validate URL without scheme

Swift 5,Xcode 10,iOS 12

我的代碼使用UIApplication.shared.canOpenURL來驗證URL,不幸的是,如果沒有“ http://”,URL將失敗。

例:

print(UIApplication.shared.canOpenURL(URL(string: "stackoverflow.com")!)) //false
print(UIApplication.shared.canOpenURL(URL(string: "http://stackoverflow.com")!)) //true
print(UIApplication.shared.canOpenURL(URL(string: "129.0.0.1")!)) //false
print(UIApplication.shared.canOpenURL(URL(string: "ftp://129.0.0.1")!)) //true

我知道使用方案 (iOS9 +)的更改,並且我知道如果String尚未以前綴開頭,則可以添加諸如“ http://”的前綴,然后檢查此新String,但我仍然疑惑:

問題:如何添加“沒有方案”方案,所以有效的URL(如“ stackoverflow.com”)也返回true (這是否可能?)?

這是我使用的方法

extension String {

    /// Return first available URL in the string else nil
    func checkForURL() -> NSRange? {
        guard let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
            return nil
        }
        let matches = detector.matches(in: self, options: [], range: NSRange(location: 0, length: self.utf16.count))

        for match in matches {
            guard Range(match.range, in: self) != nil else { continue }
            return match.range
        }
        return nil
    }

    func getURLIfPresent() -> String? {
        guard let range = self.checkForURL() else{
            return nil
        }
        guard let stringRange = Range(range,in:self) else {
            return nil
        }
        return String(self[stringRange])
    }
}

顯然,代碼中的方法名稱和注釋不夠詳細,因此這里是說明。

使用NSDataDetector並為其提供類型-NSTextCheckingResult.CheckingType.link以檢查鏈接。

這將通過提供的字符串,並返回URL類型的所有匹配項。

這將檢查您提供的字符串中的鏈接(如果有),否則返回nil。

方法getURLIfPresent從該字符串返回URL部分。

這里有一些例子

print("http://stackoverflow.com".getURLIfPresent())
print("stackoverflow.com".getURLIfPresent())
print("ftp://127.0.0.1".getURLIfPresent())
print("www.google.com".getURLIfPresent())
print("127.0.0.1".getURLIfPresent())
print("127".getURLIfPresent())
print("hello".getURLIfPresent())

產量

Optional("http://stackoverflow.com")
Optional("stackoverflow.com")
Optional("ftp://127.0.0.1")
Optional("www.google.com")
nil
nil
nil

但是,對於“ 127.0.0.1”,這不會返回true。 因此,我認為這不會實現您的事業。 在您的情況下,使用正則表達式似乎更好。 如果您遇到更多需要被視為URL的模式,則可以添加更多條件。

無法向URL添加有效的方案,因為沒有人知道將哪個前綴添加到哪個URL 您可以只在regex的幫助下驗證URL

我搜索並修改了正則表達式。

extension String { 
    func isValidUrl() -> Bool { 
        let regex = "((http|https|ftp)://)?((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+" 
        let predicate = NSPredicate(format: "SELF MATCHES %@", regex) 
        return predicate.evaluate(with: self) 
    } 
}

我用以下網址測試了它:

print("http://stackoverflow.com".isValidUrl()) 
print("stackoverflow.com".isValidUrl()) 
print("ftp://127.0.0.1".isValidUrl()) 
print("www.google.com".isValidUrl()) 
print("127.0.0.1".isValidUrl()) 
print("127".isValidUrl()) 
print("hello".isValidUrl())

產量

true 
true 
true 
true 
true 
false 
false

注意: 無法使用100%正則表達式來驗證emailurl

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM