it-swarm.com.de

Wie prüfe ich die Gültigkeit der URL in Swift?

Beim Versuch, eine App den Standardbrowser mit einer URL zu starten, jedoch nur, wenn die eingegebene URL gültig ist. Andernfalls wird eine Meldung angezeigt, dass die URL ungültig ist.

Wie überprüfe ich die Gültigkeit mit Swift?

40

Wenn Sie überprüfen möchten, ob Ihre Anwendung eine URL öffnen kann, können Sie dies tun. Obwohl Safari die URL öffnen kann, existiert die Website möglicherweise nicht oder ist inaktiv.

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
}
68
3366784

Für eine Swift 3-Version der akzeptierten Antwort:

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

Oder für eine schnellere Lösung:

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

    return UIApplication.shared.canOpenURL(url)
}
21
Doug Amos

Swift 4 elegante Lösung mit 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
        }
    }
}

Verwendungszweck:

let string = "https://www.fs.blog/2017/02/naval-ravikant-reading-decision-making/"
if string.isValidURL {
    // TODO
}
17
Milan Nosáľ

Ich fand dieses sauber (In 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)
}

Verwendungszweck:

if canOpenURL("abc") {
    print("valid url.")
} else {
    print("invalid url.")
}

===

für 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.")
}
13
Ashok Kumar S

Die Verwendung von 'canOpenUrl' war für meinen Anwendungsfall zu teuer. Ich fand diesen Ansatz schneller

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
}
11
Shachar
var url:NSURL = NSURL(string: "tel://000000000000")!
if UIApplication.sharedApplication().canOpenURL(url) {
    UIApplication.sharedApplication().openURL(url)
} else {
     // Put your error handler code...
}
5

Meine persönliche Präferenz ist es, mich mit einer Erweiterung zu nähern, da ich die Methode direkt am String-Objekt aufrufen möchte.

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)
    }
}

Auf diese Weise ist es auch erweiterbar mit anderen Anwendungsfällen wie isValidEmail, isValidName oder was auch immer Ihre Anwendung erfordert.

4
Michal

Sie können den Typ NSURL (dessen Konstruktor einen optionalen Typ zurückgibt) zusammen mit einer if-let-Anweisung verwenden, um die Gültigkeit einer angegebenen URL zu überprüfen. Verwenden Sie also NSURLfailable initializer , eine Schlüsselfunktion von 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)
}
2
AstroCB

Swift 4.2 Elegante URL-Erstellung mit Verifikation

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
  }
}

Verwendungszweck

var imageUrl: URL? {
    if let url = URL(withCheck: imageString) {
        return url
    }
    if let url = URL(withCheck: image2String) {
        return url
    }
    return nil
}
2
maslovsa

In einigen Fällen kann es ausreichend sein, zu überprüfen, ob die URL RFC 1808 erfüllt. Es gibt mehrere Möglichkeiten, dies zu tun. Ein Beispiel:

if let url = URL(string: urlString), url.Host != nil {
  // This is a correct url
}

Dies liegt daran, dass .Host sowie .path, .fragment und einige andere Methoden gleich Null zurückgeben, wenn die URL nicht RFC 1808 entspricht.

Wenn Sie dies nicht überprüfen, haben Sie möglicherweise folgende Meldungen im Konsolenprotokoll:

Task <DF46917D-1A04-4E76-B54E-876423224DF7>.<72> finished with error - code: -1002
1
Vitalii

Dies ist kein Regex-Ansatz, aber es ist ein naiver Ansatz, der gut dafür sorgt, dass es einen Host und eine Erweiterung gibt, wenn Sie einen einfachen und kostengünstigen Ansatz wünschen:

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
    }
}

Verwenden Sie dies nur, wenn Sie eine schnelle Überprüfung auf der Clientseite wünschen und über eine Serverlogik verfügen, die vor dem Speichern der Daten eine genauere Prüfung durchführt.

1
lwdthe1

Für die 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
}
1

Für Swift 4 können Sie verwenden: 

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
}
0
Paolo

Version, die mit Swift 4.2 und zuverlässigem URL-Pattern-Matching funktioniert ...

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
BadmintonCat

Dies ist für neueste Swift 4 , basierend aufDoug AmosAntwort (für 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
}
0
Shefy Gur-ary

Dadurch wird ein boolescher Wert für die Gültigkeit einer URL zurückgegeben, oder nil, wenn eine optionale URL mit dem Wert nil übergeben wird.

extension URL {

    var isValid: Bool {
        get {
            return UIApplication.shared.canOpenURL(self)
        }
    }

}

Wenn Sie eine Safari-Ansicht verwenden möchten, sollten Sie url.scheme == "http" || url.scheme == "https" testen.

0
CartoonChess

Versuche dies: 

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

Dies prüft einfach, ob gültige URL-Komponenten vorhanden sind und ob die Host- und URL-Komponenten nicht gleich Null sind. Sie können dies auch einfach einer Erweiterungsdatei hinzufügen

0
Bryan Cimo
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.
}

Es wird empfohlen, diese Prüfung nur einmal zu verwenden und anschließend erneut zu verwenden.

P.S. Kredite an Shachar für diese Funktion.

0
Hemang

Helium mit verschiedenen Schemata umgehen müssen:

struct UrlHelpers {
    // Prepends `http://` if scheme isn't `https?://` unless "file://"
    static func ensureScheme(_ urlString: String) -> String {
        if !(urlString.lowercased().hasPrefix("http://") || urlString.lowercased().hasPrefix("https://")) {
            return urlString.hasPrefix("file://") ? urlString : "http://" + urlString
        } else {
            return urlString
        }
    }

    // https://mathiasbynens.be/demo/url-regex
    static func isValid(urlString: String) -> Bool {
        // swiftlint:disable:next force_try
        if urlString.lowercased().hasPrefix("file:"), let url = URL.init(string: urlString) {
            return FileManager.default.fileExists(atPath:url.path)
        }

        let regex = try! NSRegularExpression(pattern: "^(https?://)[^\\s/$.?#].[^\\s]*$")
        return (regex.firstMatch(in: urlString, range: urlString.nsrange) != nil)
    }
}
0
slashlos