기존에 유용하게 쓰던 ASIHTTP가 업데이트가 중지된지 한참 되어(ARC도 지원 안 해주시고..) 대체할만한 wrapper class를 찾던 중 AFNetworking을 추천받았다.
현재 활발하게 업데이트 되고있으며, 간단한 사용법은 다음과 같다.
참조 사이트: https://github.com/AFNetworking/AFNetworking/wiki/Getting-Started-with-AFNetworking
https://github.com/AFNetworking/AFNetworking
불편한 점이 있다면 POST 요청을 할 때 ASIHTTP보다 꽤나 번거롭다는 점이다.
이제 웬만하면 GET으로 보내야겠다는.. ㅎㅎ
예제1:
Download and Parse JSON
AFJSONRequestOperation
is the perfect tool for this job. All you need to do is ask it for a particular URL, and it'll give you JSON when it's done:
NSURL *url = [NSURL URLWithString:@"http://httpbin.org/ip"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(@"IP Address: %@", [JSON valueForKeyPath:@"origin"]);
} failure:nil];
[operation start];
First, we construct an NSURL
object and construct an NSURLRequest
object from it. NSURLRequest
encapsulates pretty much everything there is for an HTTP request, including url, method (GET
, POST
, PUT
, DELETE
, etc.), headers, and the body.
We then pass that url request object into AFJSONRequestOperation +JSONRequestOperationWithRequest:success:failure
.
The success
and failure
parameters take block arguments. Blocks are a relatively new and complex feature in Objective-C, so if you're unfamiliar with them, think about reading up on them. Blocks are objects that contain a specified behavior--code that can be executed later.
In the case of our success
and failure
callback blocks, we're specifying what should happen after the request finishes. The request happens in the background, without locking up or slowing down the app. Depending on whether the response from the server indicates success (e.g. 200
status code and JSON Content-Type
), or failure (e.g. 404
status code or unknown MIME type), the code in the corresponding block will be executed.
You'll notice that the argument for success
is ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
. The caret (^
) indicates that what follows is part of a block. The other arguments: request
, response
, and JSON
are local variables that are passed into the block. In the block, we can use these values to do things like log the contents of the JSON (like in our example), or do more useful things, like populate anNSArray
to update the data source of a UITableView
.
After constructing the operation object, we have to start it somehow. In the example, we simply send -start
, which kicks off the request and returns immediately.
Another option would be to take advantage of the fact that AFJSONRequestOperation
, like all of the request operations in AFNetworking, is a subclass of NSOperation
. In combination with NSOperationQueue, you can easily have several requests running concurrently (you have the ability to setting a maximum number of operations to run concurrently to keep your network from getting bogged down).
One last note: in addition to JSON, AFNetworking has a handful of request operations that download data and automatically convert it to things like XML, Images, and Property Lists (http://afnetworking.github.com/AFNetworking/Classes/AFPropertyListRequestOperation.html).
Download and Display Images
AFNetworking makes downloading and setting images as simple as getting an image from the project.
Start by adding #import "UIImageView+AFNetworking"
to the top of a controller or a view implementation file. This category adds methods toUIImageView
, like:
[imageView setImageWithURL:[NSURL URLWithString:@"…"]];
A longer form of this method also allow you to set a placeholder image while the image is downloading.
Use this anytime you need to load a remote image from the server.
Interact with an API, Web Service, or Application
Chances are pretty good that most if not all of the network requests you make are to a single API or web service, like a Rails or Sinatra backend.
If your app talks to a server backend (or a few different ones), then you'll love AFHTTPClient
.
AFHTTPClient
has everything you need for talking to a web API. It stores a base URL, which you can request relative paths to (e.g. base URL:http://example.com
+ relative path: /users
= http://example.com/users
). You can store a common set of header for things like authentication, content type, and language preferences, which will be added to any request you make with the client. Best of all, it will even automatically figure out how to parse your server response, so JSON requests give you JSON objects, XML requests give you parser objects, etc.
Here are some guidelines on how best to use AFHTTPClient
:
- Create a subclass for each service endpoint you hit. For instance, if you're writing a social network aggregator, you might want a client for Twitter, one for Facebook, another for Instragram, and so on.
- In HTTP client subclasses, create a class method that returns a shared singleton instance. This way, you can configure and use a single client to use throughout the entire app.
- Want to upload a file? Check out
-multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:
. In the block, send the multipart form data builder-appendPartWithFileData:name:fileName:mimeType:
- If you need to send request parameters as JSON, simply set the
parameterEncoding
property toAFJSONParameterEncoding
. - If you need to configure or hold a reference to a request operation before it's enqueued into the client's operation queue, use
-HTTPRequestOperationWithRequest:success:failure
. Likewise with the URL request object, userequestWithMethod:path:parameters
.
A good example of an AFHTTPClient
subclass can be found in the example project: AFAppDotNetAPIClient
. Use it as a starting point for your own client.
예제 2:
Overview
AFNetworking is architected to be as small and modular as possible, in order to make it simple to use and extend.
Core | |
---|---|
AFURLConnectionOperation | An NSOperation that implements the NSURLConnection delegate methods. |
HTTP Requests | |
AFHTTPRequestOperation | A subclass of AFURLConnectionOperation for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request. |
AFJSONRequestOperation | A subclass of AFHTTPRequestOperation for downloading and working with JSON response data. |
AFXMLRequestOperation | A subclass of AFHTTPRequestOperation for downloading and working with XML response data. |
AFPropertyListRequestOperation | A subclass of AFHTTPRequestOperation for downloading and deserializing objects withproperty list response data. |
HTTP Client | |
AFHTTPClient | Captures the common patterns of communicating with an web application over HTTP, including:
|
Images | |
AFImageRequestOperation | A subclass of AFHTTPRequestOperation for downloading and processing images. |
UIImageView+AFNetworking | Adds methods to UIImageView for loading remote images asynchronously from a URL. |
Example Usage
XML Request
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://api.flickr.com/services/rest/?method=flickr.groups.browse&api_key=b6300e17ad3c506e706cb0072175d047&cat_id=34427469792%40N01&format=rest"]];
AFXMLRequestOperation *operation = [AFXMLRequestOperation XMLParserRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) {
XMLParser.delegate = self;
[XMLParser parse];
} failure:nil];
[operation start];
Image Request
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"]];
API Client Request
// AFAppDotNetAPIClient is a subclass of AFHTTPClient, which defines the base URL and default HTTP headers for NSURLRequests it creates
[[AFAppDotNetAPIClient sharedClient] getPath:@"stream/0/posts/stream/global" parameters:nil success:^(AFHTTPRequestOperation *operation, id JSON) {
NSLog(@"App.net Global Stream: %@", JSON);
} failure:nil];
File Upload with Progress Callback
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: ^(id <AFMultipartFormData>formData) {
[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);
}];
[operation start];
Streaming Request
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];
'iPhone dev. > AFNetworking / ASIHTTP' 카테고리의 다른 글
AFNetworking POST 요청 보내기 (0) | 2012.11.26 |
---|---|
ASIHTTP를 이용한 request/response (0) | 2011.08.08 |