美文网首页鲸落消零派iOS沉淀
stringByAddingPercentEncodingWit

stringByAddingPercentEncodingWit

作者: 果哥爸 | 来源:发表于2021-07-17 12:43 被阅读0次

    今天做域名加签校验遇到一个问题,就是请求地址编码问题,url地址如下:
    NSString *tmpUrlString = @"https://www.baidu.com/devtest-news/app/news/keyword/recommend?keyword=土甲,巴利基斯,萨姆桑斯堡&test=你好*2";,这里需要对参数里面的中文",","*"等进行转义。

    由于之前对NSCharacterSetstringByAddingPercentEncodingWithAllowedCharacters方法没有细致了解,因此这里做了下笔记.

    DEMO详见

    一. NSCharacterSet

    1.API解释

    /** 001 根据一个给定的字符串获取一个NSCharacterSet对象 */
    + (NSCharacterSet *)characterSetWithCharactersInString:(NSString *)aString;
    
    /** 002 相反字符串限制 【具体见接下的例子】 */
    @property (readonly, copy) NSCharacterSet *invertedSet;
    
    

    举个例子:

        // 0 - 9字符集
        NSString *numberStr = @"0123456789";
        NSCharacterSet *numberSet = [NSCharacterSet characterSetWithCharactersInString:numberStr];
        NSString *str = @"7chinafjf78990love";
        // 过滤str字符串里面的0-9内的字符
        NSLog(@"numberSet----%@",[[str componentsSeparatedByCharactersInSet:numberSet] componentsJoinedByString:@""]);
        
        // 保留str字符串里面的0-9内的字符
        NSCharacterSet *invertedSet = [[NSCharacterSet characterSetWithCharactersInString:numberStr] invertedSet];
        NSLog(@"invertedSet----%@",[[str componentsSeparatedByCharactersInSet:invertedSet] componentsJoinedByString:@""]);
    

    输出日志:

    2021-01-02 16:08:02.239695+0800 FJFBlogDemo[13342:636161] numberSet----chinafjflove
    2021-01-02 16:08:02.239784+0800 FJFBlogDemo[13342:636161] invertedSet----778990
    

    2.常用快捷方法合集

    [NSCharacterSet alphanumericCharacterSet];          //所有数字和字母(大小写)  
    [NSCharacterSet decimalDigitCharacterSet];          //0-9的数字  
    [NSCharacterSet letterCharacterSet];                //所有字母  
    [NSCharacterSet lowercaseLetterCharacterSet];       //小写字母  
    [NSCharacterSet uppercaseLetterCharacterSet];       //大写字母  
    [NSCharacterSet punctuationCharacterSet];           //标点符号  
    [NSCharacterSet whitespaceAndNewlineCharacterSet];  //空格和换行符  
    [NSCharacterSet whitespaceCharacterSet];            //空格  
    

    stringByAddingPercentEncodingWithAllowedCharacters方法

    所以这两个函数可以解释如下:

    // 对除了这些特殊字符(!$&'()*+-./:;=?@_~%#[])以外的所有字符进行编码
    + (NSString *)fjf_encodeSpecialCharacterWithUrlString:(NSString *)urlString {
        return [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet   characterSetWithCharactersInString:@"!$&'()*+-./:;=?@_~%#[]"]];
    }
    
    // 只编码 中文 字符(对所有字符都不进行编码,除了中文)
    + (NSString *)fjf_encodeChineseCharacterWithUrlString:(NSString *)urlString {
        return  [urlString stringByAddingPercentEncodingWithAllowedCharacters:[[NSCharacterSet characterSetWithCharactersInString:@""] invertedSet]];
    }
    

    对url统一处理方法

    + (NSString *)fjf_encodeUrlStringWithString:(NSString *)urlString {
    
       //先截取问号
       NSArray *allElements = [urlString componentsSeparatedByString:@"?"];
       NSMutableDictionary *params = [NSMutableDictionary dictionary];//待set的参数字典
       if (allElements.count == 2) {
          //有参数或者?后面为空
           NSString *myUrlString = allElements[0];
           NSString *paramsString = allElements[1];
    
           //获取参数对
           NSArray *paramsArray = [paramsString componentsSeparatedByString:@"&"];
           if (paramsArray.count >= 2) {
              for (NSInteger i = 0; i < paramsArray.count; i++) {
                 NSString *singleParamString = paramsArray[i];
                 NSArray *singleParamSet = [singleParamString componentsSeparatedByString:@"="];
                 if (singleParamSet.count == 2) {
                     NSString *key = singleParamSet[0];
                     NSString *value = singleParamSet[1];
                     if (key.length > 0 || value.length > 0) {
                        [params setObject:[self fjf_percentEscapedStringWithString:value]  forKey:[self fjf_percentEscapedStringWithString:key]];
                     }
                 }
              }
           } else if (paramsArray.count == 1) {
              //无 &。url只有?后一个参数
              NSString *singleParamString = paramsArray[0];
              NSArray *singleParamSet = [singleParamString componentsSeparatedByString:@"="];
              if (singleParamSet.count == 2) {
                 NSString *key = singleParamSet[0];
                 NSString *value = singleParamSet[1];
                 if (key.length || value.length) {
                     [params setObject:[self fjf_percentEscapedStringWithString:value] forKey:[self fjf_percentEscapedStringWithString:key]];
                 }
              }
           }
          //整合url及参数
           NSMutableString *tmpMstring = [NSMutableString stringWithString:myUrlString];
           [params enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
               [tmpMstring appendString:[self fjf_urlSymbolWithUrl:tmpMstring]];
               [tmpMstring appendString:[NSString stringWithFormat:@"%@=%@", key, obj]];
           }];
           return tmpMstring;
       }
        return urlString;
    }
    
    
    + (NSString *)fjf_percentEscapedStringWithString:(NSString *)string {
        NSString * kAFCharactersGeneralDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4
        NSString * kAFCharactersSubDelimitersToEncode = @"!$&'()*+,;=";
    
        NSMutableCharacterSet * allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
        [allowedCharacterSet removeCharactersInString:[kAFCharactersGeneralDelimitersToEncode stringByAppendingString:kAFCharactersSubDelimitersToEncode]];
    
        // FIXME: https://github.com/AFNetworking/AFNetworking/pull/3028
        // return [string stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
    
        static NSUInteger const batchSize = 50;
    
        NSUInteger index = 0;
        NSMutableString *escaped = @"".mutableCopy;
    
        while (index < string.length) {
            NSUInteger length = MIN(string.length - index, batchSize);
            NSRange range = NSMakeRange(index, length);
    
            // To avoid breaking up character sequences such as 👴🏻👮🏽
            range = [string rangeOfComposedCharacterSequencesForRange:range];
    
            NSString *substring = [string substringWithRange:range];
            NSString *encoded = [substring stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
            [escaped appendString:encoded];
    
            index += range.length;
        }
        return escaped;
    }
    
    
    // 请求地址 拼接 符号
    + (NSString *)fjf_urlSymbolWithUrl:(NSString *)url {
        NSString *symbolString = @"?";
        if ([url containsString:@"?"]) {
            symbolString = @"&";
        }
        return symbolString;
    }
    

    相关文章

      网友评论

        本文标题:stringByAddingPercentEncodingWit

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