How to convert json format - ios

How to remove \ and \n. This two is characters is coming.
{
PageNumber = 1;
businessCode = "{\n \"businessCode\" : \"[]\"\n}";
businessName = "";
categoryKeyword = "Ladies Traditional Wear Pagenumber";
languageCode = en;
location = "";
paginationSize = 5;
}

May be below answer is helpful for you.Follow this
//just give your URL instead of my URL
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"Your URL"]];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"content-type"];
NSError *err;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
//You need to check response.Once you get the response copy that and paste in ONLINE JSON VIEWER.If you do this clearly you can get the correct results.
//After that it depends upon the json format whether it is DICTIONARY or ARRAY
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:responseData options: NSJSONReadingMutableContainers error: &err];
From above code,you can get the correct format of JSON.Try this one.

NSMutableCharacterSet *charactersToRemove = [NSMutableCharacterSet new];
[charactersToRemove addCharactersInString:#"\n"];
[charactersToRemove addCharactersInString:#"\\"]; //This respresent obly one backslash, In Objective-c you have to support it with another slash
[jsonString stringByTrimmingCharactersInSet:charactersToRemove];

Related

Post request with raw body using NSURLSession

I have stuck here. Below is my code for Post request with raw body using NSURLSession. I got response = NULL and no error.
NSString* stringRequest = #"https://chocudan.com/api/shops/by_ids";
NSURL* urlRequest = [NSURL URLWithString:stringRequest];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:urlRequest];
request.HTTPMethod = #"POST";
NSString* bodyRequest = #"563c268b84ba489c4729f149";
//I have to tried a base64 convert here but still not work.
//request.HTTPBody = [NSData base64DataFromString:bodyRequest];
request.HTTPBody = [bodyRequest dataUsingEncoding:NSUTF8StringEncoding];
NSURLSessionConfiguration* configureSession = [NSURLSessionConfiguration defaultSessionConfiguration];
configureSession.HTTPAdditionalHeaders = #{#"Content-Type" : #"application/json charset=utf-8",
#"Content-Lenght" : #"180"};
NSURLSession* session = [NSURLSession sessionWithConfiguration:configureSession];
NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSHTTPURLResponse* respHttp = (NSHTTPURLResponse*) response;
if (!error && respHttp.statusCode == 200) {
NSDictionary* respondData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSLog(#"%#", respondData);
}else{
NSLog(#"%#", error);
}
}];
[dataTask resume];
I have to try with postman and everything work fine. This is pictures.
Thank in advance.
Try changing it too
NSArray* bodyArray = #[#"563c268b84ba489c4729f149"]
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:bodyArray
options:NSJSONWritingPrettyPrinted error:&error];
request.HTTPBody = jsonData;
My raw data was like :
{
"email":"test#gmail.com",
"password":"12345678"
}
and what I did is :
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:#"test#gmail.com" forKey:#"email"];
[dict setValue:#"12345678" forKey:#"password"];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict
options:NSJSONWritingPrettyPrinted error:&error];
request.HTTPBody = jsonData;
This fixed it for me:
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.HTTPAdditionalHeaders = ["Content-Type" : "text/plain"]
I guess that it was not data that was null but respondData was null?
That is because your service sends an Array with exactly one Object. JSONSerialisation creates an NSArray from that with one NSDictionary in it. The dictionary has the keys _id, contact and so on.
So it is
NSArray* respondData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
BTW
NSHTTPURLResponse* respHttp = (NSHTTPURLResponse*) response;
does not make much of a sense but does not harm either.
With respect to the body of your request, see mihir's answer. He is just right.
It may help you understanding mihir's point when you do this:
NSString* bodyRequest = #"[563c268b84ba489c4729f149]";
However, this is rather quick & dirty but may help you understanding the principles. Once understood you will certainly follow mihir's suggestion.
If you want to post raw, and param is a format of NSString, you only need to do this:
NSData *param_data = [encry_str dataUsingEncoding:NSUTF8StringEncoding];
murequest.HTTPBody = param_data;
If we can’t get anything from that response, notice that the response serializer is correct. Any additional settings, please deal it with server.

IOS: Dictionary Return null value/Data

