NSURLSession使用與AFNetWorking使用

介紹iOS中的兩種網絡編程。

NSURLSession

iOS原生網絡編程:支持後臺下載上傳、提供全局session、下載時是多線程異步處理效率更高。
使用上非常簡單、創建一個請求Task然後執行。NSURLSessionTask有一些子類:NSURLSessionDataTask(發送常見的Get,Post請求)、NSURLSessionDownloadTask(發送下載請求)、NSURLSessionUploadTask(發送上傳請求)

1. NSURLSession發送Get請求

  • 過程:確認請求路徑NSURL對象、創建請求對象NSURLRequest對象、創建會話對象NSURLSession、創建請求任務並執行、得到響應解析數據
  • 代碼示例:
//創建請求路徑
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://39.98.152.99:80/login?username=%@&password=%@",username,password]];
//創建請求對象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//獲得會話對象
NSURLSession *session = [NSURLSession sharedSession];
//創建Task並執行,在block裏接收返回數據
NSURLSessionTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if(error == nil) {
        	//接收字符串數據
            NSString *responseInfo = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            //接收字典類型
            NSDictionary *responseInfo = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
        }else{
            NSLog(@"error:%@",error);
        }
}];
[dataTask resume];

2. NSURLSession發送Post請求

  • 過程:確定請求路徑(NSURL)、創建可變請求對象(NSMutableURLRequest)、設置請求方法與請求體、創建會話對象、創建請求任務並執行、響應後解析數據。
  • 代碼示例
//確定請求路徑
NSURL *url = [NSURL URLWithString:@"http://39.98.152.99:80/login"];
//創建可變請求對象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//設置請求方法與請求體
request.HTTPMethod = @"POST";
request.HTTPBody = [@"username=jack&password=123" dataUsingEncoding:NSUTF8StringEncoding];
//創建會話對象
NSURLSession *session = [NSURLSession sharedSession];
//創建Task並執行
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

}];

3. 使用代理完成請求
監聽網絡請求的過程,需要遵守協議並實現代理方法。

  • 確定請求路徑
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://39.98.152.99:80/login?username=%@&password=%@",username,password]];
  • 創建請求對象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
  • 獲得會話對象並設置代理
    第三個參數決定代理方法在哪個線程中調用,[[NSOperationQueue alloc] init]則在子線程中調用,示例爲主線程。
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config
													 delegate:self 
                            					delegateQueue:[NSOperationQueue mainQueue]];
  • 遵從協議並設置接收信息的變量。
@interface LoginViewController ()<NSURLSessionDataDelegate>
@property (nonatomic, strong) NSMutableData *mData;
@end
  • 創建Task並執行
NSURLSessionDataTask *task = [session dataTaskWithRequest:request];
[task resume];
  • 代理方法的實現
//收到服務器響應的時候調用
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
    //打印http信息
    NSHTTPURLResponse *htttpResponse = (NSHTTPURLResponse *)response;
    NSLog(@"響應頭:%@",htttpResponse.allHeaderFields);
    
    //定義一個容器用於接受服務器返回的數據
    self.mData = [NSMutableData data];
    //收到響應信息之後,需要使用completionHandler回調告訴系統應該如何處理服務器返回的數據
    //默認是取消的(NSURLSessionResponseCancel),繼續傳遞數據(NSURLSessionResponseAllow)
    completionHandler(NSURLSessionResponseAllow);
}

//收到服務器返回數據的時候會調用
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
    [_mData appendData:data];
}

//請求完成(成功|失敗)的時候會調用
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
    //解析服務器返回的數據
}

AFNetWorking

第三方框架,由NSURLSession(AFURLSessionManager、AFHTTPSeesionManager)、Serialization( 協議、 協議)、AFSecurityPolicy(安全)、其他緩存。
1. AFURLSessionManager(和NSURLSession很相似)

  • 普通數據任務
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:@"http://httpbin.org/get"];
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];
  • 下載任務
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];

2. AFHTTPSeesionManager、是封裝的子類,更便捷(推薦)。

  • 發送Get請求
//1.創建AFHTTPSessionManager管理者(內部是基於NSURLSession實現)
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//2.發送請求
NSDictionary *param = @{@"username":@"520it",@"pwd":@"520it"};
[manager GET:@"http://120.25.226.186:32812/login" parameters:param success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
	NSLog(@"請求成功 %@",[responseObject class]);
}failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {
    NSLog(@"失敗 %@",error);
}];
//responseObject是請求成功返回的響應結果、通常是字典或數組
  • 下載文件
-(void)download
{
    //創建一個管理者
    AFHTTPSessionManager *manage  = [AFHTTPSessionManager manager];
    //創建請求對象
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_02.png"]];
    //創建下載進度並監聽
    NSProgress *progress = nil;
    NSURLSessionDownloadTask *downloadTask = [manage downloadTaskWithRequest:request progress:&progress destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
        //拼接文件全路徑
        NSString *fullpath = [caches stringByAppendingPathComponent:response.suggestedFilename];
        NSURL *filePathUrl = [NSURL fileURLWithPath:fullpath];
        return filePathUrl;
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nonnull filePath, NSError * _Nonnull error) {
        NSLog(@"文件下載完畢---%@",filePath);
    }];
    //參數:請求對象、下載進度、block回調,返回下載文件的目標地址、下載完成之後調用的block
    
    //使用KVO監聽下載進度
    [progress addObserver:self forKeyPath:@"completedUnitCount" options:NSKeyValueObservingOptionNew context:nil];
    [downloadTask resume];
}

//獲取並計算當前文件的下載進度
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(NSProgress *)progress change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    NSLog(@"%zd--%zd--%f",progress.completedUnitCount,progress.totalUnitCount,1.0 * progress.completedUnitCount/progress.totalUnitCount);
}
  • 上傳文件
-(void)upload
{
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    //發送POST請求上傳數據
    NSDictionary *dict = @{
                           @"username":@"wenidngding"
                           };
    [manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
     //把本地的圖片轉換爲NSData類型的數據
     UIImage *image = [UIImage imageNamed:@"123"];
     NSData *data = UIImagePNGRepresentation(image);
     [formData appendPartWithFileData:data name:@"file" fileName:@"xxoo.png" mimeType:@"application/octet-stream"];
     } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
        NSLog(@"請求成功---%@",responseObject);
     } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {
        NSLog(@"請求失敗--%@",error);
    }];
}

另一種上傳請求根據url確定文件

-(void)upload2
{
    //1.創建一個請求管理者
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    NSDictionary *dict = @{
                           @"username":@"wenidngding"
                           };
    [manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        //本地文件的url
        NSURL *fileUrl = [NSURL fileURLWithPath:@"/Users/文頂頂/Desktop/KF[WTI`AQ3T`A@3R(B96D89.gif"];
        [formData appendPartWithFileURL:fileUrl name:@"file" error:nil];
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
        NSLog(@"請求成功---%@",responseObject);
    } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {
        NSLog(@"請求失敗--%@",error);
    }];
}
  1. 代理方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章