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
This isn't a regex approach, but it is a naive one that works well for making sure there is a host and an extension if you want a simple and inexpensive approach:
extension String {
var isValidUrlNaive: Bool {
var domain = self
guard domain.count > 2 else {return false}
guard domain.trim().split(" ").count == 1 else {return false}
if self.containsString("?") {
var parts = self.splitWithMax("?", maxSplit: 1)
domain = parts[0]
}
return domain.split(".").count > 1
}
}
Use this only if you want a quick way to check on the client side and you have server logic that will do a more rigorous check before saving the data.
In some cases it can be enough to check that the url satisfies RFC 1808. There are several ways to do this. One example:
if let url = URL(string: urlString), url.host != nil {
// This is a correct url
}
This is because .host, as well as .path, .fragment and a few other methods would return nil if url doesn't conform to RFC 1808.
If you don't check, you might have this kind of messages in console log:
Task <DF46917D-1A04-4E76-B54E-876423224DF7>.<72> finished with error - code: -1002
Swift 4.2 Elegant URL construction with verification
import Foundation
import UIKit
extension URL {
init?(withCheck string: String?) {
let regEx = "((https|http)://)((\\w|-)+)(([.]|[/])((\\w|-)+))+"
guard
let urlString = string,
let url = URL(string: urlString),
NSPredicate(format: "SELF MATCHES %@", argumentArray: [regEx]).evaluate(with: urlString),
UIApplication.shared.canOpenURL(url)
else {
return nil
}
self = url
}
}
Usage
var imageUrl: URL? {
if let url = URL(withCheck: imageString) {
return url
}
if let url = URL(withCheck: image2String) {
return url
}
return nil
}
For Swift 4 version
static func isValidUrl (urlString: String?) -> Bool {
if let urlString = urlString {
if let url = URL(string: urlString) {
return UIApplication.shared.canOpenURL(url)
}
}
return false
}
extension String {
func isStringLink() -> Bool {
let types: NSTextCheckingResult.CheckingType = [.link]
let detector = try? NSDataDetector(types: types.rawValue)
guard (detector != nil && self.characters.count > 0) else { return false }
if detector!.numberOfMatches(in: self, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, self.characters.count)) > 0 {
return true
}
return false
}
}
//Usage
let testURL: String = "http://www.google.com"
if testURL.isStringLink() {
//Valid!
} else {
//Not valid.
}
It's advised to use this check only once and then reuse.
P.S. Credits to Shachar for this function.
var url:NSURL = NSURL(string: "tel://000000000000")!
if UIApplication.sharedApplication().canOpenURL(url) {
UIApplication.sharedApplication().openURL(url)
} else {
// Put your error handler code...
}