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];
Related
Actually i have json parameter
[dictionary setObject:_dateOfBirth.text forKey:#"birth_date"];
[dictionary setObject:_tfCountry.text forKey:#"country"];
[dictionary setObject:_tfEmail.text forKey:#"email"];
[dictionary setObject:#"" forKey:#"fromLogin"];
[dictionary setObject:#1 forKey:#"gender"];
[dictionary setObject:#"signup" forKey:#"methodName"];
[dictionary setObject:_tfContact.text forKey:#"mobile"];
[dictionary setObject:_tfName.text forKey:#"name"];
[dictionary setObject:_tfNickName.text forKey:#"nickname"];
[dictionary setObject:_tfPassword.text forKey:#"password"];
[dictionary setObject:_tfPinCode.text forKey:#"pincode"];
There Is also a Image that i have to set profile_pic as a Key.
Now I have Converted all Parameter as a data and POst That Data lie This
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:kNilOptions error:nil];
// this is your service request url
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://proteen2.inexture.com/webservice"]];
// set the content as format
[request setHTTPMethod:#"POST"];
[request setHTTPBody: jsonData];
// this is your response type
[request setValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"content-type"];
NSError *err;
NSURLResponse *response;
// send the synchronous connection
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
// here add your server response NSJSONSerialization
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:responseData options: NSJSONReadingMutableContainers error: &err];
It's Works fine for Text, Now how to attach Image to that Parameter, I am only aware with Multi Part but not getting that Point. Please Help
You need to manage many thing here, like set boundry append image data etc etc.
You should use AFNetworking to make is very simple. Download from github and just drag and drop library to your project and import AFNetworking.h in your class and then you can do something like,
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer]multipartFormRequestWithMethod:#"POST" URLString:#"urlstring" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
//Append image here for example;
UIImage *img = tempImageView.image;
NSData *imgData = UIImageJPEGRepresentation(img, 0.5);
[formData appendPartWithFileData:imgData name:#"imagename/serversideparameter" fileName:#"imagename" mimeType:#"image/jpeg"];
} error:nil];
//Send this request to server. Something like,
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc]initWithSessionConfiguration:configuration];
[[manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (!error) {
NSLog(#"success!!");
NSLog(#"here is the response : %#",responseObject);
}
else{
NSLog(#"Error Occured : %#",error.localizedDescription);
}
}]resume];
You shouldn't use NSUrlConnection because it is deprecated now. It's better to use NSUrlSession which i have used in answer via AFNetworking.
If you don't want to use AFNetworking then refer this stackoverflow post. It have great explanation step by step in answer.
I have been stuck for almost a week now, I want to write to a SharePoint list, usin the rest api they provide. The api looks like this, http://site/_api/lists, and from here I can read and write depending on what I append to my url, I can read from the lists without any issues, but I have issues when I have to write.
I am supposed to send in Content-Type, Accept, X-requestDigest headers, and post body when I write to list. My code
NSString *deviceToken = [self getDeviceTokenFromCoreData];
NSString *postData = [NSString stringWithFormat:#"{ \"__metadata\": { \"type\": \"SP.Data.TestListItem\" }, \"Title\": \"Test Title\" }"];
NSData *methodBodyData = [postData dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSData *jsonString = [NSJSONSerialization JSONObjectWithData:methodBodyData options:0 error:&error];
NSString *acceptType = #"application/json;data=verbose";
NSString *requestDigest = _requestDigest;
NSURL *subscribeURL = [[NSURL alloc] initWithString:subscribeUrlString];
NSMutableURLRequest *theRequest = [[NSMutableURLRequest alloc] initWithURL:subscribeURL];
[theRequest setHTTPMethod:#"POST"];
[theRequest setHTTPBody:jsonString];
[theRequest setValue:acceptType forHTTPHeaderField:#"Accept"];
[theRequest setValue:acceptType forHTTPHeaderField:#"Content-Type"];
[theRequest setValue:requestDigest forHTTPHeaderField:#"X-RequestDigest"];
This is where I construct my headers for the request. And this is how I handle the sending of the request
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:theRequest];
[operation setWillSendRequestForAuthenticationChallengeBlock:^(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge) {
// if (challenge.previousFailureCount == 0) {
NSLog(#"%#", challenge.protectionSpace);
NSURLCredential *creds = [NSURLCredential credentialWithUser:userName
password:userPass
persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:creds forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
//Handle Success
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//Handle failure
}];
[operation start];
}
This happens after I have authenticated to sharepoint, I have noticed during debugging the setWillSendRequestForAuthenticationChallengeBlock never gets called again, looks like I need to send the authentication information via the headers now, which is what I think the request digest is for, but that doesnt help cause I still don't get through.
Error message I get from server is
<?xml version="1.0" encoding="utf-8"?>
<m:error
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<m:code>-2130575251, Microsoft.SharePoint.SPException</m:code>
<m:message xml:lang="en-US">The security validation for this page is invalid and might be corrupted. Please use your web browser's Back button to try your operation again.</m:message>
</m:error>
Thanks in advance :)
I can't find any answer for this in internet. I solved in a non recommended way. I made a requisition using GET method to a page in the sharepoint application. In the return, i have a tag with the request digest value.
I used this in this way, in my POST requisition:
[headers setValue:#"0x175481C0D6D79A7534A0992E528A5B7D36C80C41C01CBEE55EFB256FA99E1EF551F755BAAE07E692ADE757290F1ACCA11B560F71338DE4AA7781ADC90CDC5249,11 Jun 2015 18:22:18 -0000" forKey:#"X-RequestDigest"];
I am super new to coding so there is most likely a better way but this is how I solved this issue:
Write a method that retrieves the Request Digest from the site that looks like this:
-(NSDictionary *)digestValue
{
NSURL *url = [NSURL URLWithString:#"https://.../sites/_api/contextinfo"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSArray* cookieArray = [NSArray arrayWithObjects: rtFaCookie, fedAuthCookie, nil];
NSDictionary * cookieHeaders = [NSHTTPCookie requestHeaderFieldsWithCookies:cookieArray];
NSMutableDictionary * requestHeaders = [[NSMutableDictionary alloc] initWithDictionary: cookieHeaders];
[requestHeaders setObject: #"application/json;odata=nometadata" forKey: #"Accept"];
[requestHeaders setObject:#"application/json;odata=verbose" forKey:#"Content-Type"];
[theRequest setHTTPMethod:#"POST"];
[theRequest setValue:#"2" forHTTPHeaderField:#"Content-Length"];
[theRequest setAllHTTPHeaderFields:requestHeaders];
NSURLResponse *response;
NSError *error;
NSData *data = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&error];
if (data) {
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return [jsonString JSONValue];
}
return nil;
}
Then call that method when you need a valid Request Digest with something like this:
//Method Pulls the most current Digest Value from SharePoint, and pulls out just the Form Digest Value Key.
NSDictionary * taskMetas = [self digestValue];
NSString *formDigestValue = [taskMetas objectForKey:#"FormDigestValue"];
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;
}
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.
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.