AFNetworking源码拾遗

一句话简介:最著名的OC开源网络库。

Github: 传送门

PS: 本拾遗系列文章只专注于代码以及工程层面知识点拾遗,架构层面作者文章已经进行了详细的讲解。

1. @import和modulemap

首先OC中的@import以及Swift中的import其实都是基于modulemap实现的。

2. 各种标记

  • __unused: 避免因变量声明未使用造成的警告。
  • ARC相关(如__autoreleasing)参考: iOS开发ARC内存管理技术要点
  • NS_DESIGNATED_INITIALIZER 声明了designated初始化方法后,其余初始化方法如果没有调用designated初始化会有警告提示,具体可以参考: Xcode 6 Objective-C Modernization
  • DEPRECATED_ATTRIBUTE(过期)、NS_SWIFT_NOTHROW(一些便于OC迁移Swift的标记)等

3. 宏

  • FOUNDATION_EXPORT: 对于extern的兼容性封装,根据不同的平台,转化为对应的extern形式。
  • NS_ASSUME_NONNULL_BEGIN、NS_ASSUME_NONNULL_END: 在宏范围内的变量、参数、返回值等都默认添加nonnull。

4. queryString转换的经典代码

经常被摘出来放到自己项目中使用。

/**
 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.
 */
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]];

	// 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;
}

[escaped appendString:encoded]

Leave a Comment

Your email address will not be published. Required fields are marked *