美文网首页iOS开发
iOS OC URL 解析参数,最终输出 NSDictionar

iOS OC URL 解析参数,最终输出 NSDictionar

作者: z_hy | 来源:发表于2018-11-14 10:26 被阅读287次
    so?.jpg

    项目中有一套 Router 根据 URL 跳转机制,在实现过程中发现如果 URL 中嵌套另外一个 URL 时,解析会出问题,引起不必要的 bug, 特此记录一下。

    一. 设计思路是将嵌套的 URL Encode 之后当做参数传入,解析外层 URL query,这样就可以得到完整的内层 URL。

    1. 方法一:
    NSString *hString = [aString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    

    这个方法在 iOS 9 之后就被废弃了,但也可以使用,只不过是有警告⚠️。而且对于 URL(例如:http://www.baidu.com?a=b&c=d)中的特殊字符 '&' 不会 encode ,在解析的时候就会出问题。

    1. 方法二:
    NSString *hString = [aString stringByAddingPercentEncodingWithAllowedCharacters: URLHostAllowedCharacterSet];
    

    这个方法中 URLHostAllowedCharacterSet 是官方 API 中给出了几个枚举值:

    URLHostAllowedCharacterSet      "#%/<>?@\^`{|}
    
    URLFragmentAllowedCharacterSet  "#%<>[\]^`{|}
    
    URLPasswordAllowedCharacterSet  "#%/:<>?@[\]^`{|}
    
    URLPathAllowedCharacterSet      "#%;<>?[\]^`{|}
    
    URLQueryAllowedCharacterSet     "#%<>[\]^`{|}
    
    URLUserAllowedCharacterSet      "#%/:<>?@[\]^`
    

    仔细观察就会发现这几个枚举值中的字符集中并没有对 '&' 进行特殊处理,所以就需要自己手动规定需要 encode 的特殊字符集,就像下面这样:

    NSString *hString = [aString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"!*'();:@&=+ $,./?%#[]"]];
    

    上面这个方法一般的情况可以覆盖到,字符集可以根据自己实际应用情况编写。

    1. 方法三:
    NSString *hString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)subUrl, NULL, (CFStringRef)@"!*'();:@&=+ $,./?%#[]", kCFStringEncodingUTF8));
    

    这个方法就比较简单粗暴了,给定的字符集和汉字都会 encode。
    比如 (http://www.baidu.com?a=b&c=d&e=百度)encode 后是 http%3a%2f%2fwww.baidu.com%3fa%3db%26c%3dd%26e%3d%e7%99%be%e5%ba%a6 这样的。但是同样在 iOS 9 之后弃用。

    二. 解决了嵌套 URL 的问题,就是解析 URL 了。

    比如自己规定的 URL 是这样:

    appName://com.appName?a=b&c=d&e=URL // 其中的 URL 就是上面提到了 encode 之后的字符串。
    
    - (NSDictionary *)getUrlParameterWithUrl:(NSURL *)url {
        NSMutableDictionary *parm = [[NSMutableDictionary alloc]init];
        //传入url创建url组件类
        NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithString:url.absoluteString];
        //回调遍历所有参数,添加入字典
        [urlComponents.queryItems enumerateObjectsUsingBlock:^(NSURLQueryItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [parm setObject:obj.value forKey:obj.name];
        }];
        return parm;
    }
    

    这个方法的好处就是把参数解析出来以后不用对于 encode 了的参数会默认 decode,不需要自己在做任何操作。

    这样下来对于项目中使用 URL 跳转页面的需求应该都可以满足了。

    相关文章

      网友评论

        本文标题:iOS OC URL 解析参数,最终输出 NSDictionar

        本文链接:https://www.haomeiwen.com/subject/eujdfqtx.html