Essayer de faire en sorte qu'une application lance le navigateur par défaut avec une URL, mais uniquement si l'URL entrée est valide, sinon un message indiquant que l'URL n'est pas valide s'affiche.
Comment puis-je vérifier la validité avec Swift?
Si votre objectif est de vérifier si votre application peut ouvrir une URL, voici ce que vous pouvez faire. Bien que le safari puisse ouvrir l’URL, le site Web n’existe peut-être pas ou est en panne.
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
}
Pour une version Swift 3 de la réponse acceptée:
func verifyUrl(urlString: String?) -> Bool {
if let urlString = urlString {
if let url = URL(string: urlString) {
return UIApplication.shared.canOpenURL(url)
}
}
return false
}
Ou pour une solution plus Swifty:
func verifyUrl(urlString: String?) -> Bool {
guard let urlString = urlString,
let url = URL(string: urlString) else {
return false
}
return UIApplication.shared.canOpenURL(url)
}
Swift 4 solution élégante utilisant 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.endIndex.encodedOffset)) {
// it is a link, if the match covers the whole string
return match.range.length == self.endIndex.encodedOffset
} else {
return false
}
}
}
Usage:
let string = "https://www.fs.blog/2017/02/naval-ravikant-reading-decision-making/"
if string.isValidURL {
// TODO
}
J'ai trouvé celui-ci propre (à 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)
}
Usage:
if canOpenURL("abc") {
print("valid url.")
} else {
print("invalid url.")
}
===
pour 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.")
}
L'utilisation de 'canOpenUrl' était trop chère pour mon cas d'utilisation, j'ai trouvé cette approche plus rapide
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
}
var url:NSURL = NSURL(string: "tel://000000000000")!
if UIApplication.sharedApplication().canOpenURL(url) {
UIApplication.sharedApplication().openURL(url)
} else {
// Put your error handler code...
}
Ma préférence personnelle est d’aborder ceci avec une extension, parce que j’aime appeler la méthode directement sur l’objet string.
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)
}
}
De cette manière, il est également extensible à d’autres cas d’utilisation, tels que isValidEmail
, isValidName
ou tout autre choix requis par votre application.
Vous pouvez utiliser le type NSURL
(dont le constructeur retourne un type facultatif) associé à une instruction if-let
pour vérifier la validité d'une URL donnée. En d’autres termes, utilisez la variable NSURL
failable initializer , une fonction clé de 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)
}
Swift 4.2 Construction d'URL élégante avec vérification
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
}
Dans certains cas, il peut être suffisant de vérifier que l'URL répond à la norme RFC 1808. Il existe plusieurs façons de procéder. Un exemple:
if let url = URL(string: urlString), url.Host != nil {
// This is a correct url
}
En effet, .Host, ainsi que .path, .fragment et quelques autres méthodes renverraient zéro si l'URL n'est pas conforme à la RFC 1808.
Si vous ne vérifiez pas, vous pourriez avoir ce type de message dans le journal de la console:
Task <DF46917D-1A04-4E76-B54E-876423224DF7>.<72> finished with error - code: -1002
Ce n’est pas une approche regex, mais une approche naïve qui fonctionne bien pour s’assurer qu’il existe un hôte et une extension si vous voulez une approche simple et peu coûteuse:
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
}
}
Utilisez cette option uniquement si vous souhaitez un moyen rapide de vérification côté client et que vous disposez d'une logique de serveur permettant d'effectuer une vérification plus rigoureuse avant de sauvegarder les données.
Pour la version 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
}
Pour Swift 4, vous pouvez utiliser:
class func verifyUrl (urlString: String?) -> Bool {
//Check for nil
if let urlString = urlString {
// create NSURL instance
if let url = URL(string: urlString) {
// check if your application can open the NSURL instance
return UIApplication.shared.canOpenURL(url)
}
}
return false
}
Ceci est pour la dernière Swift 4 , basé surDoug Amosanswer (for 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
}
Cela retournera un booléen pour la validité d'une URL, ou nil si une URL facultative avec une valeur de nil est passée.
extension URL {
var isValid: Bool {
get {
return UIApplication.shared.canOpenURL(self)
}
}
}
Notez que si vous prévoyez d’utiliser une vue Safari, vous devez tester url.scheme == "http" || url.scheme == "https"
.
Essaye ça:
func isValid(urlString: String) -> Bool
{
if let urlComponents = URLComponents.init(string: urlString), urlComponents.Host != nil, urlComponents.url != nil
{
return true
}
return false
}
Ceci vérifie simplement les composants URL valides et si les composants Host et url ne sont pas nuls. En outre, vous pouvez simplement ajouter ceci à un fichier d'extensions
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.
}
Il est conseillé d'utiliser cette vérification une seule fois, puis de la réutiliser.
P.S. Crédits à Shachar pour cette fonction.