iOS 的URL编码

stringByAddingPercentEscapesUsingEncoding:

用这个方法进行转义,每个汉字将转成相应的unicode编码对应的3个%形式,还会转义一些特殊字符(比如空格会变成%20,#会变成%23,[会变成%5B等)。该方法现在已经被废弃,官方建议使用stringByAddingPercentEncodingWithAllowedCharacters:(下面会进行介绍)。

stringByAddingPercentEscapesUsingEncoding:的用法:

NSString *queryWord = @"[q q&";

NSString *escapedString = [queryWord stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

NSLog(@"%@", escapedString);

打印结果为:%5Bq%20q&

可以发现空格和[都被转义了,但是&没有。

- (NSString *)stringByAddingPercentEncodingWithAllowedCharacters:(NSCharacterSet *)allowedCharacters的使用

这个方法是iOS7.0开始有的,这个方法会对字符串进行更彻底的转义,需要传递一个参数:这个参数是一个字符集(NSCharacterSet ),这个字符集的作用是在进行转义过程中,不会对这个字符集中包含的字符进行转义,使这个字符集中的字符保持原样。

NSCharacterSet的介绍

NSCharacterSet类似一个字符串处理工具,除了在URL转义中用到还可以用它来处理字符串。

NSCharacterSet的常用API:

/** 根据一个给定的字符串获取一个NSCharacterSet对象 */

+ (NSCharacterSet*)characterSetWithCharactersInString:(NSString*)aString;

/** 相反字符串限制  */

@property(readonly,copy)NSCharacterSet* invertedSet;

/** 常用快捷方法集合 (常用的,已满足大多数需求) */

@property (readonly, class, copy) NSCharacterSet *whitespaceCharacterSet //空格

@property (readonly, class, copy) NSCharacterSet *whitespaceAndNewlineCharacterSet //空格和换行符

@property (readonly, class, copy) NSCharacterSet *decimalDigitCharacterSet //0-9的数字

@property (readonly, class, copy) NSCharacterSet *letterCharacterSet //所有字母 + lowercaseLetterCharacterSet//小写字母

@property (readonly, class, copy) NSCharacterSet *uppercaseLetterCharacterSet //大写字母

@property (readonly, class, copy) NSCharacterSet *alphanumericCharacterSet //所有数字和字母(大小写不分)

@property (readonly, class, copy) NSCharacterSet *punctuationCharacterSet //标点符号

@property (readonly, class, copy) NSCharacterSet *newlineCharacterSet //换行

@property (class, readonly, copy) NSCharacterSet *URLQueryAllowedCharacterSet//URL中允许的字符的字符集。

上述属性使用了class修饰,直接用[NSCharacterSet whitespaceCharacterSet]就能获取空格字符串集

例子一:使用NSCharacterSet转义字符

转义除了空格之外的所有字符

NSString *queryWord = @"[q q&";

NSCharacterSet *set = [NSCharacterSet whitespaceCharacterSet];

NSString *escapedString = [queryWord stringByAddingPercentEncodingWithAllowedCharacters:set];

NSLog(@"%@", escapedString);

打印结果为:%5B%71 %71%26可以发现除了空格之外的所有参数都被转义,字母也被转义了(这只是展示用法,实际参数转义的时候还是要视情况定)。

例子二:转义除了空格和字母之外的字符

NSString *queryWord = @"[q q&";

NSMutableCharacterSet *letterSet = [NSMutableCharacterSet letterCharacterSet];

[letterSet addCharactersInString:@" "];

NSString *escapedString = [queryWord stringByAddingPercentEncodingWithAllowedCharacters:letterSet];

NSLog(@"%@", escapedString);

打印结果为:%5Bq q%26

例子三:使用NSCharacterSet处理字符串

需求:把字符串中的数字和字符串分别截取出来,分成两个字符串

NSString *originalStr = @"qssq21233fd23j49fr034";

NSCharacterSet *numCharacterSet = [NSCharacterSet decimalDigitCharacterSet];//创建数字的字符串集

NSArray *letterArray = [originalStr componentsSeparatedByCharactersInSet:numCharacterSet];//把不在字符集中的字符分离成数组

NSString *letterStr = [letterArray componentsJoinedByString:@""];//把字符数组以空字符串拼成一个字符串

NSArray *numArray = [originalStr componentsSeparatedByCharactersInSet:[numCharacterSet invertedSet]];

NSString *numStr = [numArray componentsJoinedByString:@""];

NSLog(@"字母字符串:%@", letterStr);

NSLog(@"数字字符串:%@", numStr);

打印结果:字母字符串:qssqfdjfr

                   数字字符串:212332349034

AFNetworking中转义字符串的源码解析

NSString * AFPercentEscapedStringFromString(NSString *string) {

    //定义两个字符串,这两个字符串中的字符还是需要转义的

    static NSString * const kAFCharactersGeneralDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4

    static NSString * const kAFCharactersSubDelimitersToEncode = @"!$&'()*+,;=";

    //获取URL中允许的字符的字符集。

    NSMutableCharacterSet * allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];

    //在URL中允许的字符的字符集中移除上面需要转义的字符集

    [allowedCharacterSet removeCharactersInString:[kAFCharactersGeneralDelimitersToEncode stringByAppendingString:kAFCharactersSubDelimitersToEncode]];

// FIXME: https://github.com/AFNetworking/AFNetworking/pull/3028

    // return [string stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];

    //以50个字符为单位截取字符串

    static NSUInteger const batchSize = 50;

    NSUInteger index = 0;

    NSMutableString *escaped = @"".mutableCopy;

    //最后一次字符的位置比字符串的长度小()即未转义完时继续转义

    while (index < string.length) {

        //获取剩余字符串长度和截取单位50的最小值,剩余长度大于50,先截取50个字符

        NSUInteger length = MIN(string.length - index, batchSize);

        NSRange range = NSMakeRange(index, length);

         //像表情(),一个表情有多个字符,这个方法是为了防止表情或者汉字被截断

        range = [string rangeOfComposedCharacterSequencesForRange:range];

        NSString *substring = [string substringWithRange:range];

        //转义allowedCharacterSet字符集外的字符

        NSString *encoded = [substring stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];

        //把转义后的字符拼接到准备的可变字符串

        [escaped appendString:encoded];

        index += range.length;

    }

return escaped;

}

你可能感兴趣的:(iOS 的URL编码)