美文网首页
小技巧 - NSURL遇上不规范的URLString

小技巧 - NSURL遇上不规范的URLString

作者: Jacob_LJ | 来源:发表于2018-07-10 21:48 被阅读45次
小技巧

1 问题描述

  • NSURL通过方法- (instancetype)initWithString:(NSString *)URLString实例化时返回nil

例如下面的UrlString:
http://image.myutopa.com/FrPk4GvZZRp7LqbxVNYPNnboLy-F?imageView2/1/w/80/h/80/q/75|imageslim&e=1562228012&token=WNtUYaMiCdpTDzanlE03SjKXLinbmTzkLGXEBYC_:6dc5rTdvO95Ed4yO8mUGw6Dia8w=
使用NSURL编码时返回的就是nil

2 问题产生场景

  • 该图片是存放在七牛中的,后台获取地址时给图片添加了裁剪的样式,最后返回到前端的图片地址如上。
  • 而问题地址则是用于分享功能,项目中使用MOB的ShareSDK第三方分享组件
  • 执行分享时,会调用如下代码
    NSMutableDictionary *shareParams = [NSMutableDictionary dictionary];
    [shareParams SSDKSetupShareParamsByText:content
                                     images:Images
                                        url:[NSURL URLWithString:urlStr]
                                      title:title
                                       type:SSDKContentTypeAuto]; //qq如果没有title和content只有默认图片和URL时,执行的是分享图片。最少有Title时候分享类型为URL网页分享
    
    //进行分享
    [ShareSDK share:[self switchGTSharePlatformType:sharePlatformType] //传入分享的平台类型
         parameters:shareParams
     onStateChanged:^(SSDKResponseState state, NSDictionary *userData, SSDKContentEntity *contentEntity, NSError *error) {
         // 回调处理....
         NSLog(@"\n\n分享回调 - %ld, %@, %@, %@\n\n",state, userData, contentEntity, error);
         }
     }];

其中,images 这个字符串数组就是存放分享图片的地址的。

  • 当方法SSDKSetupShareParamsByText:images:url:title:type:处理图片数组时,会将字符串地址转为 NSURL 对象。
  • 而因为地址是有问题的,所以 images 处理后得到的是空的 NSURL 对象数组,导致分享失败

3 问题定位(为什么地址在浏览器中可以获取到,使用NSURL 实例方法则返回 nil?)

3.1 参考 API 文档描述

initWithString: - NSURL | Apple Developer Documentation

NSURL
上图重点如下:
  1. URLString 参数不能为空
  2. URLString 参数的值必须满足 RFC 2396 协议中定义的URL格式,可参考RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax

3.2 问题原因

综上,URLString中应除了下述字符外的其他字符都需要进行百分号转义(percent-escaped)

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=

对比问题URLString,发现地址中有 |符号不符合要求

| 符号 导致 URLString 不符合要求

4 解决方法

  • 生产环境上,优先让后台不返回裁剪样式的 URLString,毕竟分享后都会对大图进行裁剪
  • 后续使用 hardcode 对该类型地址进行 percent-escaped 百分号编码,杜绝后患
[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  • 就本次业务逻辑hardcode
//使用ShareSDK分享
+ (void)sharePlatformType:(GTSharePlatformType)sharePlatformType title:(NSString *)title content:(NSString *)content urlStr:(NSString *)urlStr images:(NSArray *)images onStateChanged:(GTShareStateChangedHandler)stateChangedHandler {
    //1、创建分享参数
    
    // 对复杂的string url地址进行编码
    NSMutableArray *freshImages = [NSMutableArray array];
    [images enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([obj isKindOfClass:[NSString class]]) {
            NSString *obj1 = (NSString *)obj;
            NSString *fixedStr = [obj1 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
            [freshImages addObject:fixedStr];
        }
    }];
    
    if (!freshImages.count) {
        freshImages = [NSMutableArray arrayWithArray:@[[UIImage imageNamed:@"login_icon_logo"]]];
    }
    
    NSMutableDictionary *shareParams = [NSMutableDictionary dictionary];
    [shareParams SSDKSetupShareParamsByText:content
                                     images:freshImages
                                        url:[NSURL URLWithString:urlStr]
                                      title:title
                                       type:SSDKContentTypeAuto]; //qq如果没有title和content只有默认图片和URL时,执行的是分享图片。最少有Title时候分享类型为URL网页分享
    
    //进行分享
    [ShareSDK share:[self switchGTSharePlatformType:sharePlatformType] //传入分享的平台类型
         parameters:shareParams
     onStateChanged:^(SSDKResponseState state, NSDictionary *userData, SSDKContentEntity *contentEntity, NSError *error) {
         // 回调处理....
         NSLog(@"\n\n分享回调 - %ld, %@, %@, %@\n\n",state, userData, contentEntity, error);
         if (stateChangedHandler) {
             GTShareResponseState gtResponseState = [self switchSSDKResponseState:state];
             stateChangedHandler(gtResponseState, userData, contentEntity, error);
         }
         
     }];
}

5 参考

相关文章

网友评论

      本文标题:小技巧 - NSURL遇上不规范的URLString

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