iPhone에서 URL의 유효성을 검사하는 방법
제가 개발 중인 아이폰 앱에는 URL을 입력할 수 있는 설정이 있는데, 양식과 기능 때문에 이 URL은 오프라인뿐만 아니라 온라인에서도 확인해야 합니다.
지금까지 URL을 확인할 수 있는 방법을 찾지 못했기 때문에 질문은;
오프라인뿐만 아니라 온라인에서도 iPhone(Objective-C)의 URL 입력을 확인하려면 어떻게 해야 합니까?
대신에 단순히 의존하는 것이 어때요?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을 준수해야 합니다.이 방법은 RFC 1738 및 1808에 따라 URL 문자열을 구문 분석합니다.반환 값
URL 문자열로 초기화된 NSURL 개체입니다.문자열 형식이 잘못된 경우 0을 반환합니다.
이 게시물 덕분에 RegexKit 사용을 피할 수 있습니다.제 솔루션은 다음과 같습니다(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];
}
Swift에서 아래에 제시된 내 솔루션을 확인하려면:
func isValidUrl(url: String) -> Bool {
let urlRegEx = "^(https?://)?(www\\.)?([-a-z0-9]{1,63}\\.)*?[a-z0-9][-a-z0-9]{0,61}[a-z0-9]\\.[a-z]{2,6}(/[-\\w@\\+\\.~#\\?&/=%]*)?$"
let urlTest = NSPredicate(format:"SELF MATCHES %@", urlRegEx)
let result = urlTest.evaluate(with: url)
return result
}
여러분만의 정규 표현을 쓰는 대신에, 애플의 표현에 의존하세요.문자열 내에 링크가 있는지 테스트하는 데 사용되는 범주를 사용하고 있습니다.다음에 의해 발견된 링크의 범위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;
}
Swift를 통한 솔루션:
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
이걸 사용해봐요
NSString *urlRegEx = @"http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?";
RegexKit을 사용하여 문제를 해결하고 URL을 검증하기 위해 빠른 regex를 구축했습니다.
NSString *regexString = @"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+";
NSString *subjectString = brandLink.text;
NSString *matchedString = [subjectString stringByMatching:regexString];
그런 다음 matchedString이 subjectString과 동일한지 확인하고 URL이 유효한지 확인합니다 :)
정규식이 틀리면 수정합니다;)
이를 위한 가장 쉬운 방법은 다음과 같습니다.
- (BOOL)validateUrl: (NSURL *)candidate
{
NSURLRequest *req = [NSURLRequest requestWithURL:candidate];
return [NSURLConnection canHandleRequest:req];
}
이상하게도, 저는 여기서 아주 간단한 해결책을 찾지 못했지만, 여전히 문제를 해결하기 위해 노력했습니다.http
/https
링크.
이것이 완벽한 해결책은 아니지만 아래의 경우에는 효과가 있었습니다.요약하면 정규식은 URL이 다음으로 시작하는지 여부를 테스트합니다.http://
또는https://
그런 다음 하나 이상의 문자를 확인하고 점을 확인한 다음 하나 이상의 문자를 다시 확인합니다.공백은 허용되지 않습니다.
+ (BOOL)validateLink:(NSString *)link
{
NSString *regex = @"(?i)(http|https)(:\\/\\/)([^ .]+)(\\.)([^ \n]+)";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
return [predicate evaluateWithObject:link];
}
다음 URL에 대해 VALID로 테스트되었습니다.
@"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:password@example.com:8080",
@"http://userid:password@example.com:8080/",
@"http://userid@example.com",
@"http://userid@example.com/",
@"http://userid@example.com:8080",
@"http://userid@example.com:8080/",
@"http://userid:password@example.com",
@"http://userid:password@example.com/",
@"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
당신이 원하지 않는다면 이것을 사용할 수 있습니다.http
또는https
또는www
NSString *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
Lefakir의 해결책은 한 가지 문제가 있습니다.그의 정규 표현식은 "http://instagram.com/p/4Mz3dTJ-ra/ "과 일치하지 않습니다.URL 구성 요소에 숫자와 리터럴 문자가 결합되었습니다.그의 정규 표현은 그런 URL에 실패합니다.
이것이 저의 개선점입니다.
"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*)+)+(/)?(\\?.*)?"
아래 코드를 사용하면 올바른 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에 대하여.
- http://123.com
- https://123.com
- http://www.123.com
- https://www.123.com
- ftp://123.com
- ftp://www.123.com
- www.something.com
승인된 답변이 올바르지 않습니다."-"가 포함된 URL이 있는데 유효성 검사에 실패합니다.
G+ 링크 지원을 위한 Vaibhav의 답변은 다음과 같습니다.
NSString *urlRegEx = @"http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w-\\+ ./?%&=]*)?";
일부 URL의 끝 부분이 위의 솔루션에서 올바른 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
}
}
Swift에서 URL 유효성 검사
세부 사항
Xcode 8.2.1, Swift 3
코드
열거 URL 스키마:끈
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:pass@site.com: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:password@example.com:8080")
chekUrl(urlString:"http://userid@example.com")
chekUrl(urlString:"http://userid@example.com: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)
}
결과
목표 C
- (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.
도움이 되길 바랍니다.
이기적으로, 저는 입력을 검증하고 변환하기 위해 인스턴스를 사용하는 것을 제안합니다.NSURL
처리할 수 있습니다.
정규식 문자열을 사용하여 모든 종류의 유효성 검사를 처리할 수 있는 상속된 UITextField 클래스를 만들었습니다.여기에서는 유효성 검사에 실패했을 때 표시할 모든 정규식 문자열과 메시지를 순서대로 제공하기만 하면 됩니다.더 많은 정보를 위해 제 블로그를 확인할 수 있습니다. 그것은 당신에게 정말 도움이 될 것입니다.
http://dhawaldawar.wordpress.com/2014/06/11/uitextfield-validation-ios/
을 swift로 는 @Anthony 답로변 swift 여장확하카를썼, 의▁on에 를 썼습니다.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)
}
Swift 5에 대한 나의 솔루션:
extension String {
func isValidUrl() -> Bool {
do {
let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
// check if the string has link inside
return detector.numberOfMatches(in: self, options: [], range: .init( location: 0, length: utf16.count)) > 0
} catch {
print("Error during NSDatadetector initialization \(error)" )
}
return false
}
}
언급URL : https://stackoverflow.com/questions/1471201/how-to-validate-an-url-on-the-iphone
'programing' 카테고리의 다른 글
python의 mysql 인스턴스 설치 문제 (0) | 2023.08.26 |
---|---|
"SELECT DISTINCT"는 다른 경우를 무시합니다. (0) | 2023.08.26 |
Android Webview는 다음과 같은 이점을 제공합니다.ERR_CACH_MISS 메시지 (0) | 2023.08.21 |
SQL 서버에서 업데이트 전 트리거를 수행하려면 어떻게 해야 합니까? (0) | 2023.08.21 |
스프링 부트 액추에이터가 작동하지 않음 (0) | 2023.08.21 |