有没有感觉每次面试都会被问到 ,来小伙,你给我讲一下AF ,百分之八十的面试者 瞬间懵逼.再想一下如果某天 AF消失啦 ,消失啦,消失啦 怎么办,怎么办,怎么办////////////
http://www.qingpingshan.com/rjbc/ios/105767.html
http://www.w2bc.com/Article/13300
http://www.cnblogs.com/polobymulberry/p/5081049.html
http://blog.csdn.net/codywangziham01/article/details/38088017
http://doc.okbase.net/super_man_ww/archive/228130.html
http://blog.csdn.net/heapstackk/article/details/48680869
http://www.cnblogs.com/chenxianming/p/5674652.html
http://blog.sina.com.cn/s/blog_be8740510102xf4h.html
http://blog.csdn.net/wuyouyee/article/details/51066524
一,
在了解AF之前 我们来先考虑一下 如果自己去搞一个网络请求怎么搞.搞定以后再去膜拜大神么写的AFNETworking.
+(void)postByUrlPath:(NSString *)path andParams:(NSString *)params andCallBack:(CallBack)callback{
NSURL *url = [NSURL URLWithString:path];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
//multipart/form-data
//application/x-www-form-urlencoded 默认是这个 af用的也是这个格式的
[request setValue:@"application/json;chatset=utf-8" forHTTPHeaderField:@"Content-Type"];
NSData *data = [params dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = data;
[request setValue:[NSString stringWithFormat:@"%ld",data.length] forHTTPHeaderField:@"Content-Length"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
NSDictionary* jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:Nil];
NSString * str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"请求结果 ==%@ \\n$$$$ = %@",response,str);
callback(jsonData);
});
}];
//开始请求
[task resume];
}
上面是我自己写的一个post请求
1.首先创建 URL 并且通过URL 创建一个请求 request.
2.接下来创建 请求方式也就是说HTTPMethod = @"POST";
3.接下来创建 请求头[request setValue:@"application/json;chatset=utf-8" forHTTPHeaderField:@"Content-Type"];
4.由于是post请求 需要把参数设置为请求体 并且是这长度
[request setValue:@"application/json;chatset=utf-8" forHTTPHeaderField:@"Content-Type"];
NSData *data = [params dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = data;
[request setValue:[NSString stringWithFormat:@"%ld",data.length] forHTTPHeaderField:@"Content-Length"];
目前 connect 已经废弃 所以用户session
5.创建session 并且用session 和request 创建数据下载任务
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { dispatch_async(dispatch_get_main_queue(), ^{
}
其中data就是返回的数据
二, 有木有感觉很简单 那么af是用来干嘛的 不就是网络请求么 那么他必然逃不了这个过程.
接下来呢 我们先了解一下af的用法通过用法来一步一步去学习啊.
AFHTTPSessionManager *session = [AFHTTPSessionManager manager];
session.requestSerializer = [AFJSONRequestSerializer serializer];
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"start"] = @"1";
params[@"end"] = @"5";
[session POST:urlStr parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"请求成功");
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"请求成功");
}];
1.第一步创建了 一个 session管理者,并且通过管理者设置序列化为json格式的
- 创建请求参数字典 ,和URL
- 调用post方法 并且得到请求结果以block的方式返回.
对于manager 是干啥的县不解释.
我们在调用post方法时 才传入了URL params,由此我们可以猜到
post方法里面 做了哪些呢 : 创建 request 并且设置请求头 请求方式,请求体. 并且通过session 创建下载任务,将返回的nsdata 返回来.
githup 自己下载一个 af 打开我们看到
查看 manager
AFHTTPSessionManager *session = [AFHTTPSessionManager manager];
我们可以在相应的文件里面常看 创建manager的过程
可以看到 manager 最终执行的是这个步骤 并且在过程中参数都为nil 似乎看不到里面是什么有用的 ,那么紧接着 我们在看里面每个函数的意思
接下来主要理解这个方法的内容:
NSURLSessionConfiguration 通过字面理解可以知道这是为了给session 配置(http://blog.sina.com.cn/s/blog_877e9c3c0102uzox.html) 并且开启了队列线程 设置最大为1
接下来就是创建下载任务并且执行下面代码
[self addDelegateForDataTask:task uploadProgress:nil downloadProgress:nil completionHandler:nil];
从字面意思上看应该是添加代理给task
通过以上代码 将 下载任务的返回属性 复制给AFURLSessionManagerTaskDelegate 看到这里后 感觉读不下去啦 因为很多不理解的地方(据说af最牛逼和巧妙的地方 就在这里 block 和代理之间的转换 ). 那么返回来接着看
manager 创建过程已经完成.
接下来即使调用 post 创建下载任务开始下载
在这里 创建了request 和下载任务 并且反悔了 成功和失败的详情
接下来 看着一句的内容
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
可以看到 这里设置啦 请求方式 接下来用这个方法给request 进行拉相应的设置
在这里可以重新设置请求request
接下来就是是datatask啦
dataTask = [self dataTaskWithRequest:request
uploadProgress:uploadProgress
downloadProgress:downloadProgress
completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error)
第一个 红框 用request创建了 下载任务, 第二个红框 看名字addDelegate..... 以为是给datatask 添加代理,事实上 它类似与给一个model赋值,将datatask 和下载进度 以及完成结果赋值给AFURLSessionManagerTaskDelegate这个对象 接着往下看
可以看到对delegate的各个属性进行了赋值,同事还有一个红色框的函数 setDelagate
这个名字才是真正的给datatask 和delegate进行绑定
第一个红框即使将delegate和和task的标示进行绑定 一task的标示为可以 delegate为值.
第二个红框的函数看名字应该是添加通知或者是kvo之类的东西
可以看出来是注册了通知 一旦接受到task发送来的didresume名字的通知就会执行taskdidiresume 函数
可以看出来 函数里有发送了一个同名字的通知但是我知道这是什么意思
似乎读到这了 不知道该怎么办啦 这时候我们字啊看一下 一开始我们的manager 他是
可以看出来他是继承与AFURLSessionManager 那我们再去看AFURLSessionManager
可以看出来他遵守了一系列的协议
我们看一个NSURLSessionTaskDelegate的代理方法
这个代理是在已经完成下载任务的代理 有任务和错误等参数,也就是说nsurlsession 下载任务完成以后会自动调用这个任务并且将task 得到.也就是常说的,iOS原生的网络结果是通过代理返回的,而 AF=通过这个model将delegate的返回值,转换成block.接着往下看,
通过字典的task的唯一标示获取了一开始和task绑定好的得了delegate model,然后通过delegate调用了
[delegate URLSession:session task:task didCompleteWithError:error];
看到这个是不是懵逼啦,这个函数不就是本身么.怎么调用 ,我在看是啥调用的是delegate调用的 别那么自然我们去delegate里面看
可以看出来他也准守了这三个代理接下来看调用的函数
可以看出来在这里 分为有错误和无错误两种情况将结果以block的方式返回给了用户.当然里面还有一系列的结果序列化,这里就不看啦.
这是个人门前对af的一个简单的阅读思路吧,接下来有时间再具体看一下