ios 如何在 iPhone 上验证 url

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1471201/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:27:13  来源:igfitidea点击:

How to validate an url on the iPhone

iosobjective-ciphonexcodeurl

提问by Thizzer

In an iPhone app I am developing, there is a setting in which you can enter a URL, because of form & function this URL needs to be validated online as well as offline.

在我正在开发的 iPhone 应用程序中,有一个设置,您可以在其中输入 URL,由于形式和功能,此 URL 需要在线和离线验证。

So far I haven't been able to find any method to validate the url, so the question is;

到目前为止,我还没有找到任何方法来验证 url,所以问题是;

How do I validate an URL input on the iPhone (Objective-C) online as well as offline?

如何在线和离线验证 iPhone (Objective-C) 上的 URL 输入?

回答by Vincent Guerci

Why not instead simply rely on Foundation.framework?

为什么不干脆依靠Foundation.framework

That does the job and does not require RegexKit:

这可以完成工作并且不需要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)
}

According to Apple documentation :

根据苹果文档:

URLWithString:Creates and returns an NSURL object initialized with a provided string.

+ (id)URLWithString:(NSString *)URLString

Parameters

URLString: The string with which to initialize the NSURL object. Must conform to RFC 2396. This method parses URLString according to RFCs 1738 and 1808.

Return Value

An NSURL object initialized with URLString. If the string was malformed, returns nil.

URLWithString:创建并返回一个用提供的字符串初始化的 NSURL 对象。

+ (id)URLWithString:(NSString *)URLString

参数

URLString: 用于初始化 NSURL 对象的字符串。必须符合 RFC 2396。此方法根据 RFC 1738 和 1808 解析 URLString。

返回值

一个用 URLString 初始化的 NSURL 对象。如果字符串格式错误,则返回 nil。

回答by lefakir

Thanks to this post, you can avoid using RegexKit. Here is my solution (works for iphone development with iOS > 3.0) :

感谢这篇文章,您可以避免使用 RegexKit。这是我的解决方案(适用于 iOS > 3.0 的 iphone 开发):

- (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];
}

If you want to check in Swift my solution given below:

如果你想签入 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
    }

回答by Anthony

Instead of writing your own regular expressions, rely on Apple's. I have been using a category on NSStringthat uses NSDataDetectorto test for the presence of a link within a string. If the range of the link found by NSDataDetectorequals the length of the entire string, then it is a valid URL.

与其编写自己的正则表达式,不如依赖 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;
}

回答by Gabriel.Massana

My solution with Swift:

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

For Test:

测试:

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

Results:

结果:

false
false
false
true
false
false
true
true
false
false
false

回答by Vaibhav Saran

use this-

用这个-

NSString *urlRegEx = @"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?";

回答by Thizzer

I solved the problem using RegexKit, and build a quick regex to validate a URL;

我使用RegexKit解决了这个问题,并构建了一个快速的正则表达式来验证 URL;

NSString *regexString = @"(http|https)://((\w)*|([0-9]*)|([-|_])*)+([\.|/]((\w)*|([0-9]*)|([-|_])*))+";
NSString *subjectString = brandLink.text;
NSString *matchedString = [subjectString stringByMatching:regexString];

Then I check if the matchedString is equal to the subjectString and if that is the case the url is valid :)

然后我检查匹配字符串是否等于主题字符串,如果是这种情况,则 url 有效:)

Correct me if my regex is wrong ;)

如果我的正则表达式有误,请纠正我;)

回答by kgaidis

Oddly enough, I didn't really find a solution here that was very simple, yet still did an okay job for handling http/ httpslinks.

奇怪的是,我在这里并没有真正找到一个非常简单的解决方案,但在处理http/https链接方面仍然做得很好。

Keep in mind, THIS IS NOT a perfect solution, but it worked for the cases below. In summary, the regex tests whether the URL starts with http://or https://, then checks for at least 1 character, then checks for a dot, and then again checks for at least 1 character. No spaces allowed.

请记住,这不是一个完美的解决方案,但它适用于以下情况。总之,正则表达式测试 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];
}

Tested VALID against these URLs:

针对这些 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:[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"

Tested INVALID against these URLs:

针对这些 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"

Source of URLs: https://mathiasbynens.be/demo/url-regex

URL 来源:https: //mathiasbynens.be/demo/url-regex

回答by Hiren

You can use this if you do not want httpor httpsor www

如果您不想要httphttps或,您可以使用它www

NSString *urlRegEx = @"^(http(s)?://)?((www)?\.)?[\w]+\.[\w]+";

example

例子

- (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"];
}

Output:

输出:

INVALID: google
VALID: google.de
VALID: www.google.de
VALID: http://www.google.de
VALID: http://google.de

回答by covernal

Lefakir's solution has one issue. His regex can't match with "http://instagram.com/p/4Mz3dTJ-ra/". Url component has combined numerical and literal character. His regex fail such urls.

Lefakir 的解决方案有一个问题。他的正则表达式无法与“ http://instagram.com/p/4Mz3dTJ-ra/”匹配。Url 组件结合了数字和文字字符。他的正则表达式失败了这样的网址。

Here is my improvement.

这是我的改进。

"(http|https)://((\w)*|([0-9]*)|([-|_])*)+([\.|/]((\w)*|([0-9]*)|([-|_])*)+)+(/)?(\?.*)?"

回答by julianwyz

I've found the easiest way to do this is like so:

我发现最简单的方法是这样的:

- (BOOL)validateUrl: (NSURL *)candidate
{
    NSURLRequest *req = [NSURLRequest requestWithURL:candidate];
    return [NSURLConnection canHandleRequest:req];
}