Unit test for AFNetworking Post request - ios

I am trying to write unit test for my project which I use AFNetworking in.I use the following operation for my request:
- (void)testRegisterRequest{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:url parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
XCTAssert(Result,"Register failed!");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//Failure
}
As it is asynchronous it never test my XCTAssert line.
I searched a lot but I couldn't manage to find a tutorial or example for these test cases.Please help me by any tutorial link or hint.
Thanks in advance

There are a couple of things here.
You can use expectations for async tests: Asynchronous Testing With Xcode 6
You can use OHHTTPStubs to avoid unneeded network traffic and server load: Usage Examples

XCTestExpectation is a valid approach. Other testing frameworks offer different ways. For example, we can test a success response using OCHamcrest like this:
- (void)testRegisterRequest
{
__block id response = nil;
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:url parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
response = responseObject;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
assertWithTimeout(5, thatEventually(response), is(notNilValue()));
}
You would probably test the response for its attributes, instead of simply testing that it is not a nil value.

Related

GZip my AFNetworking posts to my server

My application posts large amounts of data, Orders with Order Items - sometimes 1000's, and I want to send it GZipped because my users also have crappy connections most of the time.
How can I accomplish this with AFnetworking?
I am currently using AFHTTPSessionManager to perform my posts.
You can use AFgzipRequestSerializer.
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer = [AFgzipRequestSerializer serializerWithSerializer:[AFJSONRequestSerializer serializer]];
[manager POST:#"http://example.com/"
parameters:#{#"foo": #"bar"}
success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(#"%#", responseObject);
}
failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(#"[Error] %#", error);
}];
See details here.

Objective-c Send Post request to json-RPC webservice

In iOS i want send a POST request to a json-RPC web service. How can i do this?
i read This Page before and this repo but none of them have helped me.
Take a look at the popular AFNetworking networking library. This provides full networking functionality and very well documented code. Although you can also use Apple's networking APIs for this.
Simple AFNetworking example:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
NSDictionary *params = #{#"q":#"Chicago",
#"units":#"imperial",
#"type":#"like",
#"mode":#"json"
};
[manager GET:#"http://api.openweathermap.org/data/2.5/weather" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
//Success
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//Failure
}];
There is this AFJSONRPCClient, which is a JSON-RPC Client built on AFNetworking.
Hope it helps.

How to make HTTP-POST in objective-c

I want to send a HTTP-POST message to a server. I have searched on the internet and there where only very old posts. THis was the best one: Simple http post example in Objective-C?
Does this still works? or are there new ways to make an HTTP-POST message?
You should use AFNetworking lib: https://github.com/AFNetworking/AFNetworking
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"foo": #"bar"};
[manager POST:#"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
ASIHTTP Request is undoubtedly a great way for a HTTP-POST communication. This is probably the easiest to use also...
Here's another tutorial for making GET, simple POST and multipart POST requests.
Look up "URL encoded HTTP POST requests" :)

AFNetworking 2.0 and authorizing the Imgur API

Imgur's API requires that for simply looking up information about an image you just need to authorize your app with your API keys, no need to log in with an account or anything.
It says:
...all you need to do is send an authorization header with your client_id in your requests
Which apparently looks like:
Authorization: Client-ID YOUR_CLIENT_ID
So I tried doing this using AFHTTPRequestOperationManager, which appears to be the replacement for AFHTTPClient in AFNetworking 2.0 as shown below:
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
[operationManager POST:#"https://api.imgur.com/3/image/1Nf1quS" parameters:#{#"Authorization": #"Client-ID ---"} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failure");
}];
Basically tried to send a request with authorization information (I removed my ID for this post). It keeps giving "failure" as a response however.
So I tried playing around with the credential property but NSURLCredential seems to be based off a username and password, and I have neither of those as I just need my client ID.
So I tried a completely different way again:
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
NSMutableURLRequest *request= [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"https://api.imgur.com/3/image/1Nf1quS"]];
[request addValue:#"Client-ID ---" forHTTPHeaderField:#"Authorization"];
[operationManager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"fail");
}];
This time using the authorization things as a value on the request. But this one actually never even logged anything.
I'm quite new to API use, so I'm really confused what I'm doing wrong.
Edit:
Try this code snippet
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
[operationManager.requestSerializer setValue:#"Client-ID ---" forHTTPHeaderField:#"Authorization"];
[operationManager GET:#"https://api.imgur.com/3/image/1Nf1quS" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failure");
}];
I don't know about Imgur API, but for handling header and stuff, if you are just gonna do a few request to the API, you may add the headers just before the request operation. However, if you need to make API calls in more than one place, I think subclassing AFHTTPRequestOperationManager would be a better way to handle this.
For example you can create a subclass named MRTImgurRequestOperationManager:
#interface MRTImgurRequestOperationManager : AFHTTPRequestOperationManager
+ (MRTImgurRequestOperationManager*)sharedManager;
#end
and then in your implementation file:
+ (MRTImgurRequestOperationManager*)sharedManager
{
static MRTImgurRequestOperationManager *_sharedManager;
static dispatch_once_t _dispatchOnceToken;
dispatch_once(&_dispatchOnceToken, ^{
NSURL *baseURL = [NSURL URLWithString:#"API_URL_HERE"];
_sharedManager = [[MRTImgurRequestOperationManager alloc] initWithBaseURL:baseURL];
});
return _sharedManager;
}
- (id)initWithBaseURL:(NSURL*)url
{
self = [super initWithBaseURL:url];
if (self)
{
// Add headers or other options here
// For example
[self.requestSerializer setValue:#"VALUE" forHTTPHeaderField:#"HEADER_NAME"];
}
return self;
}
This way, you can add/remove HTTP headers without ever changing you code in couple of places. This may help with the testing as well.
So to use this, you would:
#import "MRTImgurRequestOperationManager.h"
and then make your Imgur request with the shared manager.
Edit:
You should use GET, not POST, with the API endpoint you are using
[[MRTImgurRequestOperationManager sharedManager] GET:#"path" parameters:params success:success failure:failure]];
In AFNetworking 2.0 you can set header fields. By using method from AFHTTPRequestSerializer
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field
Try some thing like this:
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
[operationManager.requestSerializer setValue:#"Client-ID ---" forHTTPHeaderField:#"Authorization"];
[operationManager POST:#"https://api.imgur.com/3/image/1Nf1quS" parameters:#{#"Authorization": #"Client-ID ---"} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failure");
}];

how to POST data to an endpoint in iOS7?

I know there are tons ways to POST from an iOS app from nsurlconnection to asihttprequest.
What is the preferred or best practices way to post a few variables, asynchronously, to an end point, in iOS7?
My endpoint can be invoked in the following fashion:
curl -d 'username=tt&email=tt#example.com' 127.0.0.1/register
I ended up using afnetworking. This method works real nice.
-(void) postDictionary:(NSDictionary *)data toEndpoint:(NSString *)endpoint{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:endpoint parameters:data success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}

Resources