Skip to content

Commit d52a857

Browse files
committed
AFN-multi-part/form-data代码分析
1 parent 08ee32f commit d52a857

File tree

1 file changed

+40
-8
lines changed

1 file changed

+40
-8
lines changed

AFN3.x阅读/AFN3.x阅读/AFNetworking3.x/AFNetworking/AFURLRequestSerialization.m

+40-8
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ - (NSString *)URLEncodedStringValue {
188188
field: @"nums", value: @"2",
189189
]
190190
->
191-
name=bang&phone[mobile]=xx&phone[home]=xx&families[]=father&families[]=mother&nums=1&num=2
191+
name=bang&phone[mobile]=xx&phone[home]=xx&families[]=father&families[]=mother&nums=1&nums=2
192192
193193
194194
*/
@@ -293,7 +293,7 @@ - (instancetype)init {
293293
// self.mutableObservedChangedKeyPaths其实就是我们自己设置的request属性值的集合。
294294
self.mutableObservedChangedKeyPaths = [NSMutableSet set];
295295
// 给自己这些方法添加观察者为自己,就是request的各种属性,set方法
296-
// KVO触发的方法在 560行
296+
// KVO触发的方法在 605行
297297
for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) {
298298
if ([self respondsToSelector:NSSelectorFromString(keyPath)]) {
299299
[self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:AFHTTPRequestSerializerObserverContext];
@@ -428,7 +428,7 @@ - (NSMutableURLRequest *)requestWithMethod:(NSString *)method
428428
// AFHTTPRequestSerializerObservedKeyPaths() 就是封装了一些属性的名字,这些都是NSUrlRequest的属性
429429
for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) {
430430
// 如果自己观察到的发生变化的属性在这些方法里
431-
// mutableObservedChangedKeyPaths 在-init方法对这个集合进行了初始化,并且对当前类的和NSUrlRequest相关的那些属性添加了KVO监听 在253行
431+
// mutableObservedChangedKeyPaths 在-init方法对这个集合进行了初始化,并且对当前类的和NSUrlRequest相关的那些属性添加了KVO监听 在294行
432432
if ([self.mutableObservedChangedKeyPaths containsObject:keyPath]) {
433433
// 用KVC的方式,把属性值都设置到我们请求的request中去。
434434
[mutableRequest setValue:[self valueForKeyPath:keyPath] forKey:keyPath];
@@ -448,33 +448,59 @@ - (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
448448
{
449449
NSParameterAssert(method);
450450
NSParameterAssert(![method isEqualToString:@"GET"] && ![method isEqualToString:@"HEAD"]);
451-
// 生成request
451+
// 生成request 注意:此时传入的参数是nil
452452
NSMutableURLRequest *mutableRequest = [self requestWithMethod:method URLString:URLString parameters:nil error:error];
453453

454-
//
454+
// 初始化AFStreamingMultipartFormData 构建bodyStream
455455
__block AFStreamingMultipartFormData *formData = [[AFStreamingMultipartFormData alloc] initWithURLRequest:mutableRequest stringEncoding:NSUTF8StringEncoding];
456456

457457
if (parameters) {
458+
// 构建一个AFQueryStringPair,其中field为"Filename",value为"文件名"
459+
460+
/** parameters
461+
@{
462+
@"name" : @"bang",
463+
@"phone": @{@"mobile": @"xx", @"home": @"xx"},
464+
@"families": @[@"father", @"mother"],
465+
@"nums": [NSSet setWithObjects:@"1", @"2", nil]
466+
}
467+
-> AFQueryStringPair
468+
@[
469+
field: @"name", value: @"bang",
470+
field: @"phone[mobile]", value: @"xx",
471+
field: @"phone[home]", value: @"xx",
472+
field: @"families[]", value: @"father",
473+
field: @"families[]", value: @"mother",
474+
field: @"nums", value: @"1",
475+
field: @"nums", value: @"2",
476+
]
477+
*/
458478
for (AFQueryStringPair *pair in AFQueryStringPairsFromDictionary(parameters)) {
459479
NSData *data = nil;
460480
if ([pair.value isKindOfClass:[NSData class]]) {
461481
data = pair.value;
462482
} else if ([pair.value isEqual:[NSNull null]]) {
463483
data = [NSData data];
464484
} else {
485+
// 根据对应value的类型,构建出一个NSData变量 把string类型转换为NSData类型数据
465486
data = [[pair.value description] dataUsingEncoding:self.stringEncoding];
466487
}
467488

468489
if (data) {
490+
// 根据data和name构建Request的header和body
491+
// AFStreamingMultipartFormData的方法-拼接request一般参数
469492
[formData appendPartWithFormData:data name:[pair.field description]];
470493
}
471494
}
472495
}
473496

474497
if (block) { // 回调用户block
498+
// 往formData中添加数据
475499
block(formData);
476500
}
477501
// 生成最终的request
502+
// 设置一下MultipartRequest的bodyStream或者其特有的content-type
503+
// 将所有请求参数拼接好
478504
return [formData requestByFinalizingMultipartFormData];
479505
}
480506

@@ -590,7 +616,7 @@ - (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
590616
[mutableRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
591617
}
592618
// NSData *HTTPBody
593-
// 设置请求体 编码后的NSData (NSUTF8StringEncoding默认编码方式)
619+
// 设置请求体 一段query串编码后的NSData (NSUTF8StringEncoding默认编码方式)
594620
[mutableRequest setHTTPBody:[query dataUsingEncoding:self.stringEncoding]];
595621
}
596622

@@ -837,6 +863,7 @@ - (void)appendPartWithInputStream:(NSInputStream *)inputStream
837863
[self.bodyStream appendHTTPBodyPart:bodyPart];
838864
}
839865

866+
// form-data拼接文件参数
840867
- (void)appendPartWithFileData:(NSData *)data
841868
name:(NSString *)name
842869
fileName:(NSString *)fileName
@@ -853,6 +880,7 @@ - (void)appendPartWithFileData:(NSData *)data
853880
[self appendPartWithHeaders:mutableHeaders body:data];
854881
}
855882

883+
// form-data拼接一般请求参数
856884
- (void)appendPartWithFormData:(NSData *)data
857885
name:(NSString *)name
858886
{
@@ -868,14 +896,15 @@ - (void)appendPartWithHeaders:(NSDictionary *)headers
868896
body:(NSData *)body
869897
{
870898
NSParameterAssert(body);
871-
899+
// 表单必要的数据组装
872900
AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init];
873901
bodyPart.stringEncoding = self.stringEncoding;
874902
bodyPart.headers = headers;
875903
bodyPart.boundary = self.boundary;
876904
bodyPart.bodyContentLength = [body length];
877905
bodyPart.body = body;
878-
906+
907+
// 将需要的bodyPart模块保存到数组中
879908
[self.bodyStream appendHTTPBodyPart:bodyPart];
880909
}
881910

@@ -892,9 +921,12 @@ - (NSMutableURLRequest *)requestByFinalizingMultipartFormData {
892921
}
893922

894923
// Reset the initial and final boundaries to ensure correct Content-Length
924+
// 重设边界 保证正确的Content-Length
895925
[self.bodyStream setInitialAndFinalBoundaries];
926+
// 设置HTTPBodyStream
896927
[self.request setHTTPBodyStream:self.bodyStream];
897928

929+
// 设置请求头
898930
[self.request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", self.boundary] forHTTPHeaderField:@"Content-Type"];
899931
[self.request setValue:[NSString stringWithFormat:@"%llu", [self.bodyStream contentLength]] forHTTPHeaderField:@"Content-Length"];
900932

0 commit comments

Comments
 (0)