AFNetworking

AFHTTPRequestSerializer 請求序列化

初始化,大概干了這么些事情

  • Accept-Language :前五種語言
  • User-Agent :項目名稱琼娘?:bundleID 版本號 model ios 系統(tǒng)號 scale
  • 監(jiān)聽暴漏在外部的六個屬性
 self.stringEncoding = NSUTF8StringEncoding;
    self.mutableHTTPRequestHeaders = [NSMutableDictionary dictionary];
    self.requestHeaderModificationQueue = dispatch_queue_create("requestHeaderModificationQueue", DISPATCH_QUEUE_CONCURRENT);
    NSMutableArray *acceptLanguagesComponents = [NSMutableArray array];
    ///獲取前五中語言
    [[NSLocale preferredLanguages] enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        float q = 1.0f - (idx *0.1f);
        [acceptLanguagesComponents addObject:[NSString stringWithFormat:@"%@;q=%0.1g",obj,q]];
        *stop = q<=0.5f;
    }];
    ///設(shè)置前五種語言
    [self setValue:[acceptLanguagesComponents componentsJoinedByString:@", "] forHTTPHeaderField:@"Accept-Language"];
    NSString *userAgent = nil;
#if TARGET_OS_IOS
    ///ebooksystem       /4.0.0 (iPhone; iOS 13.3; Scale/2.00) ios.zaxue.zaxue_ios
    ///項目名稱逢并?:bundleID 版本號   model   ios 系統(tǒng)號 scale
    userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]];
#elif TARGET_OS_WATCH
    // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43
    userAgent = [NSString stringWithFormat:@"%@/%@ (%@; watchOS %@; Scale/%0.2f)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[WKInterfaceDevice currentDevice] model], [[WKInterfaceDevice currentDevice] systemVersion], [[WKInterfaceDevice currentDevice] screenScale]];
#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
    userAgent = [NSString stringWithFormat:@"%@/%@ (Mac OS X %@)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]];
#endif
    if (userAgent) {
        if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) {
            NSMutableString *mutableUserAgent = [userAgent mutableCopy];
            if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@"Any-Latin; Latin-ASCII; [:^ASCII:] Remove", false)) {
                userAgent = mutableUserAgent;
            }
        }
        [self setValue:userAgent forHTTPHeaderField:@"User-Agent"];
    }
    self.HTTPMethodsEncodingParametersInURI = [NSSet setWithObjects:@"GET",@"HEAD",@"DELETE",nil];
    self.mutableObservedChangedKeyPaths = [NSMutableSet set];
    ///監(jiān)聽六個屬性
    for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) {
        if ([self respondsToSelector:NSSelectorFromString(keyPath)]) {
            [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:AFHTTPRequestSerializerObserverContext];
        }
    }

requestWithMethod

數(shù)據(jù)放在contentType中标捺,直接用body上傳

 - (NSMutableURLRequest *)requestWithMethod:(NSString *)method
 URLString:(NSString *)URLString
parameters:(id)parameters error:(NSError *__autoreleasing *)error

生成request的基本方法

- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
                               withParameters:(id)parameters
                                        error:(NSError *__autoreleasing *)error

multipart 流傳輸 用于大文件

Content-Type:multipart/form-data;boundary=

- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
                URLString:(NSString *)URLString
               parameters:(NSDictionary *)parameters
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
                                                  error:(NSError *__autoreleasing *)error { NSParameterAssert(method);
    NSParameterAssert(![method isEqualToString:@"GET"] && ![method isEqualToString:@"HEAD"]);
    NSMutableURLRequest *mutableRequest = [self requestWithMethod:method URLString:URLString parameters:nil error:error];
    
    __block AFStreamingMultipartFormData *formData = [[AFStreamingMultipartFormData alloc] initWithURLRequest:mutableRequest stringEncoding:NSUTF8StringEncoding];
//將傳入字典轉(zhuǎn)為AFQueryStringPair
    if (parameters) {
        for (AFQueryStringPair *pair in AFQueryStringPairsFromDictionary(parameters)) {
            NSData *data = nil;
            if ([pair.value isKindOfClass:[NSData class]]) {
                data = pair.value;
            } else if ([pair.value isEqual:[NSNull null]]) {
                data = [NSData data];
            } else {
                data = [[pair.value description]dataUsingEncoding:self.stringEncoding];
            }
///拼接到data中
if (data) {
                [formData appendPartWithFormData:data name:[pair.field description]];
            }
        }
    }
    if (block) {
        block(formData);
    }
    ///返回最終拼好流和body的 request
    return [formData requestByFinalizingMultipartFormData];
}