in my project i am using JSON parsing to display data for this i created 2 NSDictionary dictionary 1 return success response but when i call it in second dictionary it return Null value.
i am sharing my code please help me to correct it
-(void)hdata
{
NSString *post = [NSString stringWithFormat:#"data[Users][ref_id]=%#&api_key=bf45c093e542f057c123ae7d6",refidstr];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"http://192.168.0.20/hspCh/api/user_diagnose_list"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSURLResponse *response;
NSError *err;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
[request setHTTPBody:postData];
NSString *str=[[NSString alloc]initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"str : %#",str);
NSDictionary *dict6 = [self cleanJsonToObject:responseData];
NSLog(#"str : %#",dict6); <=======it gives correct responce
diagnosisdict = [dict6 objectForKey:#"data[Users][ref_id]"];
[diagnosisdict setValue:refidstr forKey:#"data[Users][ref_id]"];
NSLog(#" for ref id =%# , data is= %#",refidstr, diagnosisdict); <======Gives null responce
}
Output of the above in console is as follows
2015-12-09 10:34:16.935 HcH[2841:32315] str : {"response":200,"diagnoses":[{"DiagnosesHospitals":{"hospital_id":"3341","id":"163075","discharges":"100.00","charge_amt":"1200.00","total_amt":"1500.00","medicare_amt":"1200.00"},"Diagnoses":{"diagnosis_name":"TRANSIENT ISCHEMIA"}}]}
2015-12-09 10:34:16.935 HcH[2841:32315] str : {
diagnoses = (
{
Diagnoses = {
"diagnosis_name" = "TRANSIENT ISCHEMIA";
};
DiagnosesHospitals = {
"charge_amt" = "1200.00";
discharges = "100.00";
"hospital_id" = 3341;
id = 163075;
"medicare_amt" = "1200.00";
"total_amt" = "1500.00";
};
}
);
response = 200;
}
2015-12-09 10:34:16.936 HcH[2841:32315] for ref id =3341 , data is= (null)
Replace this
diagnosisdict = [dict6 objectForKey:#"data[Users][ref_id]"];
with
diagnosisdict = [[[dict6 objectForKey:#"diagnoses"] objectAtIndex:0] objectForKey:#"DiagnosesHospitals"];
There is no entry in dict6 for "data[Users][ref_id]".
Using that string as a key is completely nonsensical, by the way. A key in this context is just a string, not a series of accesses in dictionaries.
It seems like what you want is dict6[#"data"][#"Users"][#"ref_id"].
However, this will also fail, because there is no entry for "data" in dict6.
It is possible that your cleanJSONToObject: method is stripping out the value of the "data" key. However, based on your statement that printing the value of dict6 gives the correct response, I assume that what you actually want to access is the value of "id" in "DiagnosesHospitals", since it sounds the most like a "ref_id".
Based on the output of the debugger, it seems as though you have a dictionary (dict6) with a "diagnoses" key pointing to an array with two dictionaries.
So, You would access the "id" field with dict6[diagnoses][0][#"DiagnosesHospitals"][#"id"], assuming that "id" is a string (I'm not sure why it has no quotes around it).
Somethings that you can get:
NSDictionary * diagnoses = dict6[#"diagnoses"];
NSString * diagnosis_name = diagnoses[0][#"Diagnoses"][#"diagnosis_name"];
NSDictionary * diagnosisdict = diagnoses[0][#"DiagnosesHospitals"];
NSString * hospital_id = diagnosisdict[#"hospital_id"];

How to get cookie from a url in iOS?

I have an application where I have to create session using a URL and need to get cookie from that URL and pass the cookie to webview so that it won't ask for any username and password.
For that I am using this code:
- (void)getcookie {
NSURL* aUrl =
[NSURL URLWithString:#"https://www.sessioncheck.com/session/create"];
NSMutableURLRequest* request =
[NSMutableURLRequest requestWithURL:aUrl
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:30.0];
NSString* email = #"tina#gmail.com";
NSString* password = #"abcde#123";
NSString* combinedString =
[NSString stringWithFormat:#"%#:%#", email, password];
NSString* base64encodedstring =
[NSString stringWithBase64EncodedString:combinedString];
NSData* base64data = [NSData dataWithBase64EncodedString:combinedString];
[request addValue:[NSString stringWithFormat:#"Basic %#", base64encodedstring]
forHTTPHeaderField:#"Authorization"];
[request setHTTPMethod:#"GET"];
NSError* error = nil;
NSData* returnData = [NSURLConnection sendSynchronousRequest:request
returningResponse:nil
error:&error];
if (returnData != nil) {
NSDictionary* JSONDictionary =
[NSJSONSerialization JSONObjectWithData:returnData
options:kNilOptions
error:&error];
}
}
This is my Android code. I am able to get cookie in Android:
HttpGet get;
try {
get = new HttpGet(
new URI("https://www.sessioncheck.com/session/create"));
byte[] encodedBytes = Base64.encodeBase64((email+":"+password).getBytes());
//System.out.println("encodedBytes " + new String(encodedBytes));
get.setHeader("Authorization", "Basic " + new String(encodedBytes));
http.execute(get);
List<Cookie> cookies = ((DefaultHttpClient)http).getCookieStore().getCookies();
for (int i = 0; i < cookies.size(); i++) {
cookie = cookies.get(i);
}
String cookieString = cookie.getName() + "=" + cookie.getValue();
signedin.storeCookie("cookie", cookieString);
}
I am trying to get the base64encoded string from my combinedString(username:password) but the problem is my base64encodedstring is returning nil.
Did you use this code: https://github.com/nicklockwood/Base64 ?
If you did then you should use - (NSString *)base64EncodedString; instead.
So your code should look like this:
NSString* base64encodedstring = [combinedString base64EncodedString];
NSData* base64data = [base64encodedstring dataUsingEncoding:NSUTF8StringEncoding];
About cookies, you can get them from "returningResponse" outgoing parameter of -[NSURLConnection sendSynchronousRequest:returningResponse:error:].
You should pass an address of a NSHTTPURLResponse pointer into it.
So your code should be like this:
NSHTTPURLResponse *res = nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&res
error:&error];
NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:[res allHeaderFields]
forURL:aUrl];
EDIT : As you requested, to set cookies into a NSMutableURLRequest, you have to use the NSArray *cookies from above. Here is the code:
// Use the cookies from the code above
NSDictionary *headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:newURL];
[req setAllHTTPHeaderFields:headers];
// Do your other setups here...

How to parse JSONP in Objective-C?

I am retrieving JSON information for an API and it says on the API that it is in JSON but I noticed it is in JSONP or "json with padding" as some call it. I tired to look everywhere to find how to parse this but no luck. The information I am trying to receive is this:
({"book":[{"book_name":"James","book_nr":"59","chapter_nr":"3","chapter":
{"16":{"verse_nr":"16","verse":"For where envying and strife is, there is confusion and
every evil work."}}}],"direction":"LTR","type":"verse"});
The link to the data is https://getbible.net/json?p=James3:16, so you can look at it directly.
This is the code I am using to try to retrieve the JSON Data and parse it into a NSMutableDictionary.
-(void)fetchJson {
NSString *currentURL = [NSString stringWithFormat:#"https://getbible.net/json?p=James"];
NSURL *url = [NSURL URLWithString:currentURL];
NSData *data = [[NSData alloc]initWithContentsOfURL:url];
NSURLRequest *theRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
NSMutableData *receivedData = [[NSMutableData alloc] initWithLength:0];
NSURLConnection * connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];
[receivedData setLength:0];
NSURLResponse *response = [[NSURLResponse alloc] initWithURL:url MIMEType:#".json" expectedContentLength:-1 textEncodingName:nil];
expectedTotalSize = [response expectedContentLength];
if ([data length] !=0) {
NSLog(#"appendingData");
[receivedData appendData:data];
if(connection){
NSLog(#"Succeeded! Received %lu bytes of data",(unsigned long)[receivedData length]);
}
NSError *error;
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
if(jsonResponse){
NSArray *responseArr = [jsonResponse mutableCopy];
NSLog(#"%lu",(unsigned long)[responseArr count]);
}else if (!jsonResponse){
//do internet connection error response
}
}
}
The results I am getting back from putting a breakpoint in the code is:
jsonResponse returns NULL
NSError NSCocoaErrorDomain code - 3840
but my NSData *data is returning 15640 bytes.
My console is displaying this from the NSLogs I used for debugging:
2014-04-20 01:27:31.877 appendingData
2014-04-20 01:27:31.879 Succeeded! Received 15640 bytes of data
I am receiving the data correctly but I am not parsing it correctly I know the error is because the JSON is in JSONP format. If anyone could please help with this I would appreciate it so much. I have tired to give as much detail on this question as I can but if you need more information just let me know so I can add it and make this as clear as possible.
Your code has at least two separate attempts to download the data. Neither is really correct. The code also only works with JSON, not JSONP.
Try this:
NSURL *url = [NSURL URLWithString:#"https://getbible.net/json?p=James"];
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (data) {
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSRange range = [jsonString rangeOfString:#"("];
range.location++;
range.length = [jsonString length] - range.location - 2; // removes parens and trailing semicolon
jsonString = [jsonString substringWithRange:range];
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *jsonError = nil;
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&jsonError];
if (jsonResponse) {
// process jsonResponse as needed
} else {
NSLog(#"Unable to parse JSON data: %#", jsonError);
}
} else {
NSLog(#"Error loading data: %#", error);
}
}];
One problem is that the data you're downloading has extraneous information at the beginning and end. The JSON being delivered by your URL is:
({"book":[{"book_name":"James","book_nr":"59","chapter_nr":"3","chapter":{"16":{"verse_nr":"16","verse":"For where envying and strife is, there is confusion and every evil work."}}}],"direction":"LTR","type":"verse"});
As the error message you're seeing indicates: you need to remove the initial ( from the beginning of the string and the ); from the end so that your JSON will start with the dictionary that your code expects. You can do this by calling subdataWithRange: on your NSData object:
NSData* jsonData = [data subdataWithRange:NSMakeRange(1, data.length-3)];
NSDictionary* jsonResponse = [NSJSONSerialization JSONObjectWithData:jsonData
options:0
error:&error];
Just to update everyone, the NSURLRequest has been deprecated in iOS9. I tried the answer by #rmaddy, and I didn't receive anything either (just like what #lostAtSeaJoshua was encountering I guess). I have updated rmaddy's answer to reflect the NSURLSession implementation that has (I think) replaced NSURLRequest:
NSURLSession *session = [NSURLSession sharedSession];
NSURL *url = [NSURL URLWithString:#"http://somerandomwebsite.com/get.php?anotherRandomParameter=5"];
[[session dataTaskWithURL:url
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
// handle response
if (data) {
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"stringJSONed: %#",jsonString);
//Do something with the received jsonString, just like in # rmaddy's reply
} else {
NSLog(#"Error loading data: %#", error);
}
}] resume];
Just a heads up notice, when I first ran it, it gave me the security error. What you need to do (if you are using http) is to add this to your plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
I have to mention that after the NSAllowArbitraryLoads key, there are most probably other keys and values, such as NSExceptionDomain. But they're not really relevant to this answer I think. If you need to look further, let me know and I will dig deeper :)

iOS: forcing server to provide updated data

I'm working on an iPad app that requests data from a server, changes and submits it, and then re-requests the data from the server, displaying it to the user. The app updates the data just fine (the equivalent web app sees the update happening), but the data that the iPad app gets back is the old data. I thought maybe it was the caching flag on the NSURLRequest, but it doesn't look like it.
Here is my sequence of calls:
NSString* currentStuff = self.fCurrentIndex.currentStuff;
NSError* err = nil;
[self.fCurrentIndex approve:currentStuff withUsername:username andPassword:password error:&err];
if (err == nil)
{
// rebuild the case list (grab the data from the URL again first)
[self getCaseListViaURL]; // grab the updated data
[self setupUIPanel]; // display it
}
Here's the code that grabs the data (the 'getCaseListViaURL' call):
NSURLResponse* response;
NSError* err = nil;
NSMutableDictionary * jsonObject = nil;
NSString * urlRequestString;
urlRequestString = [method to get the URL string];
NSURL * url = [NSURL URLWithString:urlRequestString];
NSURLRequest * request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60];
NSData * data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&err];
if (err == nil)
{
jsonObject = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&err];
}
if (err && error) {
*error = err;
}
return jsonObject;
Is there any way to force the server to serve up the updated data?
Thanks in advance.
EDIT: Per comments, I'm adding the sequence of update to the server and subsequent pull:
This does the push to the server:
NSString* currentStuff = self.fCurrentIndex.currentStuff;
NSError* err = nil;
[self.fCurrentPatient approveStuff:currentStuff withUsername:username andPassword:password error:&err];
Where 'approveStuff' eventually calls:
__block NSData * jsonData;
__autoreleasing NSError * localError = nil;
if (!error) {
error = &localError;
}
// Serialize the dictionary into JSON
jsonData = [NSJSONSerialization dataWithJSONObject:data
options:NSJSONWritingPrettyPrinted
error:error];
if (*error) return nil;
NSURLResponse* response;
NSString * urlRequestString;
urlRequestString = [self urlStringForRelativeURL:relativeURL
withQueryParams:params];
NSURL * url = [NSURL URLWithString:urlRequestString];
NSMutableURLRequest * request;
request = [NSMutableURLRequest requestWithURL:url
cachePolicy:self.cachePolicy
timeoutInterval:self.timeOutInterval];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:jsonData];
[request setValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
jsonData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&localError];
NSMutableDictionary * jsonObject;
if (localError == nil)
{
jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers
error:&localError];
}
if (error && localError) {
*error = localError;
}
return jsonObject;
Right after this, I call the aforementioned get call and rebuild the UI. Now, if I stick a breakpoint when I do the get, and check on the web server if the data is updated after the push, I see the data is there. However, when I let the get operation continue, it gives me the old data.
So it looks like the issue was on the server. There were some data structures on the server side that weren't being refreshed when the data was being posted.

Resources