NSString *urlString=[NSString stringWithFormat:#"http://192.168.178.1/iBus/appService/_getMarker.php"];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *responseCode = nil;
NSData *dataConnect;
dataConnect = [NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error];//connect todata
NSDictionary * jsonObj;
if (responseCode) {//if connect(response)
NSLog(#"%#",dataConnect);//here is return data
NSLog(#"%#",[NSJSONSerialization JSONObjectWithData:dataConnect options:kNilOptions error:nil]);//here is return NULL!!!
}
Its return NSData but not encode to JSON
Here is slog console
2014-12-18 13:14:00.997 iBus[2689:58536] (null)
Here is my json output : http://notes.io/Zd3
According to the documentation, if JSONObjectWithData returns nil, that means an error occurs. You can read the error message by passing a reference to an NSError object to the error: argument.
As Kampai mentioned, this is likely caused by invalid JSON.
Related
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 :)
I have have some trouble in understanding what is needed to fetch a JSON file with mantle.h from a URL.
Can someone give me an example of how it works?
For example:
-I have a URL www.example.com with a JSONFile as follows:
{
"name": "michael"
}
How could I fetch it?
I use this process for fetching JSON:
NSURL *s = url;//Put your desird url here
NSURLRequest *requestURL = [NSURLRequest requestWithURL:s cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.00];
NSHTTPURLResponse *response;
NSError *error = [[NSError alloc]init];
NSData *apiData = [NSURLConnection sendSynchronousRequest:requestURL returningResponse:&response error:&error];
dictionaryData = [NSJSONSerialization JSONObjectWithData:apiData options:kNilOptions error:&error];
Now the dictionaryData contains your JSON. You can fetch it by:
NSString *name = [dictionaryData valueForKey:#"name"];
And make sure you are making async request. For this put the code within this block:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
//Put the code here
});
Hope this helps.. :)
Call it with following method
[super getRequestDataWithURL:urlString
andRequestName:sometext];
You will get response in the following method if successful
- (void)successWithRequest:(AFHTTPRequestOperation *)operation withRespose:(id)responseObject withRequestName:(NSString *)requestName {
NSString *response = operation.responseString;
id jsonObject = [response objectFromJSONString];
if(![super checkforServerRequestFailureErrorMessage:jsonObject]) {
[self.leaderboardProxyDelegate leaderboardListSuccessful:jsonObject];
}
}
You will get dictionary in jsonObject
I am trying to parse some values from a json. I manage to get the value for results.geometry.location. If the parameters fails the server return a json with 2 value. results which is empty[] and status "some error".
url = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?address=%#&sensor=false",postalCode];
NSData *jsonDataString = [[NSString stringWithContentsOfURL:[NSURL URLWithString:url] encoding:NSUTF8StringEncoding error: nil] dataUsingEncoding:NSUTF8StringEncoding];
NSArray* myResults = [NSJSONSerialization JSONObjectWithData:jsonDataString options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:&error];
latLon =[myResults valueForKeyPath:#"results.geometry.location"];
generalDict = (NSDictionary *)[latLon objectAtIndex:0];
NSLog(#"%#",[generalDict objectForKey:#"lat"]);
It's confusing. I tried:
latLon =[myResults valueForKeyPath:#""];
generalDict = (NSDictionary *)[latLon objectAtIndex:0];
NSLog(#"%#",[generalDict objectForKey:#"status"]);
but is not working. How can I get the value of the status. This is how it looks like when the request is invalid:
{
"results" : [],
"status" : "ZERO_RESULTS"
}
myResults is a dictionary, not an array. I think you want something like this:
NSURL *url = [NSURL urlWithString:[NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?address=%#&sensor=false",postalCode];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSDictionary *jsonPayload = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves
error:nil];
NSString *status = [jsonPayload objectForKey:#"status"];
//Check for error status
NSArray *resultsArray = [jsonPayload objectForKey:#"results"];
//Do whatever you want with your results array
}];
There are, for example, 100 JSON files and appropriate 100 images on my ftp server.
1.With loading JSON where are no bug (I hope)
NSString *recipesPath = #"ftp://.../recipes/";
NSString *recipeFileName = [NSString stringWithFormat:#"00001.json", recipeCode];
NSString *recipeFileFullPath = [recipesPath stringByAppendingString:recipeFileName];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:recipeFileFullPath]];
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSError *error = nil;
NSDictionary *recipeDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
2.But images can not be loaded
NSString *recipeImageName = #"recipeImages/00001-1.jpg";
NSString *recipeImageFullPath = [recipesPath stringByAppendingString:recipeImageName];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:recipeImageFullPath]];
if (request) {
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
if (responseData) {
UIImage *image = [UIImage imageWithData:responseData];
}
}
responseData nearly always is nil.
May be there is the other method?
All this code is in MyMethod which I execute in NSOperationQueue:
operation = [[NSInvocationOperation alloc] initWithTarget:self selector:#selector(MyMethod) object:nil];
[operationQueue addOperation:operation];
EDIT: image sizes are not big - from 50 to 100 kbyte
EDIT: can image file extension affect to downloading process?
You can try this:
NSURL *url = [NSURL URLWithString:recipeImageFullPath];
NSData *data = [NSData alloc] initWithContentsOfURL:url];
Please try to test it:
NSError *requestError;
NSURLResponse *urlResponse = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
/* Return Value
The downloaded data for the URL request. Returns nil if a connection could not be created or if the download fails.
*/
if (responseData == nil) {
// Check for problems
if (requestError != nil) {
...
}
}
else {
// Data was received.. continue processing
}
Where JSON_CATEGORY_DATA_URL_STRING is my feed URL, which returns fine as:
[
{
"group":"For Sale",
"code":"SSSS"
},
{
"group":"For Sale",
"category":"Wanted",
"code":"SWNT"
}
]
I cannot seem to get a nice NSDictionary (or NSArray) out of the following code:
+ (NSDictionary *)downloadJSON
{
NSDictionary *json_string;
NSString *dataURL = [NSString stringWithFormat:#"%#", JSON_CATEGORY_DATA_URL_STRING];
NSLog(#"%#",dataURL);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:dataURL]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
json_string = [[[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]autorelease];
NSDictionary *json_dict = (NSDictionary *)json_string;
NSLog(#"json_dict\n%#",json_dict);
NSLog(#"json_string\n%#",json_string);
return json_string;
}
I've read many posts on this, but am not getting it.
With IOS5 you can use NSJSONSerialization for serializing the JSON.
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
You can't just cast a string as a dictionary and expect it to parse the JSON. You must use a JSON parsing library to take that string and convert it into a dictionary.
I made a class that makes this task easier. It uses iOS 5's NSJSONSerialization. Clone it from github here.
You need to use JSON parser. here is the edited code
+ (NSDictionary *)downloadJSON
{
NSDictionary *json_string;
NSString *dataURL = [NSString stringWithFormat:#"%#", JSON_CATEGORY_DATA_URL_STRING];
NSLog(#"%#",dataURL);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:dataURL]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
json_string = [[[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]autorelease];
//JSONValue is a function that will return the appropriate object like dictionary or array depending on your json string.
NSDictionary *json_dict = [json_string JSONValue];
NSLog(#"json_dict\n%#",json_dict);
NSLog(#"json_string\n%#",json_string);
return json_dict;
}
this should be the code to get the NSDictionary. but you json string is an array so instead use .
+ (NSArray *)downloadJSON
{
NSDictionary *json_string;
NSString *dataURL = [NSString stringWithFormat:#"%#", JSON_CATEGORY_DATA_URL_STRING];
NSLog(#"%#",dataURL);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:dataURL]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
json_string = [[[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]autorelease];
NSArray *json_dict = [json_string JSONValue];
NSLog(#"json_dict\n%#",json_dict);
NSLog(#"json_string\n%#",json_string);
return json_dict;
}
Edit:
you need to use JSON.framework to call JSONValue method.
also you need to return json_dict instead of json_string as json_string is of NSString type and not NSDictionary or NSArray.
and dont autorelease it, as it is your class variable
create method to fetchjson data.Pass your url in urlwithstring.
-(void)fetchjsondata
{
NSString *login= [[NSString stringWithFormat:#"your url string"]stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"----%#", login);
NSURL *url = [NSURL URLWithString:[login stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
//-- Get request and response though URL
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (data) {
dic_property= [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(#"%#", dic_property);
NSLog(#"counts=%d",[[dic_property objectForKey:#"Data"]count]);
}
else {
NSLog(#"network error, %#", [error localizedFailureReason]);
}
});
}];
}
call fetchjsonmethod in anywhere.
[NSThread detachNewThreadSelector:#selector(fetchdata) toTarget:self withObject:nil];