How to check validity of URL in Swift?

后端 未结 22 1680
不知归路
不知归路 2020-11-29 02:05

Trying to make an app launch the default browser to a URL, but only if the URL entered is valid, otherwise it displays a message saying the URL is invalid.

How would

相关标签:
22条回答
  • 2020-11-29 02:07

    Try this:

    func isValid(urlString: String) -> Bool
    {
        if let urlComponents = URLComponents.init(string: urlString), urlComponents.host != nil, urlComponents.url != nil
        {
            return true
        }
        return false
    }
    

    This simply checks for valid URL components and if the host and url components are not nil. Also, you can just add this to an extensions file

    0 讨论(0)
  • 2020-11-29 02:11

    My personal preference is to approach this with an extension, because I like to call the method directly on the string object.

    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\\.&%\\$\\-]+)*@)*((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\\.\\,\\?\\'\\\\\\+&%\\$#\\=~_\\-]+))*$"
            return self.matches(pattern: urlPattern)
        }
    }
    

    This way it is also extensible with another use-cases, such as isValidEmail, isValidName or whatever your application requires.

    0 讨论(0)
  • 2020-11-29 02:12

    You can use the NSURL type (whose constructor returns an optional type) combined with an if-let statement to check the validity of a given URL. In other words, make use of the NSURL failable initializer, a key feature of Swift:

    let stringWithPossibleURL: String = self.textField.text // Or another source of text
    
    if let validURL: NSURL = NSURL(string: stringWithPossibleURL) {
        // Successfully constructed an NSURL; open it
        UIApplication.sharedApplication().openURL(validURL)
    } else {
        // Initialization failed; alert the user
        let controller: UIAlertController = UIAlertController(title: "Invalid URL", message: "Please try again.", preferredStyle: .Alert)
        controller.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
    
        self.presentViewController(controller, animated: true, completion: nil)
    }
    
    0 讨论(0)
  • 2020-11-29 02:13

    Version that works with Swift 4.2 and has reliable URL pattern matching ...

    func matches(pattern: String) -> Bool
    {
        do
        {
            let regex = try NSRegularExpression(pattern: pattern, options: [.caseInsensitive])
            return regex.firstMatch(in: self, options: [], range: NSRange(location: 0, length: utf16.count)) != nil
        }
        catch
        {
            return false
        }
    }
    
    
    func isValidURL() -> Bool
    {
        guard let url = URL(string: self) else { return false }
        if !UIApplication.shared.canOpenURL(url) { return false }
    
        let urlPattern = "(http|ftp|https):\\/\\/([\\w+?\\.\\w+])+([a-zA-Z0-9\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)_\\-\\=\\+\\\\\\/\\?\\.\\:\\;\\'\\,]*)?"
        return self.matches(pattern: urlPattern)
    }
    
    0 讨论(0)
  • 2020-11-29 02:14

    Swift 5.1 Solution

    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)
        }
    }
    
    0 讨论(0)
  • 2020-11-29 02:16

    If your goal is to verify if your application can open a URL, here is what you can do. Although safari can open the URL, the website might not exist or it might be down.

    `// Swift 5
     func verifyUrl (urlString: String?) -> Bool {
        if let urlString = urlString {
            if let url = NSURL(string: urlString) {
                return UIApplication.shared.canOpenURL(url as URL)
            }
        }
        return false
    }
    `
    

    As a side note, this does not check whether or not a URL is valid or complete. For example, a call that passes "https://" returns true.

    0 讨论(0)
提交回复
热议问题