[iOS 多線程 & 網路,ios多線程
A.AFN基本知識1.概念
- AFNetworking
- 是對NSURLConnection的封裝
- 運行效率沒有ASI高(因為ASI基於CFNetwork),但是使用簡單
- AFN支援ARC
B.基本請求使用1.基本使用(1)標頭檔 AFNetworking.h(2)管理者類:AFHTTPRequestOperationManager(3)“GET”方法發送GET請求,使用“POST”方法發送POST請求(4)使用字典發送參數(5)block處理請求成功/失敗
1 /** 發送 GET/POST 請求 */ 2 - (void) sendNormalRequest { 3 // 1.建立請求 管理者 4 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 5 6 // 2.設定參數 7 NSMutableDictionary *param = [NSMutableDictionary dictionary]; 8 param[@"user"] = @"tom"; 9 param[@"password"] = @"123";10 11 // 3.發送請求12 // // 3.1 GET請求13 // [manager GET:@"http://192.168.0.21:8080/MyTestServer/login" parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {14 // NSLog(@"請求成功");15 // NSLog(@"%@", responseObject);16 // } failure:^(AFHTTPRequestOperation *operation, NSError *error) {17 // NSLog(@"請求失敗");18 // NSLog(@"%@", error);19 // }];20 21 // 3.2 POST請求22 [manager POST:@"http://192.168.0.21:8080/MyTestServer/login" parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {23 NSLog(@"請求成功");24 NSLog(@"%@", responseObject);25 } failure:^(AFHTTPRequestOperation *operation, NSError *error) {26 NSLog(@"請求失敗");27 NSLog(@"%@", error);28 }];29 } 2.為了方便查看伺服器返回的中文資料,給數組和字典增加一個分類,支援中文
1 #import <Foundation/Foundation.h> 2 3 @implementation NSDictionary (Log) 4 5 /** 本地化顯示 */ 6 - (NSString *)descriptionWithLocale:(id)locale { 7 NSMutableString *str = [NSMutableString string]; 8 9 [str appendString:@"{\n"];10 11 // 遍曆字典12 [self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {13 [str appendFormat:@"\t%@ = %@,\n", key, obj];14 }];15 16 [str appendString:@"}"];17 18 // 取出最後一個“,”19 NSRange range = [str rangeOfString:@"," options:NSBackwardsSearch];20 [str deleteCharactersInRange:range];21 22 return str;23 }24 25 @end26 27 @implementation NSArray (Log)28 29 - (NSString *)descriptionWithLocale:(id)locale {30 NSMutableString *str = [NSMutableString string];31 32 [str appendString:@"[\n"];33 34 // 遍曆數組所有元素35 [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {36 [str appendFormat:@"%@, \n", obj];37 }];38 39 [str appendString:@"]"];40 41 return str;42 }43 44 @end 3.解析返回的json資料
- AFHTTPRequestOperationManager 依靠設定序列化器來自動識別、解析返回的資料
- 預設使用的就是json解析,可以不用設定序列化器
- 會把json自動轉換成為字典或者數組輸出
1 /** 返回json資料 */ 2 - (void) getJson { 3 // 1.建立請求 管理者 4 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 5 6 // 設定序列化器 7 // [manager setResponseSerializer:[AFJSONResponseSerializer serializer]];//預設 8 9 // 2.設定參數10 NSMutableDictionary *param = [NSMutableDictionary dictionary];11 param[@"type"] = @"json";12 13 // 3.發送請求14 [manager GET:@"http://192.168.0.21:8080/MyTestServer/video" parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {15 NSLog(@"請求成功");16 NSLog(@"返回的資料類型是:%@", [responseObject class]);17 NSLog(@"%@", responseObject);18 } failure:^(AFHTTPRequestOperation *operation, NSError *error) {19 NSLog(@"請求失敗");20 NSLog(@"%@", error);21 }];22 } output:
2015-01-30 03:34:14.817 AFNBasicDemo[1889:192783]
請求成功
2015-01-30 03:34:14.817 AFNBasicDemo[1889:192783]
返回的資料類型是
:__NSCFDictionary
2015-01-30 03:34:14.818 AFNBasicDemo[1889:192783] {
videos = [
{
name =
馴龍高手
1,
video = videos/1.MP4,
length = 16
秒
,
image = images/[20150124-180852-0].PNG
},
... 4.解析返回的xml資料設定使用xml序列化器,也可以自動將xml資料轉換成為字典或者數組如果不設定xml序列化器,處理返回資料會失敗
1 /** 返回xml資料 */ 2 - (void) getXml{ 3 // 1.建立請求 管理者 4 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 5 6 // 設定序列化器 7 [manager setResponseSerializer:[AFXMLParserResponseSerializer serializer]]; 8 9 // 2.設定參數10 NSMutableDictionary *param = [NSMutableDictionary dictionary];11 param[@"type"] = @"xml";12 13 14 // 3.發送請求15 __weak typeof(self) vc = self;16 [manager GET:@"http://192.168.0.21:8080/MyTestServer/video" parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {17 NSLog(@"請求成功");18 NSLog(@"返回的資料類型是:%@", [responseObject class]);19 20 NSXMLParser *parser = (NSXMLParser *) responseObject;21 parser.delegate = vc;22 [parser parse];23 } failure:^(AFHTTPRequestOperation *operation, NSError *error) {24 NSLog(@"請求失敗");25 NSLog(@"%@", error);26 }];27 }
C.檔案下載/上傳1.檔案下載
1 - (void) downloadFile { 2 // 1.建立要求管理者 3 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 4 5 // 設定序列化器 6 [manager setResponseSerializer:[AFHTTPResponseSerializer serializer]]; // 使用位元據序列化 7 8 // 3.發送請求 9 [manager GET:@"http://192.168.0.21:8080/MyTestServer/images/images.zip" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {10 11 NSLog(@"請求成功");12 NSLog(@"返回的資料類型是:%@", [responseObject class]);13 14 NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];15 NSString *filePath = [cachePath stringByAppendingPathComponent:@"download.zip"];16 NSData *data = (NSData *) responseObject;17 [data writeToFile:filePath atomically:YES];18 19 } failure:^(AFHTTPRequestOperation *operation, NSError *error) {20 NSLog(@"請求失敗");21 NSLog(@"%@", error);22 }];23 } 2.檔案上傳
- 使用POST請求,帶formData的post方法
- 要區分普通參數和檔案參數,把檔案資料放在普通參數中上傳是不行的
- 檔案放在block參數中賦值
(1)把檔案轉換成位元據(2)拼接檔案參數
1 /** 上傳檔案 */ 2 - (void) uploadFile { 3 // 1.建立要求管理者 4 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 5 6 // 2.設定參數 7 NSMutableDictionary *param = [NSMutableDictionary dictionary]; 8 param[@"user"] = @"uploader"; 9 10 // 3.設定上傳檔案11 NSString *filePath = [[NSBundle mainBundle] pathForResource:@"M2.jpg" ofType:nil];12 NSData *fileData = [NSData dataWithContentsOfFile:filePath];13 14 // 4.上傳檔案15 __weak typeof(fileData) uploadData = fileData;16 17 [manager POST:@"http://192.168.0.21:8080/MyTestServer/upload" parameters:param constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {18 19 // 拼接檔案資料20 [formData appendPartWithFileData:uploadData name:@"uploadedFile" fileName:@"my_pic.jpg" mimeType:@"image/jpg"];21 22 } success:^(AFHTTPRequestOperation *operation, id responseObject) {23 NSLog(@"上傳成功 ---- %@", responseObject);24 } failure:^(AFHTTPRequestOperation *operation, NSError *error) {25 NSLog(@"上傳失敗 ---- %@", error);26 }];27 }
D.網路狀態監控AFNetworkReachabilityManager(1)建立網路監控管理者(2)設定監控網路狀態變化(3)開啟監控(4)也可以主動去擷取網路狀態
1 - (IBAction)monitorNetwork:(UIButton *)sender { 2 // 1.建立網路狀態監控管理者 3 AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager]; 4 5 // 2.網路狀態改變事件(被動檢測) 6 [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { 7 switch (status) { 8 case AFNetworkReachabilityStatusUnknown: 9 NSLog(@"轉換為未知網路");10 break;11 case AFNetworkReachabilityStatusReachableViaWWAN:12 NSLog(@"轉換為行動電話通訊");13 break;14 case AFNetworkReachabilityStatusReachableViaWiFi:15 NSLog(@"轉換為WIFI網路");16 break;17 case AFNetworkReachabilityStatusNotReachable:18 NSLog(@"轉換為沒有網路");19 break;20 21 default:22 break;23 }24 }];25 26 // 開啟監控27 [manager startMonitoring];28 29 // 主動式偵測30 if ([manager isReachable]) {31 NSLog(@"現在有網路");32 } else if ([manager isReachableViaWiFi]) {33 NSLog(@"現在是通過wifi上網");34 } else if ([manager isReachableViaWWAN]) {35 NSLog(@"現在是通過行動電話通訊上網");36 } else {37 NSLog(@"現在沒有網路");38 }39 }