IOS网络访问之使用AFNetworking
AFNetworking是IOS上常用的第三方网络访问库,我们可以在github上下载它,同时github上有它详细的使用说明,最新的AFNetworing2.0与1.0有很大的变化,这里仅对2.0常用的使用方法进行总结
基于NSURLConnection的API
提交GET请求
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:@"http://example.com/resources.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
上面代码中responseObject代表了返回的值,当网络返回json或者xml之类的数据时,它们的本质都是字符串,我们需要通过一定操作才能 把字符串转成希望的对象,AFNetWorking通过设置AFHTTPRequestOperationManager对象的 responseSerializer属性替我们做了这些事。
如果返回的数据时json格式,那么我们设定
manager.responseSerializer = [[AFJSONResponseSerializer alloc] init],responseObject就是获得的json的根对象(NSDictionary或者NSArray)
//manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //这句也可以,很重要,去掉就容易遇到错误,暂时还未了解更加详细的原因
如果返回的是plist格式我们就用AFPropertyListResponseSerializer解析器
如果返回的是xml格式我们就用AFXMLParserResponseSerializer解析器,responseObject代表了NSXMLParser对像
如果返回的是图片,可以使用AFImageResponseSerializer
如果只是希望获得返回二进制格式,那么可以使用AFHTTPResponseSerializer
AFRequestSerializer
AFHTTPRequestOperationManager还可以通过设置requestSeializer属性设置请求的格式
有如下的请求地址与参数
NSString *URLString = @"http://example.com";
NSDictionary *parameters = @{@"foo": @"bar", @"baz": @[@1, @2, @3]};
我们使用AFHTTPRequestSerializer的GET提交方式
[[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET" URLString:URLString parameters:parameters error:nil];
GET http://example.com?foo=bar&baz[]=1&baz[]=2&baz[]=3
我们使用AFHTTPRequestSerializer的POST提交方式
[[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters];
POST http://example.com/
Content-Type: application/x-www-form-urlencoded
foo=bar&baz[]=1&baz[]=2&baz[]=3
我们使用AFJSONRequestSerializer
[[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters];
POST http://example.com/
Content-Type: application/json
{"foo": "bar", "baz": [1,2,3]}
默认提交请求的数据是二进制(AFHTTPRequestSerializer)的,返回格式是JSON(AFJSONResponseSerializer)
提交POST请求
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"foo": @"bar"};
[manager
POST:@"http://example.com/resources.json" parameters:parameters
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
|
提交POST请求时附带文件
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"foo": @"bar"};
NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"];
[manager
POST:@"http://example.com/resources.json" parameters:parameters
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:filePath name:@"image" error:nil];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"Success: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
|
也可以通过appendPartWithFileData上传NSData数据的文件
AFHTTPRequestOperation
除了使用AFHTTPRequestOperationManager访问网络外还可以通过AFHTTPRequestOperation,AFHTTPRequestOperation继承自AFURLConnectionOperation,
AFURLConnectionOperation继承自NSOperation,所以可以通过AFHTTPRequestOperation定义了一个网络请求任务,然后添加到队列中执行。
NSMutableArray *mutableOperations = [NSMutableArray array];
for (NSURL *fileURL in filesToUpload) {
NSURLRequest
*request = [[AFHTTPRequestSerializer serializer]
multipartFormRequestWithMethod:@"POST"
URLString:@"http://example.com/upload" parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:fileURL name:@"images[]" error:nil];
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[mutableOperations addObject:operation];
}
NSArray
*operations = [AFURLConnectionOperation batchOfRequestOperations:@[...]
progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger
totalNumberOfOperations) {
NSLog(@"%lu of %lu complete", numberOfFinishedOperations, totalNumberOfOperations);
} completionBlock:^(NSArray *operations) {
NSLog(@"All operations in batch complete");
}];
[[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO];
|
批量任务处理
NSMutableArray *mutableOperations = [NSMutableArray array];
for (NSURL *fileURL in filesToUpload) {
NSURLRequest
*request = [[AFHTTPRequestSerializer serializer]
multipartFormRequestWithMethod:@"POST"
URLString:@"http://example.com/upload" parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:fileURL name:@"images[]" error:nil];
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[mutableOperations addObject:operation];
}
NSArray
*operations = [AFURLConnectionOperation batchOfRequestOperations:@[...]
progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger
totalNumberOfOperations) {
NSLog(@"%lu of %lu complete", numberOfFinishedOperations, totalNumberOfOperations);
} completionBlock:^(NSArray *operations) {
NSLog(@"All operations in batch complete");
}];
[[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO];
|
上面的API是基于NSURLConnection,IOS7之后AFNetWorking还提供了基于NSURLSession的API
基于NSURLSession的API
下载任务
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:@"http://example.com/download.zip"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDownloadTask
*downloadTask = [manager downloadTaskWithRequest:request progress:nil
destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSURL
*documentsDirectoryURL = [[NSFileManager defaultManager]
URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask
appropriateForURL:nil create:NO error:nil];
return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
NSLog(@"File downloaded to: %@", filePath);
}];
[downloadTask resume];
|
文件上传任务
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:@"http://example.com/upload"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"];
NSURLSessionUploadTask
*uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath
progress:nil completionHandler:^(NSURLResponse *response, id
responseObject, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
} else {
NSLog(@"Success: %@ %@", response, responseObject);
}
}];
[uploadTask resume];
|
带进度的文件上传
NSMutableURLRequest
*request = [[AFHTTPRequestSerializer serializer]
multipartFormRequestWithMethod:@"POST"
URLString:@"http://example.com/upload" parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData
appendPartWithFileURL:[NSURL
fileURLWithPath:@"file://path/to/image.jpg"] name:@"file"
fileName:@"filename.jpg" mimeType:@"image/jpeg" error:nil];
} error:nil];
AFURLSessionManager
*manager = [[AFURLSessionManager alloc]
initWithSessionConfiguration:[NSURLSessionConfiguration
defaultSessionConfiguration]];
NSProgress *progress = nil;
NSURLSessionUploadTask
*uploadTask = [manager uploadTaskWithStreamedRequest:request
progress:&progress completionHandler:^(NSURLResponse *response, id
responseObject, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
} else {
NSLog(@"%@ %@", response, responseObject);
}
}];
[uploadTask resume];
NSURLSessionDataTask
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:@"http://example.com/upload"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDataTask
*dataTask = [manager dataTaskWithRequest:request
completionHandler:^(NSURLResponse *response, id responseObject, NSError
*error) {
if (error) {
NSLog(@"Error: %@", error);
} else {
NSLog(@"%@ %@", response, responseObject);
}
}];
[dataTask resume];
|
查看网络状态
苹果官方提供Reachablity用来查看网络状态,AFNetWorking也提供这方面的API
NSURL *baseURL = [NSURL URLWithString:@"http://example.com/"];
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:baseURL];
NSOperationQueue *operationQueue = manager.operationQueue;
[manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
switch (status) {
case AFNetworkReachabilityStatusReachableViaWWAN:
case AFNetworkReachabilityStatusReachableViaWiFi:
[operationQueue setSuspended:NO];
break;
case AFNetworkReachabilityStatusNotReachable:
default:
[operationQueue setSuspended:YES];
break;
}
}];
//开始监控
[manager.reachabilityManager startMonitoring];
|