Skip to content

Instantly share code, notes, and snippets.

@jkyin
Created October 10, 2015 10:01
Show Gist options
  • Save jkyin/997ac6b359b50b88eefe to your computer and use it in GitHub Desktop.
Save jkyin/997ac6b359b50b88eefe to your computer and use it in GitHub Desktop.
AFNetworking POST 大量中文字符崩溃
/**
Returns a percent-escaped string following RFC 3986 for a query string key or value.
RFC 3986 states that the following characters are "reserved" characters.
- General Delimiters: ":", "#", "[", "]", "@", "?", "/"
- Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow
query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/"
should be percent-escaped in the query string.
- parameter string: The string to be percent-escaped.
- returns: The percent-escaped string.
*/
static NSString * AFPercentEscapedStringFromString(NSString *string) {
static NSString * const kAFCharactersGeneralDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4
static NSString * const kAFCharactersSubDelimitersToEncode = @"!$&'()*+,;=";
NSMutableCharacterSet * allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
[allowedCharacterSet removeCharactersInString:[kAFCharactersGeneralDelimitersToEncode stringByAppendingString:kAFCharactersSubDelimitersToEncode]];
//==========================================================================================================
//
// Batching is required for escaping due to an internal bug in iOS 8.1 and 8.2. Encoding more than a few
// hundred Chinense characters causes various malloc error crashes. To avoid this issue until iOS 8 is no
// longer supported, batching MUST be used for encoding. This introduces roughly a 20% overhead. For more
// info, please refer to:
//
// - https://github.com/Alamofire/Alamofire/issues/206
//
//==========================================================================================================
NSString *escaped = @"";
if (([[UIDevice currentDevice].systemVersion floatValue] >= 8.3)) {
escaped = [string stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet] ? [string stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet] : string;
} else {
NSUInteger batchSize = 50;
NSUInteger endIndex = string.length;
NSUInteger index = 0;
while (index != endIndex) {
NSUInteger startIndex = index;
NSRange range = NSMakeRange(startIndex, batchSize);
NSInteger delta = NSMaxRange(range) - endIndex;
if (delta > 0) {
batchSize -= delta;
range = NSMakeRange(startIndex, batchSize);
}
NSString *substring = [string substringWithRange:range];
NSString *escapedSubstring = [substring stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet] ? [substring stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet] : substring;
escaped = [escaped stringByAppendingString:escapedSubstring];
index += batchSize;
}
}
return escaped;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment