https://github.com/AFNetworking/AFNetworking
与asi-http-request功能类似的网络库,不过是基于 和 的,同样支持iOS与MacOS双平台。目前的更新比较频繁,适合新项目使用,而且使用起来也更简单。
操作JSON
- (IBAction)jsonTapped:(id)sender { // 1 NSString *weatherUrl = [NSString stringWithFormat:@"%@weather.php?format=json", BaseURLString]; NSURL *url = [NSURL URLWithString:weatherUrl]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; // 2 AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request // 3 success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { self.weather = (NSDictionary *)JSON; self.title = @"JSON Retrieved"; [self.tableView reloadData]; } // 4 failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error Retrieving Weather" message:[NSString stringWithFormat:@"%@",error] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [av show]; }]; // 5 [operation start];}
- 根据基本的URL构造出完整的一个URL。然后通过这个完整的URL获得一个NSURL对象,然后根据这个url获得一个NSURLRequest.
- AFJSONRequestOperation 是一个功能完整的类(all-in-one)— 整合了从网络中获取数据并对JSON进行解析。
- 当请求成功,则运行成功块(success block)。在本示例中,把解析出来的天气数据从JSON变量转换为一个字典(dictionary),并将其存储在属性 weather 中.
- 如果运行出问题了,则运行失败块(failure block),比如网络不可用。如果failure block被调用了,将会通过提示框显示出错误信息。
操作Property Lists(plists)
-(IBAction)plistTapped:(id)sender{ NSString *weatherUrl = [NSString stringWithFormat:@"%@weather.php?format=plist",BaseURLString]; NSURL *url = [NSURL URLWithString:weatherUrl]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; AFPropertyListRequestOperation *operation = [AFPropertyListRequestOperation propertyListRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id propertyList) { self.weather = (NSDictionary *)propertyList; self.title = @"PLIST Retrieved"; [self.tableView reloadData]; } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id propertyList) { UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error Retrieving Weather" message:[NSString stringWithFormat:@"%@",error] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [av show]; }]; [operation start];}
上面的代码几乎与JSON版的一致,只不过将操作(operation)的类型从AFJSONOperation 修改为 AFPropertyListOperation.
操作XML
- (IBAction)xmlTapped:(id)sender{ NSString *weatherUrl = [NSString stringWithFormat:@"%@weather.php?format=xml",BaseURLString]; NSURL *url = [NSURL URLWithString:weatherUrl]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; AFXMLRequestOperation *operation = [AFXMLRequestOperation XMLParserRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) { //self.xmlWeather = [NSMutableDictionary dictionary]; XMLParser.delegate = self; [XMLParser setShouldProcessNamespaces:YES]; [XMLParser parse]; } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLParser *XMLParser) { UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error Retrieving Weather" message:[NSString stringWithFormat:@"%@",error] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [av show]; }]; [operation start];}
到现在为止,这看起来跟之前处理JSON和plist很类似。最大的改动就是在成功块(success block)中, 在这里不会传递给你一个预处理好的NSDictionary对象. 而是AFXMLRequestOperation实例化的NSXMLParse对象,这个对象将用来处理繁重的XML解析任务。
NSXMLParse对象有一组delegate方法是你需要实现的 — 用来获得XML数据。注意,在上面的代码中我将XMLParser的delegate设置为self, 因此WTTableViewController将用来处理XML的解析任务。
下载图片
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 100.0f)];[imageView setImageWithURL:[NSURL URLWithString:@"http://i.imgur.com/r4uwx.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder-avatar"]];
- (IBAction)updateBackgroundImage:(id)sender { //Store this image on the same server as the weather canned files NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.scott-sherwood.com/wp-content/uploads/2013/01/scene.png"]]; AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request imageProcessingBlock:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) { self.backgroundImageView.image = image; [self saveImage:image withFilename:@"background.png"]; } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) { NSLog(@"Error %@",error); }]; [operation start];}
-(void)saveImage:(UIImage *)image withFilename:(NSString *)filename{ NSString *path; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"WeatherHTTPClientImages/"]; BOOL isDir; if(![[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir]){ if(!isDir){ NSError *error; [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]; NSLog(@"%@",error); } } path = [path stringByAppendingPathComponent:filename]; NSData *imageData = UIImagePNGRepresentation(image); NSLog(@"Written: %d",[imageData writeToFile:path atomically:YES]);}
AFHTTPClient
AFHTTPClient一般是给它设置一个基本的URL,然后用AFHTTPClient进行多个请求(而不是像之前的那样,每次请求的时候,都创建一个AFHTTPClient)。
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ if(buttonIndex==0){ NSURL *baseURL = [NSURL URLWithString:[NSString stringWithFormat:BaseURLString]]; NSDictionary *parameters = [NSDictionary dictionaryWithObject:@"json" forKey:@"format"]; AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:baseURL]; [client registerHTTPOperationClass:[AFJSONRequestOperation class]]; [client setDefaultHeader:@"Accept" value:@"application/json"]; [client postPath:@"weather.php" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { self.weather = responseObject; self.title = @"HTTP POST"; [self.tableView reloadData]; } failure:^(AFHTTPRequestOperation *operation, NSError *error) { UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error Retrieving Weather" message:[NSString stringWithFormat:@"%@",error] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [av show]; } ]; } else if (buttonIndex==1){ NSURL *baseURL = [NSURL URLWithString:[NSString stringWithFormat:BaseURLString]]; NSDictionary *parameters = [NSDictionary dictionaryWithObject:@"json" forKey:@"format"]; AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:baseURL]; [client registerHTTPOperationClass:[AFJSONRequestOperation class]]; [client setDefaultHeader:@"Accept" value:@"application/json"]; [client getPath:@"weather.php" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { self.weather = responseObject; self.title = @"HTTP GET"; [self.tableView reloadData]; } failure:^(AFHTTPRequestOperation *operation, NSError *error) { UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error Retrieving Weather" message:[NSString stringWithFormat:@"%@",error] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [av show]; } ]; }}
- 构建一个baseURL,以及一个参数字典,并将这两个变量传给AFHTTPClient.
- 将AFJSONRequestOperation注册为HTTP的操作, 这样就可以跟之前的示例一样,可以获得解析好的JSON数据。
- 做了一个GET请求,这个请求有一对block:success和failure。
- POST请求跟GET一样。
上传一个文件
NSURL *url = [NSURL URLWithString:@"http://api-base-url.com"];AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:@"avatar.jpg"], 0.5);NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:@"POST" path:@"/upload" parameters:nil constructingBodyWithBlock: ^(idformData) { [formData appendPartWithFileData:imageData name:@"avatar" fileName:@"avatar.jpg" mimeType:@"image/jpeg"];}];AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { NSLog(@"Sent %lld of %lld bytes", totalBytesWritten, totalBytesExpectedToWrite);}];[httpClient enqueueHTTPRequestOperation:operation];
下载一个文件
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:8080/encode"]];AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];operation.inputStream = [NSInputStream inputStreamWithFileAtPath:[[NSBundle mainBundle] pathForResource:@"large-image" ofType:@"tiff"]];operation.outputStream = [NSOutputStream outputStreamToMemory];[operation start];
参考: