Как проверить url-адрес на iPhone
в приложении для iPhone, которое я разрабатываю, есть настройка, в которой вы можете ввести URL-адрес, потому что форма и функция этот URL-адрес должен быть проверен онлайн, а также в автономном режиме.
до сих пор я не смог найти какой-либо метод для проверки url, поэтому вопрос;
Как проверить ввод URL-адреса на iPhone (Objective-C) онлайн, а также в автономном режиме?
21 ответов:
спасибо этот пост, вы можете избежать использования RegexKit. Вот мое решение (работает для разработки iphone с iOS > 3.0):
- (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]; }
почему бы вместо этого просто не положиться на
Foundation.framework?что делает работу и не требует
RegexKit:NSURL *candidateURL = [NSURL URLWithString:candidate]; // WARNING > "test" is an URL according to RFCs, being just a path // so you still should check scheme and all other NSURL attributes you need if (candidateURL && candidateURL.scheme && candidateURL.host) { // candidate is a well-formed url with: // - a scheme (like http://) // - a host (like stackoverflow.com) }согласно документации Apple :
URLWithString: создает и возвращает объект NSURL, инициализированный с помощью предоставленная строка.
+ (id)URLWithString:(NSString *)URLStringпараметры
URLString: строка, с помощью которой инициализируется объект NSURL. Должен соответствовать RFC 2396. Этот метод анализирует URLString в соответствии с RFC 1738 и 1808.Возвращаемое Значение
объект NSURL, инициализированный с помощью URLString. если строка была искажена, возвращает nil.
вместо того, чтобы писать свои регулярные выражения, полагаться на компании Apple. Я использую категорию на
NSStringиспользуетNSDataDetectorчтобы проверить наличие ссылки в строке. Если диапазон ссылки найден поNSDataDetectorравна длине всей строки, то это допустимый URL.- (BOOL)isValidURL { NSUInteger length = [self length]; // Empty strings should return NO if (length > 0) { NSError *error = nil; NSDataDetector *dataDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:&error]; if (dataDetector && !error) { NSRange range = NSMakeRange(0, length); NSRange notFoundRange = (NSRange){NSNotFound, 0}; NSRange linkRange = [dataDetector rangeOfFirstMatchInString:self options:0 range:range]; if (!NSEqualRanges(notFoundRange, linkRange) && NSEqualRanges(range, linkRange)) { return YES; } } else { NSLog(@"Could not create link data detector: %@ %@", [error localizedDescription], [error userInfo]); } } return NO; }
мое решение с Свифт:
func validateUrl (stringURL : NSString) -> Bool { var urlRegEx = "((https|http)://)((\w|-)+)(([.]|[/])((\w|-)+))+" let predicate = NSPredicate(format:"SELF MATCHES %@", argumentArray:[urlRegEx]) var urlTest = NSPredicate.predicateWithSubstitutionVariables(predicate) return predicate.evaluateWithObject(stringURL) }Для Теста:
var boolean1 = validateUrl("http.s://www.gmail.com") var boolean2 = validateUrl("https:.//gmailcom") var boolean3 = validateUrl("https://gmail.me.") var boolean4 = validateUrl("https://www.gmail.me.com.com.com.com") var boolean6 = validateUrl("http:/./ww-w.wowone.com") var boolean7 = validateUrl("http://.www.wowone") var boolean8 = validateUrl("http://www.wow-one.com") var boolean9 = validateUrl("http://www.wow_one.com") var boolean10 = validateUrl("http://.") var boolean11 = validateUrl("http://") var boolean12 = validateUrl("http://k")результаты:
false false false true false false true true false false false
Я решил проблему с помощью RegexKit, и построить быстрое регулярное выражение для проверки URL;
NSString *regexString = @"(http|https)://((\w)*|([0-9]*)|([-|_])*)+([\.|/]((\w)*|([0-9]*)|([-|_])*))+"; NSString *subjectString = brandLink.text; NSString *matchedString = [subjectString stringByMatching:regexString];затем я проверяю, если matchedString равен subjectString и если это так, url-адрес действителен :)
поправьте меня, если мое регулярное выражение неправильно ;)
вы можете использовать это, если вы не хотите, чтобы
httpилиhttpsилиwwwNSString *urlRegEx = @"^(http(s)?://)?((www)?\.)?[\w]+\.[\w]+";пример
- (void) testUrl:(NSString *)urlString{ NSLog(@"%@: %@", ([self isValidUrl:urlString] ? @"VALID" : @"INVALID"), urlString); } - (void)doTestUrls{ [self testUrl:@"google"]; [self testUrl:@"google.de"]; [self testUrl:@"www.google.de"]; [self testUrl:@"http://www.google.de"]; [self testUrl:@"http://google.de"]; }выход:
INVALID: google VALID: google.de VALID: www.google.de VALID: http://www.google.de VALID: http://google.de
решение Лефакира имеет одну проблему. Его регулярное выражение не может совпадать с "http://instagram.com/p/4Mz3dTJ-ra/". Компонент Url имеет комбинированный числовой и буквенный характер. Его выражение не такие URL.
вот мое улучшение.
"(http|https)://((\w)*|([0-9]*)|([-|_])*)+([\.|/]((\w)*|([0-9]*)|([-|_])*)+)+(/)?(\?.*)?"
Я нашел самый простой способ сделать это вот так:
- (BOOL)validateUrl: (NSURL *)candidate { NSURLRequest *req = [NSURLRequest requestWithURL:candidate]; return [NSURLConnection canHandleRequest:req]; }
как ни странно, я действительно не нашел здесь решение, которое было очень простым, но все же сделал хорошую работу для обработки
http/httpsссылки.имейте в виду, что это не идеальное решение, но оно сработало для случаев ниже. Таким образом, регулярное выражение проверяет, начинается ли URL-адрес с
http://илиhttps://, затем проверяет наличие по крайней мере 1 символа, затем проверяет наличие точки, а затем снова проверяет наличие по крайней мере 1 символа. Места не допускаются.+ (BOOL)validateLink:(NSString *)link { NSString *regex = @"(?i)(http|https)(:\/\/)([^ .]+)(\.)([^ \n]+)"; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex]; return [predicate evaluateWithObject:link]; }проверено действует против этих URL:
@"HTTP://FOO.COM", @"HTTPS://FOO.COM", @"http://foo.com/blah_blah", @"http://foo.com/blah_blah/", @"http://foo.com/blah_blah_(wikipedia)", @"http://foo.com/blah_blah_(wikipedia)_(again)", @"http://www.example.com/wpstyle/?p=364", @"https://www.example.com/foo/?bar=baz&inga=42&quux", @"http://✪df.ws/123", @"http://userid:[email protected]:8080", @"http://userid:[email protected]:8080/", @"http://[email protected]", @"http://[email protected]/", @"http://[email protected]:8080", @"http://[email protected]:8080/", @"http://userid:[email protected]", @"http://userid:[email protected]/", @"http://142.42.1.1/", @"http://142.42.1.1:8080/", @"http://➡.ws/䨹", @"http://⌘.ws", @"http://⌘.ws/", @"http://foo.com/blah_(wikipedia)#cite-", @"http://foo.com/blah_(wikipedia)_blah#cite-", @"http://foo.com/unicode_(✪)_in_parens", @"http://foo.com/(something)?after=parens", @"http://☺.damowmow.com/", @"http://code.google.com/events/#&product=browser", @"http://j.mp", @"http://foo.bar/?q=Test%20URL-encoded%20stuff", @"http://مثال.إختبار", @"http://例子.测试", @"http://उदाहरण.परीक्षा", @"http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", @"http://1337.net", @"http://a.b-c.de", @"http://223.255.255.254"протестировано неверно против этих URL:
@"", @"foo", @"ftp://foo.com", @"ftp://foo.com", @"http://..", @"http://..", @"http://../", @"//", @"///", @"http://##/", @"http://.www.foo.bar./", @"rdar://1234", @"http://foo.bar?q=Spaces should be encoded", @"http:// shouldfail.com", @":// should fail"источник URL-адресов: https://mathiasbynens.be/demo/url-regex
ниже код позволит вам найти действительные URL-адреса
NSPredicate *websitePredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",@"^(((((h|H)(t|T){2}(p|P)s?)|((f|F)(t|T)(p|P)))://(w{3}.)?)|(w{3}.))[A-Za-z0-9]+(.[A-Za-z0-9-:;\?#_]+)+"]; if ([websitePredicate evaluateWithObject:##MY_STRING##]) { printf"Valid" }для таких URL-адресов
Tweeked Vaibhav ответ на поддержку G + ссылки:
NSString *urlRegEx = @"http(s)?://([\w-]+\.)+[\w-]+(/[\w-\+ ./?%&=]*)?";
некоторые URL-адреса без / в конце не определяются как правильные в решениях выше. Так что это может быть полезно.
extension String { func isValidURL() -> Bool{ let length:Int = self.characters.count var err:NSError? var dataDetector:NSDataDetector? = NSDataDetector() do{ dataDetector = try NSDataDetector(types: NSTextCheckingType.Link.rawValue) }catch{ err = error as NSError } if dataDetector != nil{ let range = NSMakeRange(0, length) let notFoundRange = NSRange(location: NSNotFound, length: 0) let linkRange = dataDetector?.rangeOfFirstMatchInString(self, options: NSMatchingOptions.init(rawValue: 0), range: range) if !NSEqualRanges(notFoundRange, linkRange!) && NSEqualRanges(range, linkRange!){ return true } }else{ print("Could not create link data detector: \(err?.localizedDescription): \(err?.userInfo)") } return false } }
проверка URL в Swift
подробности
Xcode 8.2.1, Swift 3
код
перечисление URLSchemes: String
import Foundation enum URLSchemes: String { case http = "http://", https = "https://", ftp = "ftp://", unknown = "unknown://" static func detectScheme(urlString: String) -> URLSchemes { if URLSchemes.isSchemeCorrect(urlString: urlString, scheme: .http) { return .http } if URLSchemes.isSchemeCorrect(urlString: urlString, scheme: .https) { return .https } if URLSchemes.isSchemeCorrect(urlString: urlString, scheme: .ftp) { return .ftp } return .unknown } static func getAllSchemes(separetedBy separator: String) -> String { return "\(URLSchemes.http.rawValue)\(separator)\(URLSchemes.https.rawValue)\(separator)\(URLSchemes.ftp.rawValue)" } private static func isSchemeCorrect(urlString: String, scheme: URLSchemes) -> Bool { if urlString.replacingOccurrences(of: scheme.rawValue, with: "") == urlString { return false } return true } }строка расширение
import Foundation extension String { var isUrl: Bool { // for http://regexr.com checking // (?:(?:https?|ftp):\/\/)(?:xn--)?(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[#-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)? let schemes = URLSchemes.getAllSchemes(separetedBy: "|").replacingOccurrences(of: "://", with: "") let regex = "(?:(?:\(schemes)):\/\/)(?:xn--)?(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[#-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?" let regularExpression = try! NSRegularExpression(pattern: regex, options: []) let range = NSRange(location: 0, length: self.characters.count) let matches = regularExpression.matches(in: self, options: [], range: range) for match in matches { if range.location == match.range.location && range.length == match.range.length { return true } } return false } var toURL: URL? { let urlChecker: (String)->(URL?) = { url_string in if url_string.isUrl, let url = URL(string: url_string) { return url } return nil } if !contains(".") { return nil } if let url = urlChecker(self) { return url } let scheme = URLSchemes.detectScheme(urlString: self) if scheme == .unknown { let newEncodedString = URLSchemes.http.rawValue + self if let url = urlChecker(newEncodedString) { return url } } return nil } }использование
func tests() { chekUrl(urlString:"http://example.com") chekUrl(urlString:"https://example.com") chekUrl(urlString:"http://example.com/dir/file.php?var=moo") chekUrl(urlString:"http://xn--h1aehhjhg.xn--d1acj3b") chekUrl(urlString:"http://www.example.com/wpstyle/?p=364") chekUrl(urlString:"http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com") chekUrl(urlString:"http://example.com") chekUrl(urlString:"http://xn--d1acpjx3f.xn--p1ai") chekUrl(urlString:"http://xn--74h.damowmow.com/") chekUrl(urlString:"ftp://example.com:129/myfiles") chekUrl(urlString:"ftp://user:[email protected]:21/file/dir") chekUrl(urlString:"ftp://ftp.example.com:2828/asdah%20asdah.gif") chekUrl(urlString:"http://142.42.1.1:8080/") chekUrl(urlString:"http://142.42.1.1/") chekUrl(urlString:"http://userid:[email protected]:8080") chekUrl(urlString:"http://[email protected]") chekUrl(urlString:"http://[email protected]:8080") chekUrl(urlString:"http://foo.com/blah_(wikipedia)#cite-1") chekUrl(urlString:"http://foo.com/(something)?after=parens") print("\n----------------------------------------------\n") chekUrl(urlString:".") chekUrl(urlString:" ") chekUrl(urlString:"") chekUrl(urlString:"-/:;()&@.,?!'{}[];'<>+_)(*#^%$") chekUrl(urlString:"localhost") chekUrl(urlString:"yandex.") chekUrl(urlString:"коряга") chekUrl(urlString:"http:///a") chekUrl(urlString:"ftps://foo.bar/") chekUrl(urlString:"rdar://1234") chekUrl(urlString:"h://test") chekUrl(urlString:":// should fail") chekUrl(urlString:"http://-error-.invalid/") chekUrl(urlString:"http://.www.example.com/") } func chekUrl(urlString: String) { var result = "" if urlString.isUrl { result += "url: " } else { result += "not url: " } result += "\"\(urlString)\"" print(result) }результат
С
- (BOOL)validateUrlString:(NSString*)urlString { if (!urlString) { return NO; } NSDataDetector *linkDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil]; NSRange urlStringRange = NSMakeRange(0, [urlString length]); NSMatchingOptions matchingOptions = 0; if (1 != [linkDetector numberOfMatchesInString:urlString options:matchingOptions range:urlStringRange]) { return NO; } NSTextCheckingResult *checkingResult = [linkDetector firstMatchInString:urlString options:matchingOptions range:urlStringRange]; return checkingResult.resultType == NSTextCheckingTypeLink && NSEqualRanges(checkingResult.range, urlStringRange); }надеюсь, что это помогает!
вы хотели проверить, является ли введенный пользователем URL-адрес? Это может быть так же просто, как регулярное выражение, например проверка, если строка содержит
www.(Это способ, которым Yahoo messenger проверяет, является ли статус пользователя ссылкой или нет)
Надеюсь, что поможет
эгоистично, я бы предложил использовать
KSURLFormatterэкземпляр для проверки ввода и преобразования его в нечтоNSURLсправлюсь.
Я создал унаследованный класс UITextField, который может обрабатывать все виды проверки с помощью строки регулярного выражения. В этом вам просто нужно дать им все строки регулярных выражений в последовательности и их сообщение, которое вы хотите показать, когда проверка не удалась. Вы можете проверить мой блог для получения дополнительной информации, это действительно поможет вам
http://dhawaldawar.wordpress.com/2014/06/11/uitextfield-validation-ios/
расширяя ответ @ Anthony на swift, я написал категорию на
Stringкоторый возвращает необязательныйNSURL. Возвращаемое значениеnilЕслиStringне может быть проверено, чтобы быть URL.import Foundation // A private global detector variable which can be reused. private let detector = try! NSDataDetector(types: NSTextCheckingType.Link.rawValue) extension String { func URL() -> NSURL? { let textRange = NSMakeRange(0, self.characters.count) guard let URLResult = detector.firstMatchInString(self, options: [], range: textRange) else { return nil } // This checks that the whole string is the detected URL. In case // you don't have such a requirement, you can remove this code // and return the URL from URLResult. guard NSEqualRanges(URLResult.range, textRange) else { return nil } return NSURL(string: self) } }
func checkValidUrl(_ strUrl: String) -> Bool { let urlRegEx: String = "(http|https)://((\w)*|([0-9]*)|([-|_])*)+([\.|/]((\w)*|([0-9]*)|([-|_])*))+" let urlTest = NSPredicate(format: "SELF MATCHES %@", urlRegEx) return urlTest.evaluate(with: strUrl) }

Comments