2015-03-17 8 views
3

В моем проекте Swift iOS я хочу проверить, есть ли действительный URL-адрес или нет, прежде чем запрашивать сервер. Ранее я делал код Objective C для проверки многих элементов, таких как наличие www, http, https,:, и т. Д. Для проверки правильности URL-адреса или нет. У нас есть что-то подобное в коде Swift?Проверка URL-адресов в Swift

ожидаем подобный Obj C способ.

- (BOOL) validateUrl: (NSString *) candidate { 
    NSString *urlRegEx = 
    @"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"; 
    NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", urlRegEx]; 
    return [urlTest evaluateWithObject:candidate]; 
} 

Просьба предложить.

+0

Что вы делали раньше? Вы пытались сделать то же самое? – Wain

+0

Я попытался использовать предикат NSPredicateWithFormat, но не мог быть достигнут в Swift. – Stella

+0

Попробуйте это, http://stackoverflow.com/a/24207852/3411787 –

ответ

4

Вы можете использовать метод stringByAddingPercentEscapesUsingEncoding для замены специальных символов Ваша ссылка может иметь и тогда вы можете проверить, если ваша ссылка является допустимым URL с помощью NSURL(string:) следующим образом:

let link = "http://www.yourUrl.com".stringByRemovingPercentEncoding!.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)! 

if let checkedUrl = NSURL(string: link) { 
    // you can use checkedUrl here 
} 

Примечание: NSURL (строка :) только для веб-ссылок. Если вы хотите создать NSURL для файла локального ресурса, вам нужно использовать NSURL (fileURLWithPath :)

+2

Вы, вероятно, хотите объяснить обоснование – Wain

+2

@Wain Что объяснить? NSURL уже выполняет проверку и возвращает только экземпляр, если ему была присвоена действительная строка. Не нужно изобретать велосипед. –

+0

Я не сказал, изобретать колесо, просто объясните, почему он работает, поэтому в основном ваш комментарий в ответе. +1 в любом случае, но объяснение добавляет ценность. – Wain

0

Я предлагаю использовать регулярное выражение, подобное этому. Нижеприведенный шаблон верен для URL-адреса.

let regex = NSRegularExpression(pattern: "/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/",options: nil, error: nil)! 

if regex.firstMatchInString(searchTerm!, options: nil, range: NSMakeRange(0, searchTerm!.length)) != nil { 
    println("not valid url ") 
} 
+1

Правильно ли это компилируется? Он не компилирует этот код. Ошибка сборки в первой строке - «Последовательные операторы на строке должны быть разделены:» – Stella

1

У меня проблема с самым высоким рейтингом здесь. Я думаю, что это просто неправильно по двум причинам:

Первый, то stringByAddingPercentExcapedUsingEncoding фактически двойные кодируют действительные URL-адреса, что делает их недействительными или, по крайней мере, отличается от исходного входа. Если входная строка уже правильно закодированная URL-адрес, вы должны просто использовать ее.

Например, http://foo.com/My%20Stuff/ станет http://foo.com/My%2520Stuff/, что не является тождественным. Если вы передадите это NSURL, он фактически расшифрует его URL-адресом с буквами %.

Второй, NSURL, как известно, очень плохо распознает плохой вход. Например, он с радостью возвращает результат non-nil, когда вы даете ему что-то вроде x/3:()foo/blah, которое явно искажено и не является допустимым URL.

Я думаю, что лучше использовать регулярное выражение. Я не думаю, что есть что-то в Foundation, который может правильно проверять URL-адреса.

1

Попробуйте это.

func validateUrl (urlString: String?) -> Bool { 
    let urlRegEx = "(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+" 
    return NSPredicate(format: "SELF MATCHES %@", urlRegEx).evaluateWithObject(urlString) 
} 
0

После кода проверки на http://google.com или http://www.google.com, проверил его http://9gag.com тоже, но без HTTP или HTTPS метить он не будет работать. Если вы пропустите имя домена (в этом случае Google), он покажет ошибку.

