iOS新手入门:开源项目AFNetworking 网络库学习

文章标签: ios开发
2014-10-22 17:07:51     48 人阅读    

https://github.com/AFNetworking/AFNetworking
与asi-http-request功能类似的网络库,不过是基于NSURLConnection 和 NSOperation 的,同样支持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"];
A
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
N
NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:@"avatar.jpg"], 0.5);
N
NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:@"POST" path:@"/upload" parameters:nil constructingBodyWithBlock: ^(id formData) {
 
    [formData appendPartWithFileData:imageData name:@"avatar" fileName:@"avatar.jpg" mimeType:@"image/jpeg"];
}
}];



A
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"]];



A
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
o
operation.inputStream = [NSInputStream inputStreamWithFileAtPath:[[NSBundle mainBundle] pathForResource:@"large-image" ofType:@"tiff"]];
o
operation.outputStream = [NSOutputStream outputStreamToMemory];
[
[operation start];

 
参考:
http://www.raywenderlich.com/zh-hans/36079/afnetworking%E9%80%9F%E6%88%90%E6%95%99%E7%A8%8B%EF%BC%881%EF%BC%89


原文地址:http://www.itmmd.com/201410/53.html
该文章由 萌萌的IT人 整理发布,转载须标明出处。

Android 教程-解压缩功能实现   上一篇
下一篇  iOS新手入门:MMDrawerController 控件学习

精彩回复
发表评论
姓名:       

《程序员app》专门为程序员量身定做!