How to call a Asynchronous SOAP web service? - ios

I want to execute my SOAP web service Asynchronously,Because I got some lag in getting data while calling synchronously.Also i was able to get result when calling a single web service when a multiple web service is called in (view did load) or in (view will appear) i was unable to get the data.
Can anyone tell how to call a asynchronous SOAP webService: Here is my code
cws = [[CustomWebService alloc]init];
NSString *soapMessage = [NSString stringWithFormat:#"my soap string"];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(msgCount) name:#"my response name" object:nil];
NSDictionary *Details=[[NSDictionary alloc]initWithObjectsAndKeys:nil];
[cws getSoapAction:#".........." andNameSpace:#"" andDetails:Details andUrlIs:[AppDelegate URLSource] andSoapMessage:soapMessage ];
[cws getPageName:#"my response name"];
NSLog(#"SOAP MESSAGE IS %#",soapMessage);
And I get the response here:
-(void)msgCount
{
[[NSNotificationCenter defaultCenter]removeObserver:self];
NSMutableDictionary *diict=[[NSMutableDictionary alloc]initWithDictionary:[cws msgCount]];
NSLog(#"the response is %#",diict);
}

you can wrap your webservice call in a GCD async block to make the code run asynchronously in the background
dispatch_async(dispatch_get_main_queue(), ^{
//code that should run asynchronously
});

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"UR URL"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setHTTPMethod:#"POST"];
NSString *postString = #"UR KEY1=UR VALUE1"; //for single variable
//OR for Multiple
[request setValue:#"UR VALUE1" forKey:#"UR KEY1"];
[request setValue:#"UR VALUE2" forKey:#"UR KEY2"];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
if (error) {
NSLog(#"Error,%#", [error localizedDescription]);
} else {
NSLog(#"%#", [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
}
}];

Related

how to send the values in body when I call the asynchronous post request

I am trying to do a task which I am completely not aware of, that is video uploading to server in objective c. I am a beginner and I was using swift, but now my requirement is in objective c.
Here I have to send an asynchronous request using multipart form data to server with three values. here is the data need to send in body:
body->form-data
projectId : String
sessionId : String
file : file
Its getting crashed at this line
" [urlRequest addValue:#"65" forHTTPHeaderField:#"projectId"];"
Can anyone help me to do this.
Thanks in advance.
NSString *str = [NSString stringWithFormat:#"http://abcdefghijkl.mnopqrst.com:8965/upload"];
NSURL *url = [NSURL URLWithString:str];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[urlRequest addValue:#"65" forHTTPHeaderField:#"projectId"];
[urlRequest addValue:#"43" forHTTPHeaderField:#"sessionId"];
[urlRequest addValue:#"" forHTTPHeaderField:#"file"];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (error) {
NSLog(#"Error,%#", [error localizedDescription]);
} else {
NSLog(#"%#", [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
}
}];
You should use NSMutableURLRequest
NSMutableURLRequest is a subclass of NSURLRequest that allows you to
change the request’s properties.
NSMutableURLRequest *mutableRequest = [request mutableCopy];
[mutableRequest addValue:#"65" forHTTPHeaderField:#"projectId"];
...
request = [mutableRequest copy];

how to make asynchronous Mutable request and getting only last request value and canceling all request before last request

NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSOperationQueue *downloadOperationQueue = [[NSOperationQueue alloc] init];
[downloadOperationQueue cancelAllOperations];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:Url]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:jsonData];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
NSLog(#"Respose %#",response.URL);
NSString *jsonInString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"json in string for backend: %#",jsonInString);
[self.delegate responseConnection:data withMethodName:methodName];
if (!error)
{
// did finish logic here, then tell the caller you are done with success
// completion(YES, nil);
}
else
{
// otherwise, you are done with an error
// completion(NO, error);
}
}];
For NSURLSession:
You can use [NSURLSession cancelPreviousPerformRequestsWithTarget:self];
For NSURLConnection also
You can use [NSURLConnection cancelPreviousPerformRequestsWithTarget:self];

NSOperationQueue run same task again on response iOS

In my project I need to send data to server, for that I've used the following code to achieve the task:
- (void)sendJSONToServer:(NSString *) jsonString
{
// Create a new NSOperationQueue instance.
operationQueue = [NSOperationQueue new];
//
// Create a new NSOperation object using the NSInvocationOperation subclass to run the operationQueueTask method
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:#selector(operationQueueTask:)
object:jsonString];
// Add the operation to the queue and let it to be executed.
[operationQueue addOperation:operation];
}//End of sendJSONToServer method
-(void) operationQueueTask:(NSString *) jsonString
{
//NSOperationQueue *remoteResultQueue = [[NSOperationQueue alloc] init];
dispatch_queue_t myQueue = dispatch_queue_create("SERVER_QUEUE",NULL);
dispatch_async(myQueue, ^{
// Performing long running process
// Sending json data to server asynchronously
NSData *postData = [jsonString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[jsonString length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"MY_URL_eg_http://www.example.com"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
[NSURLConnection sendAsynchronousRequest:request queue:operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
NSLog(#"Response is:%#",[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
}];
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
NSLog(#"Thread Process Finished");
});
});
}//End of operationQueueTask method
By the above code I'm able to send data and get response.
But when there is no internet the data will not be sent to server. How to handle this situation based on the response we get.
Let's say we get response success on fair condition ans false on worst condition.
UPDATED CODE FOR RETRIES
-(id)init
{
self = [super init];
if (self != nil)
{
//initialize stuffs here
pendingOperationQueue = [[NSMutableArray alloc] init];
operationQueue = [NSOperationQueue new];
}
return self;
}//End of init method
- (void)sendJSONToServer:(NSString *) jsonString
{
NSOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:#selector(operationQueueTask:) object:[NSString stringWithString:[pendingOperationQueue objectAtIndex:0]]];
[operation start];
}//End of sendJSONToServer method
-(void) operationQueueTask:(NSString *) jsonString
{
//NSOperationQueue *remoteResultQueue = [[NSOperationQueue alloc] init];
dispatch_queue_t myQueue = dispatch_queue_create("SERVER_QUEUE",NULL);
dispatch_async(myQueue, ^{
// Performing long running process
// Sending json data to server asynchronously
NSData *postData = [jsonString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[jsonString length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"MY_URL_http://www/example.com"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
[NSURLConnection sendAsynchronousRequest:request queue:operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
NSLog(#"Response is:%#",[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
if([[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] rangeOfString:#"true"].location == NSNotFound)
{
// Add the operation to the queue and let it to be executed.
NSLog(#"Failed To Add To Server, Rerunning the task");
}
else
{
NSLog(#"Successfully Added To Server");
NSLog(#"ADDED_DATA_TO_SERVER: %#", jsonString);
if([pendingOperationQueue count] > 0)
{
[pendingOperationQueue removeObjectAtIndex:0];
if([pendingOperationQueue count] > 0)
{
NSOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:#selector(operationQueueTask:) object:[NSString stringWithString:[pendingOperationQueue objectAtIndex:0]]];
[operation start];
}
}
}
}];
});
}//End of operationQueueTask method
Heads up! This is a long answer. TL;DR: You can't re-run an NSOperation, but you can design your classes and methods to make it easy to retry requests.
First a quick answer to your title question: you can't re-run an NSOperation, they're not designed to do that. From the docs:
An operation object is a single-shot object — that is, it executes its
task once and cannot be used to execute it again.
With that out of the way, lets take a look at what you're currently doing and clean it up a bit so that re-using it is easier. There's a ton of async stuff going on in there that you don't need; I'll go through it piece by piece.
Let's start with your operationQueueTask: method. The first thing you do in the method is:
dispatch_queue_t myQueue = dispatch_queue_create("SERVER_QUEUE",NULL);
That means that every time that method is called, you're creating a new dispatch queue. While you can do that if you really want to, that's not what dispatch queues are really designed for. A better idea would be to use one of the background queues that are already available:
dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
Next you are dispatching a block asynchronously to that queue. That block:
Sets up your NSMutableURLRequest.
Calls [NSURLConnection sendAsynchronousRequest:...].
Dispatches another block (which has a comment in it about updating the UI) to the main queue.
1 and 2 are fine, I don't see anything you need to change there. 3, however, is problematic because of where that dispatch is being called. The way you have it setup now, NSURLConnection will fire off its asynchronous request and then, before that even has a chance to run, you fire off the block to the main queue to update the UI. What you need to do instead is fire off that block in the completion handler passed to [NSURLConnection sendAsynchronousRequest:...]. Like so:
[NSURLConnection sendAsynchronousRequest:request queue:operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
NSLog(#"Response is:%#",[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
NSLog(#"Thread Process Finished");
});
}];
Now, notice the name of the method you're calling on NSURLConnection? sendAsynchronousRequest:. It actually handles queuing the request on a background queue for you. Which mean, you don't actually need (or want) all the dispatch_* stuff at the beginning of this method. With that in mind, we can reduce it down to:
-(void) operationQueueTask:(NSString *) jsonString
{
NSData *postData = [jsonString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[jsonString length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"MY_URL_eg_http://www.example.com"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
[NSURLConnection sendAsynchronousRequest:request queue:operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
NSLog(#"Response is:%#",[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
NSLog(#"Thread Process Finished");
});
}];
} //End of operationQueueTask method
Now, on to your sendJSONToServer: method. You're doing a similar thing here that you did at the start of operationQueueTask:: you're creating a new NSOperationQueue each time it runs; that's also not needed (nor typically wanted). What you should probably be doing is creating that operationQueue when your class is initialized (it looks like it's already an instance variable on your class, so you're good there):
// NOTE: I'm just using a default initializer here; if you already have an initializer, use that instead
- (instancetype)init {
if (self = [super init]) {
operationQueue = [NSOperationQueue new];
}
return self;
}
That gets rid of your first line. Next, you're creating an NSInvocationOperation which calls operationQueueTask: and then adding it to your operationQueue. Since you've been re-creating your operationQueue every time, I'm going to assume that it isn't used for anything other than these server requests. In that case, you actually don't need to do this on your operationQueue at all because, as we discovered in the previous method, NSURLConnection is already handling all the background threading for you. In that case, we can actually just copy the code from operationQueueTask: to sendJSONToServer: and get rid of operationQueueTask: altogether. That makes it look like:
- (void)sendJSONToServer:(NSString*)jsonString {
NSData *postData = [jsonString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[jsonString length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"MY_URL_eg_http://www.example.com"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
[NSURLConnection sendAsynchronousRequest:request queue:operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
NSLog(#"Response is:%#",[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
NSLog(#"Thread Process Finished");
});
}];
}
Note: We still need to keep operationQueue around since we pass it to [NSURLConnection sendAsynchronousRequest:... as the queue that it should run on.
So, how do we go about retrying the request when it fails? The simplest method is to add a recursive function that calls itself when the request fails. You'll pass this method the jsonString you want to send and the maximum number of times it should try to send it before it gives up for good.
To facilitate that, lets make one more change to you existing function: instead of handling the completion block inside the function, lets make the completion block a parameter you pass to the function so that it can be processed elsewhere.
- (void)sendJSONToServer:(NSString*)jsonString withCompletionHandler:(void (^)(NSURLResponse *response, NSData *data, NSError *connectionError))completionHandler {
NSData *postData = [jsonString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[jsonString length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"MY_URL_eg_http://www.example.com"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
[NSURLConnection sendAsynchronousRequest:request queue:operationQueue completionHandler:completionHandler];
}
Now, lets build that recursive function. I'll call it:
- (void)sendJSONToServer:(NSString*)jsonString withRetryAttempts:(NSUInteger)retryTimes;
The basic flow will be:
Check if retryTimes is greater than 0
If it is, attempt to send the request to the server
When the request finishes, check the response for success
If successful, update the UI on the main queue
If not successful, subtract one from retryTimes and call this function again
That looks something like:
- (void)sendJSONToServer:(NSString*)jsonString withRetryAttempts:(NSUInteger)retryTimes {
if (retryTimes > 0) {
[self sendJSONToServer:jsonString withCompletionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSLog(#"Response is:%#",[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
if (/* check response to make sure it succeeded */) {
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
NSLog(#"Thread Process Finished");
});
} else {
// Note: you can add a dispatch_after here (or something similar) to wait before the next attempt
// You could also add exponential backoff here, which is usually good when retrying network stuff
[self sendJSONToServer:jsonString withRetryAttempts:(retryTimes - 1)];
}
}];
} else {
// We're out of retries; handle appropriately
}
}
Note: There are some bits in there that are just comments because they are application specific; they'll need to be implemented before that code will compile/run.
Now, instead of calling [yourClass sendJSONToServer:jsonString], call: [yourClass sendJSONToServer:jsonString withRetryTimes:maxRetries] and, if the request fails, it should retry up to maxRetries times.
One last note: As #Deftsoft mentioned, Apple's Reachability classes are a nice way to know if you have an active connection to the network or not. It's a good idea to check that first before trying to call sendJSONToServer:withRetryTimes:. That way you're not trying to make requests when it's not possible to even connect in the first place.
You can Apple reachability classes below is the reference code which will provide you the better idea.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(networkChanged:) name:kReachabilityChangedNotification object:nil];
reachability = [Reachability reachabilityForInternetConnection];
[reachability startNotifier];
- (void)networkChanged:(NSNotification *)notification
{
NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];
if(remoteHostStatus == NotReachable) { NSLog(#"not reachable");}
else if (remoteHostStatus == ReachableViaWiFiNetwork) { NSLog(#"wifi"); }
else if (remoteHostStatus == ReachableViaCarrierDataNetwork) { NSLog(#"carrier"); }
}

An asynchronous nsurlconnection in a popup view in ios7

I am creating an asynchronous NSURLconnection in a popup view in ios.
To implement the asynchronous NSURLconnection I implement the methods of the NSURLDelegate.
The problem occurs when the user taps outside the popup view and the view is dismissed.
leaving the nsurlconnection callbacks and other actions inside the view incomplete.
How can I assure that the actions inside the popup complete inspite of the dismissal of the view?
I tried putting an activity indicator inside the popup view till the actions are completed, but even then a tap outside the popup view dismisses the view.
I dont want the user to be left with an inactive app till actions are completed, instead I want the actions to be completed in the background.
If you want to send an asynchronous connection you can use this methods.
GET REQUEST
-(void)placeGetRequest:(NSString *)action withHandler:(void (^)(NSURLResponse *response, NSData *data, NSError *error))ourBlock {
NSString *url = [NSString stringWithFormat:#"%#/%#", URL_API, action];
NSURL *urlUsers = [NSURL URLWithString:url];
NSURLRequest *request = [NSURLRequest requestWithURL:urlUsers];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:ourBlock];
}
POST REQUEST
-(void)placePostRequest:(NSString *)action withData:(NSDictionary *)dataToSend withHandler:(void (^)(NSURLResponse *response, NSData *data, NSError *error))ourBlock {
NSString *urlString = [NSString stringWithFormat:#"%#/%#", URL_API, action];
NSLog(urlString);
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// Creamos el JSON desde el data
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dataToSend options:0 error:&error];
NSString *jsonString;
if (! jsonData) {
NSLog(#"Got an error: %#", error);
} else {
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSData *requestData = [NSData dataWithBytes:[jsonString UTF8String] length:[jsonString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
[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 sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:ourBlock];
}
}
EXAMPLE OF USE
- (void) getMyMethod:(NSString *)myParam1
myParam2:(NSString *)myParam2
myParam3:(NSString *)myParam3
calledBy:(id)calledBy
withSuccess:(SEL)successCallback
andFailure:(SEL)failureCallback{
[self placeGetRequest:[NSString stringWithFormat:#"api/myMethod?myParam1=%#&myParam2=%#&myParam3=%#",myParam1, myParam2, myParam3]
withHandler:^(NSURLResponse *response, NSData *rawData, NSError *error) {
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
NSInteger code = [httpResponse statusCode];
NSLog(#"%ld", (long)code);
if (code == 0){
// error
} else if (!(code >= 200 && code < 300) && !(code == 500)) {
NSString *string = [[NSString alloc] initWithData:rawData
encoding:NSUTF8StringEncoding];
NSLog(#"ERROR (%ld): %#", (long)code, string);
[calledBy performSelector:failureCallback withObject:string];
} else {
// If you receive a JSON
NSMutableDictionary *result = [NSJSONSerialization JSONObjectWithData:rawData options:0 error:nil];
// If you receive an Array
// NSArray *result = [NSJSONSerialization JSONObjectWithData:rawData options:0 error:nil];
// If you receive a string
// NSString *result = [[NSString alloc] initWithData:rawData encoding:NSUTF8StringEncoding];
[calledBy performSelector:successCallback withObject:result];
}
}];
}
CALL YOU MUST DO IN YOUR VIEW/CONTROLLER/ETC
(...)
[api getMyMethod:myParam1Value myParam2:myParam2Value myParam3:myParam3Value calledBy:self withSuccess:#selector(getMyMethodDidEnd:) andFailure:#selector(getMyMethodFailureFailure:)];
(...)
// Don't forget to set your callbacks functions or callbacks will do your app crash
-(void)getMyMethodDidEnd:(id)result{
// your actions with the result
// ...
}
-(void)getMyMethodFailure:(id)result{
// your actions with the result
// ...
}
To prevent the dismissal of popup view when tapping out side u need to implement this delegate method
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
return NO;
}
dismiss it by using the action
- (void)someAction
{
//check the operations are completed
.....
.....
[popoverController dismissPopoverAnimated:YES];
}

Difference between Post & Get method in Json Parsing in ios

I implement the JSON Parsing as follow:
-(void)getallEvent
{
SBJSON *json = [SBJSON new];
json.humanReadable = YES;
responseData = [[NSMutableData data] retain];
NSString *service = #"/GetAllVenue";
NSString *str;
str = #"Calagary";
NSString *requestString = [NSString stringWithFormat:#"{\"CityName\":\"%#\"}",str];
//NSLog(#"request string:%#",requestString);
// NSString *requestString = [NSString stringWithFormat:#"{\"GetAllEventsDetails\":\"%#\"}",service];
NSData *requestData = [NSData dataWithBytes: [requestString UTF8String] length: [requestString length]];
NSString *fileLoc = [[NSBundle mainBundle] pathForResource:#"URLName" ofType:#"plist"];
NSDictionary *fileContents = [[NSDictionary alloc] initWithContentsOfFile:fileLoc];
NSString *urlLoc = [fileContents objectForKey:#"URL"];
urlLoc = [urlLoc stringByAppendingString:service];
//NSLog(#"URL : %#",urlLoc);
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: urlLoc]];
NSString *postLength = [NSString stringWithFormat:#"%d", [requestData length]];
[request setHTTPMethod: #"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody: requestData];
// self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
NSError *respError = nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: &respError ];
if (respError)
{
NSString *msg = [NSString stringWithFormat:#"Connection failed! Error - %# %#",
[respError localizedDescription],
[[respError userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Check your network connection" message:msg delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
[alertView release];
}
else
{
NSString *responseString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];
NSDictionary *results = [[responseString JSONValue] retain];
//NSLog(#" %#",results);
NSString *extractUsers = [[results objectForKey:#"d"] retain];
NSDictionary *finalResult = [[extractUsers JSONValue] retain];
NSLog(#"Final Results : %#",finalResult);
listOfEvents = [finalResult objectForKey:#"List of Event details of given Venue"];
}
Using this code, it slow down the app. How can I parse the json in background?
*Is this right for Post Method? what is the difference between Post & Get Method?*
Is there any other way to json parsing?
You are using synchronous request which is executed on Main thread so if you need to do it in background use asynchronous loading.
POST METHOD:
The POST method generates a FORM collection, which is sent as a HTTP request body. All the values typed in the form will be stored in the FORM collection.
GET METHOD: The GET method sends information by appending it to the URL (with a question mark) and stored as A Querystring collection. The Querystring collection is passed to the server as name/value pair. The length of the URL should be less than 255 characters.
An HTTP GET is a request from the client to the server, asking for a resource.
An HTTP POST is an upload of data (form information, image data, whatever) from the client to the server.
Check this answer for more details : what-is-the-difference-between-post-and-get
You are making synchronous communication request which slows down the application. You should make the asynchronous request to keep your app responsive.
It is not having any concern with parsing JSON data.
I would recommend using AFNetworking in your context which will simplify the connection management, background queue execution and parsing of the JSON you are getting back form the server.
The code example below will create an HTTP client with a base URL (<hostname>) and get a JSON payload from a given path. The network request runs in the background and runs a given block when completing
httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
// set the type to JSON
[httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
[httpClient setDefaultHeader:#"Accept" value:#"application/json"];
[httpClient setParameterEncoding:AFJSONParameterEncoding];
// Activate newtork indicator
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
// Request the <path> from the server and parse the response to JSON
// this calls a GET method to <hostname>/<path>
[httpClient getPath:<your path> parameters:Nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
// responseObject is a JSON object here
//
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// handle error
}];
Get: With the get method the value is send through the query string appended with the url. So you can see the the name, value, description on the addressbar when the page display in the browser.
Post: This method transfer the information through the complete form. You can not see the detail description on the addresss bar. When the page display.
NSString *myUrlString =[NSString stringWithFormat: #"your url];
NSString *postdata=[NSString stringWithFormat:#"emailId=%#&password=%#,username,password];
NSLog(#"%#",postdata);
//create a NSURL object from the string data
NSURL *myUrl = [NSURL URLWithString:myUrlString];
//create a mutable HTTP request
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:myUrl];
//sets the receiver’s timeout interval, in seconds
[urlRequest setTimeoutInterval:30.0f];
//sets the receiver’s HTTP request method
[urlRequest setHTTPMethod:#"POST"];
//sets the request body of the receiver to the specified data.
[urlRequest setHTTPBody:[postdata dataUsingEncoding:NSUTF8StringEncoding]];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//Loads the data for a URL request and executes a handler block on an
//operation queue when the request completes or fails.
[NSURLConnection
sendAsynchronousRequest:urlRequest
queue:queue
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *error) {
if ([data length] >0 && error == nil){
//process the JSON response
//use the main queue so that we can interact with the screen
dispatch_sync(dispatch_get_main_queue(), ^{
[self parseResponse:data];
});
}
else if ([data length] == 0 && error == nil){
NSLog(#"Empty Response, not sure why?");
}
else if (error != nil){
NSLog(#"Not again, what is the error = %#", error);
}
}];
}
- (void) parseResponse:(NSData *) data
{
responseData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"JSON = %#", responseData);
NSLog(#"Response ==> %#", responseData;
Finally u get the response from that specific url .and what ever u wanted to it do ur own way.

Resources