來進一步分析里面干了些什么

  1. 先根據(jù)requestWithMethod:method生成一個request
 NSMutableURLRequest *mutableRequest = [self requestWithMethod:method URLString:URLString parameters:nil error:error];
 __block AFStreamingMultipartFormData *formData = [[AFStreamingMultipartFormData alloc] initWithURLRequest:mutableRequest stringEncoding:NSUTF8StringEncoding];

AFStreamingMultipartFormData

AFStreamingMultipartFormData干了些什么呢吞滞?

  1. 核心方法是這個辱揭,設(shè)置BodyStream ,其中 self.boundary 和 bodyStream是其兩個屬性背伴,返回設(shè)置bodyStream 的 request
- (NSMutableURLRequest *)requestByFinalizingMultipartFormData

appendPartWithFileURL 是誰調(diào)用呢沸毁?

  1. 遵守 AFMultipartFormData 的代理方 外部調(diào)用 appendPartWithFileData 方法傳入Data數(shù)據(jù)并將數(shù)據(jù)轉(zhuǎn)為AFHTTPBodyPart 模型

然后appendHTTPBodyPart 將body 加到 AFMultipartBodyStream 的 HTTPBodyParts body數(shù)組中

AFMultipartBodyStream

用于存放AFHTTPBodyPart的數(shù)組
@property (readwrite, nonatomic, strong) NSMutableArray *HTTPBodyParts;

外部暴漏的方法

初始化stream
- (instancetype)initWithStringEncoding:(NSStringEncoding)encoding;
///HTTPBodyParts的第一個元素設(shè)置開始屬性為YES,把最后一個元素設(shè)置結(jié)束屬性為YES  AFStreamingMultipartFormData返回Request時 和打開流 時 會調(diào)用
- (void)setInitialAndFinalBoundaries;
/// HTTPBodyParts 添加 HTTPBodyParts
- (void)appendHTTPBodyPart:(AFHTTPBodyPart *)bodyPart;
///重寫了NSInputStream的 讀取拼接數(shù)據(jù)
- (NSInteger)read:(uint8_t *)buffer
        maxLength:(NSUInteger)length
///拼接下一段body

AFHTTPBodyPart

外部暴漏方法

///轉(zhuǎn)移到下一個階段
- (BOOL)transitionToNextPhase;
///模型拼接Data數(shù)據(jù)
- (NSInteger)readData:(NSData *)data
           intoBuffer:(uint8_t *)buffer
            maxLength:(NSUInteger)length;
- (BOOL)transitionToNextPhase
 對Multipart請求體各部分(初始邊界傻寂、頭部息尺、內(nèi)容數(shù)據(jù)實體、結(jié)束邊界)做拼接和讀取的封裝
AFHTTPRequestSerializer邏輯圖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疾掰,一起剝皮案震驚了整個濱河市搂誉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌静檬,老刑警劉巖炭懊,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浪汪,死亡現(xiàn)場離奇詭異,居然都是意外死亡凛虽,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門广恢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凯旋,“玉大人,你說我怎么就攤上這事钉迷≈练牵” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵糠聪,是天一觀的道長荒椭。 經(jīng)常有香客問我,道長舰蟆,這世上最難降的妖魔是什么趣惠? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮身害,結(jié)果婚禮上味悄,老公的妹妹穿的比我還像新娘。我一直安慰自己塌鸯,他們只是感情好侍瑟,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著丙猬,像睡著了一般涨颜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上茧球,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天庭瑰,我揣著相機與錄音,去河邊找鬼袜腥。 笑死见擦,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的羹令。 我是一名探鬼主播鲤屡,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼福侈!你這毒婦竟也來了酒来?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤肪凛,失蹤者是張志新(化名)和其女友劉穎堰汉,沒想到半個月后辽社,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡翘鸭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年滴铅,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片就乓。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡汉匙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出生蚁,到底是詐尸還是另有隱情噩翠,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布邦投,位于F島的核電站伤锚,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏志衣。R本人自食惡果不足惜屯援,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蠢涝。 院中可真熱鬧旦棉,春花似錦养距、人聲如沸搔弄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惯吕。三九已至惕它,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間废登,已是汗流浹背淹魄。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留堡距,地道東北人甲锡。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像羽戒,于是被迫代替她去往敵國和親缤沦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容