NSURL with JSON returns null - ios

I'm keep getting a (null) error when I try to build my NSURL to open another app.
The URL should be
ms-test-app://eventSourceId=evtSrcId&eventID=13675016&eventType=0&json={"meterresults":[{"clean":"2","raw":"2","status":"0"}]}
but when I try to build my URL it's always null.
At first I thought it has something to do with the URL itself, but it's the same as I got it from the example here.
Another thought was that IOS got some problems with the double quotes in the JSON, but I replaced them with %22, but this doesn't work either.
Here is the code, where I build the URL:
NSString *jsonString = [NSString stringWithFormat:#"{%22meterresults%22:[{%22clean%22:%22%#%22,%22raw%22:%22%#%22,%22status%22:%22%#%22}]}", cleanReadingString, rawReadingString, status];
NSLog(#"JSON= %#",jsonString);
//Send the result JSON back to the movilizer app
NSString *eventSourceId = #"evtSrcId";
NSString *encodedQueryString = [NSString stringWithFormat:#"?eventSourceId=%#&eventID=%d&eventType=0&json=%#",
eventSourceId, _eventId, jsonString];[NSCharacterSet URLQueryAllowedCharacterSet]]
NSString *urlStr = [NSString stringWithFormat:#"%#%#",
[_endpointUrls objectForKey:[NSNumber numberWithInt:(int)_selectedEndpoint]],
encodedQueryString];
NSURL *url = [NSURL URLWithString:urlStr];
I don't know where I'm wrong and I would be glad if someone got any idea.
Thanks in advance.

You should really be using NSURLComponents to create URLs rather than trying to format them into a string.
NSDictionary* jsonDict = #{#"clean": #"2", #"raw": #"2", #"status": #"0"};
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:jsonDict options:0 error:NULL];
NSString* jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSURLComponents* components = [[NSURLComponents alloc] init];
components.scheme = #"ms-test-app";
components.queryItems = #[
[[NSURLQueryItem alloc] initWithName:#"eventSourceId" value:eventSourceId],
[[NSURLQueryItem alloc] initWithName:#"eventID" value:#(_eventId).stringValue],
[[NSURLQueryItem alloc] initWithName:#"json" value:jsonString]
];
NSURL* url = components.URL;
Once you build the URL that way, it becomes apparent that your string doesn't have a host portion (or more accurately, one of your parameters is being used as the host portion).
The other comments about not being able to send JSON as an URL parameter are incorrect. As long as the system on the other side that is parsing the query string can handle it, you can send anything you want as an URL parameter.

Related

How to encode the query part of the NSURL

(iOS 8.0+)
I want to use NSURL to pass some parameters in query part, like this:
NSURLComponents *components = [[NSURLComponents alloc] initWithString:#"ft://market/detail"];
NSDictionary *parameters = #{#"username" : #"高高高", #"from" : #"中国北京"};
NSMutableArray *items = [[NSMutableArray alloc] init];
for (NSString *key in parameters.allKeys) {
[items addObject:[[NSURLQueryItem alloc] initWithName:key value:parameters[key]]];
}
components.queryItems = items;
NSURL *url = components.URL;
NSLog(#"url : %#", url);
However, when I receive the URL and parse it, I find that the Chinese characters passed in the query part are abnormal, and I used NSURLComponents to parse the URL like this:
NSURLComponents *anaComponents = [NSURLComponents componentsWithString:url.absoluteString];
NSMutableDictionary *queryParams = [[NSMutableDictionary alloc] init];
for (NSURLQueryItem *querItem in anaComponents.queryItems) {
[queryParams setObject:querItem.value forKey:querItem.name];
}
NSLog(#"queryParams : %#", queryParams);
The following is the debug log:
url : ft://market/detail?username=%E9%AB%98%E9%AB%98%E9%AB%98&from=%E4%B8%AD%E5%9B%BD%E5%8C%97%E4%BA%AC
queryParams : {
from = "\U4e2d\U56fd\U5317\U4eac";
username = "\U9ad8\U9ad8\U9ad8";
}
The problem now seems to be that there is a problem with encoding and decoding of characters such as Chinese, even if [parameters[key] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]] method is used to encode the query value, it is still wrong when decoding.
The query part I want to parse is like this : #{#"username" : #"高高高", #"from" : #"中国北京"};.
Hope for your helps here, Thanks sincerely.

Convert NSString to NSData in Chinese case

everybody, I know this question is lots of people to ask and have lots of answer in stack overflow, but In my case, I try to get the JSON format from here, and code like this:
// Get JSON
NSString* path = #"http://opendata.epa.gov.tw/ws/Data/UV/?format=json";
NSURL* url = [NSURL URLWithString:path];
NSString* jsonString = [[NSString alloc]initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSData* jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:nil];
NSArray* arrayResult = dic;
NSDictionary* resultDic = [arrayResult objectAtIndex:0];
NSLog(#"resultDic:%#", resultDic);
NSString* uv = [resultDic objectForKey:#"UVI"];
NSLog(#"UVI:%#", uv);
NSString* publicshedTime = [resultDic objectForKey:#"PublishTime"];
NSLog(#"PublishTime:%#", publicshedTime);
NSLog(#"中文");
I used :
NSString* jsonString = [[NSString alloc]initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSData* jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
But it's not effective to this case, I don't know why.
In console, I can see the Chinese words correctly, and in debugger I can see the "jsonString" content is correct, but I don't know why I convert it to NSData, the content will be wrong, and it output like this :
2014-05-27 03:24:09.307 Tab demo[3014:60b] resultDic:{
County = "\U5609\U7fa9\U5e02";
PublishAgency = "\U4e2d\U592e\U6c23\U8c61\U5c40";
PublishTime = "2014-05-27 03:00";
SiteName = "\U5609\U7fa9";
TWD97Lat = "23,29,52";
TWD97Lon = "120,25,28";
UVI = 0;
}
2014-05-27 03:24:09.308 Tab demo[3014:60b] UVI:0
2014-05-27 03:24:09.308 Tab demo[3014:60b] PublishTime:2014-05-27 03:00
2014-05-27 03:24:09.308 Tab demo[3014:60b] 中文
For sure, the other data without Chinese words is display correctly.
This wrong looks like encoding wrong, but I don't know how to fix it correctly, can anyone tell me the way to fix it, Thanks a lot!
Don't compare contents of objects by their appearance in the console when logged using NSLog. That's unreliable because the algorithm to convert objects into strings is not documented, not strict and is for debugging purposes only.
Compare objects by using the compare: method.

Objective C get html from URL, encoding wrong

I want to ge the html content from the url bellow:
https://bbs.sjtu.edu.cn/file/bbs/mobile/top100.html
The code I have use below:
NSURL *url2 = [NSURL URLWithString:#"http://bbs.sjtu.edu.cn/file/bbs/mobile/top100.html"];
NSString *res = [NSString stringWithContentsOfURL:url2 encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000) error:nil];
NSLog(#"%#",res);
the result is null.
I have also tried with UTF8 encoding (also null) and ASCII encoding (has content and the english part of the content is right, but for Chinese charset, the content is garbled).
any one can help about this problem? I have been stuck here for a lot of time.
Try using stringWithContentsOfURL:usedEncoding:error: instead:
NSError *error = nil;
NSStringEncoding encoding;
NSString *my_string = [[NSString alloc] initWithContentsOfURL:url2
usedEncoding:&encoding
error:&error];

Encoding for getting contents of a url IOS

I want to get the contents of a url hosted by me. The contents of the url is
<p class="citation_style_APA">Blaine, J. D. (1992). <i>Buprenorphine: An alternative treatment for opioid dependence</i>. Rockville, MD: U.S. Dept. of Health and Human Services, Public Health Service, Alcohol, Drug Abuse, and Mental Health Administration, National Institute on Drug Abuse. </p>
Below is my code to get the above contents in a string.
NSString *s =[NSString stringWithFormat:#"%#",#"xyz.com"];
url = [NSURL URLWithString:s];
NSString *content = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:nil];
NSLog(#"%#",content);
I am getting null, can anyone tell where i am going wrong.
Try a complete web address, like #"http://www.xyz.com/myfile.html". Once you get it working, you'll want to change to an asynch technique.
You need to do two things.
1. you should use a valid url
2. NSString *content=[[NSString string] initWithContentsOfURL:url encoding:NSASCIIStringEncoding error:Nil];
Now check your Log; It'll definitely work.
Try this way
NSString *strUrl = < YOUR URL >
NSURL *url = [NSURL URLWithString:[strUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSError *error = nil;
NSString *content = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:&error];
if(content==nil)
NSLog(#"%#",error!=nil ? error.description : #"");
else
NSLog(#"%#",content);

Encode JSON data for URL

In iOS, I want to send JSON data in URL to make service call. I tried following code snipped but Encoded URL seems wrong. Because in JSON there is a colon character (:) between key and value and comma character (,) for separation. But, i am not able to encode colon(:) as %3A and comma(,) as %2C
Code Snippet:
- (NSURL *)getEncodedUrl {
// Build dictionnary with parameters
NSString *abc = #"abc";
NSNumber *limitNumber = [NSNumber numberWithInt:2];
NSMutableDictionary *dictionnary = [NSMutableDictionary dictionary];
[dictionnary setObject:limitNumber forKey:#"limit"];
[dictionnary setObject:abc forKey:#"abc"];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionnary options:0 error:&error];
if (!jsonData) {
debug("Json error %#",error);
return nil;
} else {
NSString *JSONString = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding];
debug("Json op %#",JSONString);
NSString* params = [JSONString stringByAddingPercentEscapesUsingEncoding:
NSASCIIStringEncoding];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://baseUrl.com?param=#",params]];
debug("URL = %#",url);
return url;
}
}
OUTPUT:~
URL = http://baseUrl.com?param=%7B%22abc%22:%22abc%22,%22limit%22:2%7D
(Include colon and comma characters)
But I want following o/p:
http://baseUrl.com?param=%7B%22abc%22%3A%22abc%22%2C%22limit%22%3A2%7D
(No colon and comma characters)
Online Encoding-Decoding Site that I am referring as of now.
http://www.url-encode-decode.com/
you can simply use
NSString *url = #"http://baseUrl.com?param=%7B%22abc%22:%22abc%22,%22limit%22:2%7D";
NSString *encodeImgUrl = [url stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
I'd recommend that you send the JSON as POST data instead of the GET that you're using. It'd be more straightforward to package it as MIME data and any encoding you do would be easier to understand.
So you are trying to generate the query portion of a URL here. Colons are a perfectly legitimate character to include in URL queries. I wrote an article covering the intricacies of escaping URL queries in Cocoa:
http://www.mikeabdullah.net/escaping-url-queries-in-cocoa.html
Since you're keen to perform extra escaping, I suggest taking my sample code and extending it to specially ask for : and ; characters to be escaped too.
I made small mistake in API call that is why I am getting wrong result. There is no need to encode colon(:) as %3A and comma(,) as %2C.
One more thing I would like to share with you. You can use base64 string instead of encoding JSON part.

Resources