Start NSURLConnection requests serially - ios

I'm looping through an array which contains few strings and making a request to a web server for each
strings in the array.
I would like each request to be processed completely before the subsequent request is sent to the server. Because each request sends me a response which I will send with next request and so on.
The problem I am having is that my NSURLConnection is set up using the standard asynchronous call. This results in requests not blocking any subsequent requests. But I need to block other requests in the loop before first completes.
The request URL is same always , only JSON data changes with every request in the loop.
Here is my code
for (int i = 0; i < array.count; i++)
{
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:finalJSON options:NSJSONWritingPrettyPrinted error:&error];
if (!jsonData) {
NSLog(#"Error creating JSON object: %#", [error localizedDescription]);
}
NSString *url = [NSString stringWithFormat:#“abc.com/folders”];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setValue:#"application/json;charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setValue:APIKEY forHTTPHeaderField:#"X_API_KEY"];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:jsonData];
//I am adding all connections to NSDictionary so that later I can process request.
NSURLConnection *connection = [self connectionForRequest:request];
[connection start];
}

I thought of 2 solutions for your problem:
AFNetworking - U can use AFNetworking and maintain a counter in the success block. The counter will count the requests and when all done, will do your next task.
GCD - Dispatch Groups - Grand Central Dispatch provide u the option to make group or requests and do something at the end (when all the requests finished). For that, u need to read nice tutorial (2nd part of "Ray Wenderlich". If U r not familiar with GCD, jump to the tutorial 1st part).
Anyway, With your code above U can't achieve your task. U don't have any async block which run at the end of the requests.
Edit:
Use AFNetworking:
U must remove your for loop first, and then do like this:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"foo": #"bar"};
[manager POST:#"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { // HERE u can do your second request which uses the first response
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters_new = <USE_YOUR_DATA_FROM_responseObject>;
[manager POST:#"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { // HERE u can do your third request which uses the first and second response
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];

A simple way to do this is with recursion. Create a method that sends the url connection, and, once the connection is complete, calls itself to send it again.
Here's the key to the solution: make a method that can be called recursively, which sends requests and collects results. By calling itself recursively in the completion block, this method sees to it that each request starts after the previous one finishes...
// note - edited per the comments to get a new NSURLRequest each time
- (void)makeRequests:(NSInteger)count
results:(NSMutableArray *)results
completion:(void (^)(NSError *))completion {
// complete recursion
if (count == 0) return completion(nil);
NSURLRequest *request = [self nextRequest];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error) {
[results addObject:data];
[self makeRequests:count-1 results:results completion:completion];
} else {
completion(error);
}
}];
}
To call it, allocate an array that will carry the results...
- (void)makeManyRequests {
NSMutableArray *resultsArray = [NSMutableArray array];
[self makeRequests:10 results:resultsArray completion:^(NSError *error) {
NSLog(#"done. results are %#", resultsArray);
}];
}
EDIT - Its unclear in the OP how this request changes each time, but it sounds like you have that figured out. This is just your originally posted code in its own method. Its a good idea to factor this out so your code can be clear on how it forms a different JSON payload each time...
- (NSURLRequest *)nextRequest {
id finalJSON = // your app supplies...
// somehow, this changes each time nextRequest is called
NSString *APIKEY = // your app supplies
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:finalJSON options:NSJSONWritingPrettyPrinted error:&error];
if (!jsonData) {
NSLog(#"Error creating JSON object: %#", [error localizedDescription]);
}
// your request creation code, copied from the OP
NSString *url = [NSString stringWithFormat:#"abc.com/folders"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setValue:#"application/json;charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setValue:APIKEY forHTTPHeaderField:#"X_API_KEY"];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:jsonData];
return request;
}

Related

Run Two urls in single method

I am finding for the way to run 2 services in a method one after another to post images one by one . after the 1st service i need to get response then i need pass that response to 2nd service.
The code i've used to post run a single service to post single image is
NSString *url=[NSString stringWithFormat:#"http://37.187.152.236/UserImage.svc/InsertObjectImage?%#",requestString];
NSLog(#"url1%#",url);
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;
[request setURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"POST"];
// Create 'POST' MutableRequest with Data and Other Image Attachment.
NSString *boundary = #"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#", boundary];
[request setValue:contentType forHTTPHeaderField:#"Content-Type"];
NSData *data = UIImageJPEGRepresentation(chosenImage1, 0.2f);
[request addValue:#"image/JPEG" forHTTPHeaderField:#"Content-Type"];
NSMutableData *body = [NSMutableData data];
[body appendData:[NSData dataWithData:data]];
[request setHTTPBody:body];
some similar questions may be there in stackoverflow but my need is completely different.
Flow of method must be like this
*Run 1st url --> generate response ({userid:"20",message:"success"} ) --> run 2nd url *
help me, thanks in advance for everyone.
you can call the second method with respect to the response of first method
-(void)webservicecall {
WebApiController *obj=[[WebApiController alloc]init];
NSMutableDictionary *imageparameter = [NSMutableDictionary dictionary];
NSData *imagedata = UIImagePNGRepresentation(self.productImageView.image);
[imageparameter setValue:imagedata forKey:#"image"];
[obj callAPIWithImage:#"upload.php" WithImageParameter:imageparameter WithoutImageParameter:nil SuccessCallback:#selector(upload_response:Response:) andDelegate:self];
}
Response From Web Service:
-(void)upload_response:(NSString *)apiAlias Response:(NSData *)response {
NSMutableDictionary *jsonDictionary=[NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableContainers error:nil];
NSString *responseMsg=[[NSString alloc] initWithString:[jsonDictionary objectForKey:#"message"]];
if ([responseCode isEqualToString:#"success"]) {
[self CallToSecondWebService];
}
}
Second WebService:
-(void)CallToSecondWebService
{
}
http://codewithchris.com/tutorial-how-to-use-ios-nsurlconnection-by-example/
NSURLConnection synchronous request on https
how to send Asynchronous URL Request?
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html
https://developer.apple.com/library/mac/documentation/cocoa/reference/foundation/classes/NSURLConnection_Class/Reference/Reference.html
You can read from all of these as per your choice..
Maybe this will help you.
-(void)getData:(NSString *)userid
{
/*--- Your Current code here ---*/
/*--- this is synchronous request you can use asynchronous as well ---*/
NSURLResponse *response = nil;
NSData *dataResponse = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
/*--- Save your response if you want ---*/
id Obj = [NSJSONSerialization JSONObjectWithData:dataResponse options:NSJSONReadingMutableLeaves error:nil];
if ([Obj isKindOfClass:[NSArray class]])
{
/*--- here you get response ---*/
/*--- I've created sample method that you can pass userid in same method ---*/
/*--- Call same method or create new method and do same thing ---*/
[self getData:[[Obj objectAtIndex:0] valueForKey:#"userid"]];
}
}
I would strongly discourage you in using sync connections, they block the thread until they have finished and if this thread is the main thread, they will block the user interactions. Also you will not have control on the chunk sent or auth challenges.
In your case most probably the best is to use a network manger such as AFNetworking 2 and creating different network operations, after that you can add dependencies between them (thus chaining them if you like).
The other way is dispatch_group. You can add the operations (or sessions) to a group and wait until they end.
[UPDATE]
In AFnetworking 2.0
NSDictionary * parameter = #{ParameterImage : mainImage ? #"1" : #"0",};
NSError * __autoreleasing * constructingError = nil;
AFHTTPRequestOperation * op1 = [self POST:ApiImageUploadURL parameters:parameter constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:[NSURL fileURLWithPath:imagePath] name: ParameterImageData error:constructingError];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSError * error = nil;
id objects = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:&error];
DLog(#"Response %#", objects);
NSString * imageID = [objects[#"id"] stringValue];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
DLog(#"Error%#", error);
}];
// create operation op2
[op2 addDependecy:op1];

Using NSURLConnection to retrieve data

I've got this api (http://www.timeapi.org/utc/now) that just gives the time as a string and I want to use NSURLConnection to retrieve it, except I'm confused as to how NSURLConnection works.
Current code:
+(NSString *) fetchTime
{
NSString *timeString=#"not_set";
//Code for URL request here
NSURL *timeURL = [NSURL URLWithString:#"http://www.timeapi.org/utc/now"]
return timeString;
}
The method is called from the view controller that will then in turn display it on the screen as per MVC, all I need is a good example to get me in the right direction.
In order to make a request to that api you need something like this:
NSURL *timeURL = [NSURL URLWithString:#"http://www.timeapi.org/utc/now"]
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:120];
NSData *urlData;
NSURLResponse *response;
NSError *error;
urlData = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
NSString *string = [[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding];
What you want to do is send an Asynchronous request to the server to fetch the Time. If you send out a synchronous request it will block your UI and for some reason if server took a minute to send the response back user wont be able to do anything for a minute. Example using the standard API :
Note that if you are using sync request you can expect a return value but in async calls you would need the help of a block to return the value. So
-(void) fetchTimeFromServerWithCompletionHandler:(void(^)(id)) onComplete {
NSURLRequest *timeRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.timeapi.org/utc/now"]];
[NSURLConnection sendAsynchronousRequest:timeRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *urlResponse, NSData *data, NSError *error) {
// Do something usefull with Data.
// If expected object is a String, alloc init a String with received Data
NSString *time = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
onComplete(time); // This will return back the time string.
}];
}
If you are using service API a lot in your app, you can check out AFNetworking as well.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:#"http://example.com/resources.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];

RestKit: Post multiple objects synchronously

In my app have an array of dictionaries containing GPS logs (100 per dictionary). I have to post these dictionaries one at a time to a server. The problem I am having is not posting which works just wonderful with RestKit, it is that I have to post them in the same order as they are in the array. This is due to an index count in the dictionaries which shouldn't be messed up on the server and in the same order as in the array.
How can I post these objects using RestKit in a synchronous manner?
Here ist the code I am using currently (asynchronous):
for (int i = 0; i < [arrayOfGPSLogChunks count]; i++)
{
NSMutableDictionary *historyToUpload = [[NSMutableDictionary alloc] init];
[historyToUpload setObject:driveID forKey:#"driveID"];
[historyToUpload setObject:[arrayOfGPSLogChunks objectAtIndex:i] forKey:#"gpsLog"];
[[RKObjectManager sharedManager] postObject:nil
path:#"api/drives/addDriveChunk"
parameters:historyToUpload
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
{
RKLogInfo(#"Successfully Uploaded Drive Chunk %i/%i", i,arrayOfGPSLogChunks.count);
}
failure:^(RKObjectRequestOperation *operation, NSError *error)
{
RKLogError(#"Failed Uploading Drive Chunk (%i): (Error: %#)", i, error);
}];
}
Update:
I tried using this method which does work just the ways I want it to but it blocks my whole UI thread:
for (int i = 0; i < [arrayOfGPSLogChunks count]; i++)
{
NSMutableDictionary *historyToUpload = [[NSMutableDictionary alloc] init];
[historyToUpload setObject:driveID forKey:#"driveID"];
[historyToUpload setObject:[arrayOfGPSLogChunks objectAtIndex:i] forKey:#"gpsLog"];
NSData *requestData = [NSJSONSerialization dataWithJSONObject:historyToUpload options:NSJSONWritingPrettyPrinted error:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:kUploadDrivesChunkURL]
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:kConnectionTimeOut];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:[NSString stringWithFormat:#"%d", [requestData length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody: requestData];
RKObjectRequestOperation *operation = [[RKObjectManager sharedManager] objectRequestOperationWithRequest:request success:nil failure:nil];
[operation start];
[operation waitUntilFinished];
if (operation.error)
{
...
}
}
Thanks a lot!
You should use NSOperationQueue to manage your server calls and setMaxConcurrentOperationCount to 1, like:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:1];
You can also take a look at this Link for further details.
You can set the operation queue of the object managers http client to have a max concurrent count of 1. Of you can use RestKit to do the mapping and then use something else to upload.
Arguably you should modify the server so that you send the objects and associated ordering information and then it doesn't matter what order they are received in (and this will remove numerous likely headaches in the future).

NSURLSessionUploadTask as separate method, but returning data to a call

Undoubtedly, people will shake their head in shame at the following, but I would appreciate the help.
I seem to make the same calls to NSURLSessionUploadTask with pretty much the same structure throughout the program. Hence, I am trying to make it a method which I can call from anywhere in the program and, when it's complete, return the NSDictionary to the call which made it.
Currently I have the following:
-(NSDictionary *)serverRequest:(NSString *)requestURL withDictionary:(NSDictionary *)sendDict {
NSURL *homeURL = [[NSURL alloc] initWithString:[NSString stringWithFormat:#"%#/%#",baseURL, requestURL]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:homeURL];
[request setHTTPMethod:#"POST"];
[request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setCachePolicy:NSURLCacheStorageAllowedInMemoryOnly];
NSData *sentData = [NSJSONSerialization dataWithJSONObject:sendDict options:0 error:nil];
NSURLSessionUploadTask *uploadTask = [_session uploadTaskWithRequest:request fromData:sentData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
returnedData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
if ([returnedData[#"code"] isEqualToString:#"OK"])
{
dispatch_async(dispatch_get_main_queue(), ^{
return returnedData;
});
}
}];
[uploadTask resume];
}
So I pass in the URL I want to call, and the NSDictionary which is then sent to the server. The server replies, with a JSON response, which I then turn into returnedData. I simply wish to pass this data back to the call which made it ... something like:
NSDictionary *mydata = #{#"email": userRegisterTextFieldEmailAddress.text};
NSDictionary *passedBackData = [self serverRequest:#"checkUserName" withDictionary:mydata];
When I try this it won't build as the dispatch_async isn't the right format etc, etc. I have tried to read up on this, and can't believe it's a hard problem? Surely others aren't making the same call with the same code each time they want to return some data from a web server?
Thanks in advance for any help you can give in clearing up my misunderstanding.
What you'd generally do is add a completion block parameter to your method, that specifies what you want to do upon receiving the response. So, add a block parameter to your method and add the code that calls that block, something like:
- (void) serverRequest:(NSString *)requestURL withDictionary:(NSDictionary *)sendDict completion:(void (^)(id responseObject, NSError *error))completion
{
NSURL *homeURL = [[NSURL alloc] initWithString:[NSString stringWithFormat:#"%#/%#", baseURL, requestURL]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:homeURL];
[request setHTTPMethod:#"POST"];
[request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setCachePolicy:NSURLCacheStorageAllowedInMemoryOnly];
NSData *sentData = [NSJSONSerialization dataWithJSONObject:sendDict options:0 error:nil];
NSURLSessionUploadTask *uploadTask = [_session uploadTaskWithRequest:request fromData:sentData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// report any network-related errors
if (!data) {
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(nil, error);
});
}
return;
}
// report any errors parsing the JSON
NSError *parseError = nil;
returnedData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
if (!returnedData) {
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(nil, parseError);
});
}
return;
}
// if everything is ok, then just return the JSON object
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(returnedData, nil);
});
}
}];
[uploadTask resume];
}
You'd then call this serverRequest method, specifying precisely what you want to do with the data you receive:
[self serverRequest:url withDictionary:dictionary completion:^(id responseObject, NSError *error) {
if (responseObject) {
// do what you want with the response object here
} else {
NSLog(#"%s: serverRequest error: %#", __FUNCTION__, error);
}
}];
Clearly, you can change this as you see fit, but hopefully this illustrates the idea. If, for example, you knew that responseObject was always going to be a NSDictionary, then I'd change the references to id responseObject with NSDictionary *responseObject.
But the idea is that you should just provide a block that takes the response data and/or the error as parameters. That way, the code that calls this method can specify what should happen when the asynchronous network request completes.
So the call is asynch so you can't really do it like that. What I tend to do is wait for the method to return on its own and then get the main thread (as you've done) and then update UI/models etc like that.

Waiting for multipart image sending get completed

I'm impementing an application in iOS7, it's kind of a social network app with posts with images and a backend that saves all of the data sent form the client. The iOS client is sending the information of the post via json and after the info is sent, it starts to send the image via multipart form using AFNetworking.
I need to be notified when the image is sent, so that I can refresh the main view of the app with the new posts, including the recently posted by the client. In the practice if I request the backend for the last posts and the multipart hasn't finished, the sending of the image gets interruped and fails to send the image.
The backend is develop in WCF and is a RESTful JSON web service.
Here is the method that sends the post to the backend:
+(void)addPostToServerAddtext:(NSString *)text addimage:(UIImage *)image addbeach:(NSString *)beach location:(NSString*)location;
{
NSLog(#"entro a addPost");
NSString *urlBackend = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"URLBackend"];
NSData* dataImage = UIImageJPEGRepresentation(image, 1.0);
NSString* ImageName = [NSString stringWithFormat:#"%#_%#.jpg",idUser ,dateToServer];
NSString *jsonRequest = [NSString stringWithFormat:#"{\"Date\":\"%#\"...."];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#newPost",urlBackend]];
NSMutableURLRequest *request = [ [NSMutableURLRequest alloc] initWithURL:url];
NSData *requestData = [NSData dataWithBytes:[jsonRequest UTF8String] length:[jsonRequest length]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:[NSString stringWithFormat:#"%d", [requestData length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:requestData];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
if (image != nil) {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:[NSString stringWithFormat:#"%#FileUpload",urlBackend]
parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:dataImage name:#"image" fileName:ImageName mimeType:#"image/jpg" ];
}
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %#", responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
}
A couple of thoughts:
You say:
The iOS client is sending the information of the post via json and after the info is sent, it starts to send the image via multipart form using AFNetworking.
Technically, you're not waiting for the information to be sent, but you're doing these concurrently. Do you want these to be concurrent? Or sequential? Or why not just a single request that posts the information as well as the image?
I'd suggest using AFNetworking for both requests. You've got a powerful framework for managing network requests, and it feels awkward to see hairy NSURLConnection code in there.
If you keep the NSURLConnection code in there, note that you do not want to start a NSURLConnection, unless you used initWithRequest:delegate:startImmediately: with NO for that last parameter. You're effectively starting it twice, which can cause problems. I'd suggest removing the start call.
Setting all of that aside, what you want to do is to add a completion block parameter to your method, e.g., something like:
+ (void)addPostToServerAddtext:(NSString *)text addimage:(UIImage *)image addbeach:(NSString *)beach location:(NSString*)location completion:(void (^)(id responseObject, NSError *error))completion
{
// ...
if (image != nil) {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:[NSString stringWithFormat:#"%#FileUpload",urlBackend] parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:dataImage name:#"image" fileName:ImageName mimeType:#"image/jpg" ];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
if (completion) completion(responseObject, nil);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (completion) completion(nil, error);
}];
}
}
You'd then invoke that like so:
[Persistence addPostToServerAddtext:text addimage:image addbeach:nil location:annotation completion:^(id responseObject, NSError *error) {
if (error) {
// handle error
return
}
// otherwise use the responseObject
}];
Now, I don't know what parameters you want to return in your completion block (I'm assuming you wanted to return what the AFHTTPRequestOperationManager did), but just change the parameters for that completion block as suits your needs.
Unrelated to your original question, but I notice that you're building jsonRequest like so:
NSString *jsonRequest = [NSString stringWithFormat:#"{\"Date\":\"%#\"...."];
That's a little risky if any of those fields include user supplied information (e.g. what if the user used double quotes in the information provided). I'd suggest you build a dictionary, and then build the jsonRequest from that. It will be more robust. Thus:
NSDictionary *dictionary = #{#"Date" : date,
#"Message" : message};
NSError *error = nil;
NSData *request = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error];
if (error)
NSLog(#"%s: dataWithJSONObject error: %#", __FUNCTION__, error);
Or, if you use AFNetworking, I believe it will do this JSON conversion of your dictionary for you. But, bottom line, be very wary about creating JSON strings yourself, at least if the request might include any user supplied information.

Resources