func checkGivenUrl(userURL:String) -> Bool { 

    let userURL:String = userURL 

    do { 
     let checkReg = try NSRegularExpression(pattern: "(http|https)://([A-Z]|[a-z].)|([A-Z]|[a-z]|[0-9]+)*.([a-z]|[A-Z])", options: .CaseInsensitive) 

     if checkReg.firstMatchInString(userURL, options: .ReportCompletion, range: NSMakeRange(0, userURL.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))) != nil { 

      if let url = NSURL(string: userURL) { 
      if UIApplication.sharedApplication().canOpenURL(url) { 

       return true 
      } 
      } 
      return false 
     } 

    } 

    catch 
    { 
     print("Error") 
    } 


    return false 
} 

Вызов функции выглядит

requestedURL = "http://google.com" 
    if checkGivenUrl(requestedURL!) == true { 
    performSegueWithIdentifier("gotoWebView", sender: self) 
    } 
    else{ 
     let alert = UIAlertController(title: "Failed", message: "Enter a valid URL", preferredStyle: .Alert) 
     alert.addAction(UIAlertAction(title: "Dismiss", style: .Cancel, handler: nil)) 

     self.presentViewController(alert, animated: true, completion: nil) 
    } 
} 

Пожалуйста, комментарий, если вы обнаружите какие-либо тестовые случаи, которые не подходят к описанным выше способом.Я постараюсь их решить :)

+0

firebase.google.com возвращает false. Не могли бы вы помочь добавить этот сценарий? –

+1

Вы должны упомянуть https: // или http: // то только он будет работать. Протокол необходим, поскольку я проверяю, можно ли открыть URL-адрес. –

0

Я обнаружил, что это довольно легко стремительной

func validateUrl() -> Bool { 
    let urlRegEx = "((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+" 
    return NSPredicate(format: "SELF MATCHES %@", urlRegEx).evaluate(with: self) 
} 

Я нахожу это легко. Если вы положили в качестве расширения или только в классе вы можете сказать

func fooBar(textField: UITextField) { 
    if textField == someTextField { 
     if textField.text?.validateUrl() == true { 
     print("true") 
     } else { 
     print("false") 
     } 
    } 
} 

Очень похожи на другие ответы Тхо, и года конца

Это не требует HTTP части, я чувствую, как большинство пользователей Wouldn не печатайте на http или https, например, http://www.google.com, а просто на google.com или www.google.com.

Очевидно, что вы могли бы пройти лишнюю милю и проверить, не сделали ли они или не поместили http (s) и если вы действительно хотите добавить это самостоятельно .. или не

0

У меня есть другое решение. В Swift 3

import Foundation 
import UIKit 

extension String { 

    var canOpenURL : Bool { 

     guard let url = NSURL(string: self) else {return false} 
     if !UIApplication.shared.canOpenURL(url as URL) {return false} 
     let regEx = "((https|http)://)((\\w|-)+)(([.]|[/])((\\w|-)+))+" 
     let predicate = NSPredicate(format:"SELF MATCHES %@", argumentArray:[regEx]) 
     return predicate.evaluate(with: self) 
    } 
} 

Он может быть использован в качестве

if textField == someTextField { 

    if (self.textField.text?.canOpenURL)! { 
     //URL valid 
    }else { 
     //URL invalid 
    } 
} 
0

Вы можете использовать Regex для проверки Формат URL

(https?://(www.)?)?[[email protected]:%._+~#=]{2,256}.[a-z]{2,6}b([[email protected]:%_+.~#?&//=]*) 

СВИФТ 4:

func validateURL (urlString: String) -> Bool { 
    let urlRegEx = "(https?://(www.)?)?[[email protected]:%._+~#=]{2,256}.[a-z]{2,6}b([[email protected]:%_+.~#?&//=]*)" 
    let urlTest = NSPredicate(format:"SELF MATCHES %@", urlRegEx) 
    return urlTest.evaluate(with: urlString) 
} 
Смежные вопросы