比较两个NSURL或一个NSURL和一个NSString的可靠方法?

hzx*_*zxu 19 objective-c nsurl uiwebview nsstring nsurlrequest

我最近在比较两个NSURL并将一个NSURL与NSString(这是一个URL地址)进行比较时遇到了问题,情况是我从某个地方得到了一个N​​SURLRequest,我可能知道也可能不知道它指向的URL地址,我有一个URL NSString,比如"http://m.google.com",现在我需要检查NSURLRequest中的URL是否与我的URL字符串相同:

[[request.URL.absoluteString lowercaseString] isEqualToString: [self.myAddress lowercaseString]];
Run Code Online (Sandbox Code Playgroud)

这返回NO,因为它absoluteString给了我"http://m.google.com/",而我的字符串是"http://m.google.com",最后没有斜线,即使我使用创建NSURLRequest

[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://m.google.com"]]
Run Code Online (Sandbox Code Playgroud)

它仍然给我"http://m.google.com/" absoluteString,我想有没有可靠的方法来比较NSURL或一个NSURL和一个NSString?

  1. 检查一个'包含'是否另一个,但这不可靠,因为'http://m.google.com/blabla'包含'http://m.google.com'.

  2. 将NSString转换为NSURL并使用该isEqual方法比较两个NSURL并希望NSURL的实现isEqual可以搞清楚吗?

  3. 基于步骤2,但使用standardizedURL?将每个NSURL转换为标准URL ?

非常感谢!

dan*_*anh 28

如果你只关心斜杠的模糊性,你可以通过知道NSURL路径修剪尾部斜杠来快速省去这个问题.

但我喜欢NSURL上的类别方法的想法,它实现了一些基于标准的等价(在这种情况下,"等价"可能是比平等更好的术语).

@RobNapier提到了一个相关的问题,其答案很好,指向RFC2616.url语法的另一个相关标准是RFC1808.

困难的部分是通过等价来决定我们的意思,例如,不同的查询或片段(锚链接)是什么?下面的代码在大多数这些歧义的允许方面犯了错误......

// in NSURL+uriEquivalence.m

- (BOOL)isEquivalent:(NSURL *)aURL {

    if ([self isEqual:aURL]) return YES;
    if ([[self scheme] caseInsensitiveCompare:[aURL scheme]] != NSOrderedSame) return NO;
    if ([[self host] caseInsensitiveCompare:[aURL host]] != NSOrderedSame) return NO;

    // NSURL path is smart about trimming trailing slashes
    // note case-sensitivty here
    if ([[self path] compare:[aURL path]] != NSOrderedSame) return NO;

    // at this point, we've established that the urls are equivalent according to the rfc
    // insofar as scheme, host, and paths match

    // according to rfc2616, port's can weakly match if one is missing and the
    // other is default for the scheme, but for now, let's insist on an explicit match
    if ([self port] || [aURL port]) {
        if (![[self port] isEqual:[aURL port]]) return NO;
        if (![[self query] isEqual:[aURL query]]) return NO;
    }

    // for things like user/pw, fragment, etc., seems sensible to be
    // permissive about these.
    return YES;
}
Run Code Online (Sandbox Code Playgroud)

  • 这种方法使用起来并不安全.如果```self.query == nil```但是aURL.query不是方法返回YES; (2认同)