I'm using TouchJSON. Made a call to my Rails app to fetch all "posts" at localhost:3000/posts.json. This returns a JSON array, surrounded by square brackets. I'm currently set up to convert the jsonString into an NSDictionary, but that fails due to the square brackets.
NSString *jsonString=[self jsonFromURLString:#"http://localhost:3000/posts.json"];
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *error = nil;
self.dictionary = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:&error];
What's the best way to turn this result into an NSArray using the TouchJSON library?
Error Domain=kJSONScannerErrorDomain Code=-101 "Could not scan dictionary. Dictionary that does not start with '{' character."
Why don't you just use the -deserialize: method and then figure out what kind of object you have after its done?
Or to answer your specific question, use -deserializeAsArray:
I think most parsers frown with array data. You'll have to return a hash:
{'result': [Your array data]}
Related
I’m trying to parse an JSON file into an NSArray and it all works well for positive numbers. However all the negative integers in that JSON file produce high numbers like “[11] __NSCFNumber * (long)72057594037927933”. How can i get that to work?
Here is my JSON file:
[0,1,2,3,4,5,6,7,8,9,10,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11]
and here the code:
NSError* error;
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"https://some/json/file.json"]];
NSMutableArray* array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
Xcode doesn't always print nice values into the Debug area of the Xcode (where live values for the context appear).
I dropped your code into my own project and when I step through each line, I do see the "eachNumber __NSCFNumber * (long)72057594037927934 {0xbfffffffffffffe3} bits, but if I try print out the values of the array into the console, you'll see the correct "-2" result.
Try it yourself. I added in these lines right after yours:
NSMutableArray* array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
NSLog(#"array is %#", array);
for(id eachNumber in array)
{
NSLog(#"eachNumber is %#", eachNumber);
}
I have some problems with parsing json using swift code.
json example
{"responce": "ok","orders": [{"id":"1"), {"id":"2"}, {"id":"3"} ]}
and this code working fine
let dataArray: NSArray = jsonResult["orders"] as! NSArray
but if I get {"responce": "ok","orders": ""} I got the error: Could not cast value of type __NSCFConstantString (0x10c7bfc78) to NSArray (0x10c7c0470).
Can I somehow check if value is array or not to do not crashed?
Yes you can check if the value is a NSArray by doing this:
if let dataArray = jsonResult["orders"] as? NSArray {
}
If the result of jsonResult["orders"] is a NSArray then dataArray will be set and you will go into the if statement.
This error is most likely caused by the response you are getting back from what I assume is a server not being JSON, but being something like an HTML/XML response saying that the server either could not be reached, or that your query/post request was invalid (hence the fact that the value was an "NSCFConstantString").
Using James' answer is a perfectly good way to check that the value is an Array, but you might want to test your requests using a program like Postman to see what he response is, and then hard code a way to handle that error on the user side.
I want to parse json data which contains html but there is a problem
I made a parser with this lines but always I got this error: The operation couldn’t be completed. (Cocoa error 3840.)
NSString *str = [[NSString alloc] initWithData:responseObject encoding:NSASCIIStringEncoding];
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding]
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:dataoptions:NSJSONReadingMutableContainers error:&error];
You need to fix the incoming JSON object. You will need to encode that HTML in your web-service (whatever that may be). You should be able to see the issue when you run your JSON through a validator like JSONViewer or JSONLint.
I created a servlet which responds to get requests with a byte array created from json data. I am trying to consume this data in iOS and use NSJSONSerialization to parse it into a NSDictionary, but it fails with the following error
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Duplicate key for object around character 11.) UserInfo=0x6833200 {NSDebugDescription=Duplicate key for object around character 11.}
Here is my code:
NSString *query = #"http://localhost:8888/url?method=retrieve";
NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:query]];
NSError *error = nil;
NSString *stringData = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"substring to index 255: %#", [stringData substringToIndex:255]);
NSDictionary *results = jsonData ? [NSJSONSerialization JSONObjectWithData:[stringData dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error] : nil;
NSLog(#"Response as Dictionary:\n%#", results.description);
if (error) {
NSLog(#"Error: %#", error);
}
the value of stringData is
{"APPEALS":{"APPEAL":{"AppealID":387423483,"LastEdit":"1 . . .
Response as Dictionary returns (null) obviously since there is an error
I am guessing that it has something to do with the fact that my server sends the data in an output stream as a byte[] (java) and it is not formatted correctly as json when received in iOS, but it doesn't make sense to me why it would fail at character 11 ":"
FYI, the server is written on Google App Engine in java and the localhost url is the local dev server. The json data was created using Jackson Generator library. Thanks!
I discovered the answer myself: when the error points to a duplicate key at a ":" character, that means that some key within the following json array is duplicated, not necessarily the one immediately following that character index. From my json data above, I had many "APPEAL" entries, that when turned into an NSDictionary will throw an error since there can be only 1 value for a given key. I believe my confusion arose from reading a Jackson json generator tutorial which described creating entries with the same key so that they can later be serialized into many instances of an object with "key" as the object class name (so I could have created many APPEAL objects using a Jackson parser, but not so in NSJSONSerialization).
I also had concatenated several json files server side:
( {"table":{"title":value}}{"anotherTable":{"title":value}} )
so that my url request response could serve several files with 1 request (cost efficiency), but these had to be split client side and serialized individually since "}}{" isn't legal json format.
The json had a duplicate key.For example,{"json":"3","string":"34","json":"3"}.The json can't be parsed before iOS6.0.
I'm a newbie with Json, so I want to extract some app information from the app store, I found this question here :
How to get info from the Apple iTunes «App Store» and «Mac App Store»
It allows to get a Json file containing all the app information, but it would be nice if someone could show me how to get the price for example.
Thanks.
Where and how do you want to collect the results? Is this for an app or for some other kind of tool? In the reuslting JSON you have an array "results" where each element has a "currency" and a "price" value. Those can be queired rather simply. For example using the iOS 5 NSJSONSerialization (note this is an example, there has to be more error handling, handling of no / too many entries etc):
// assuming you have the downloaded data
NSError *error = nil;
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:downloadedData options:nil error:&error];
if (error != nil)
{
// error handling
}
else
{
NSArray *results = [jsonData objectForKey:#"results"];
// assuming you have 1 valid entry
NSDictionary *result = [results objectAtIndex:0];
NSNumber *price = [result objectForKey:#"price"];
NSString *currency = [result objectForKey:#"currency"];
NSLog(#"Price is %# #%", price, currency);
}
Similar ways to access the data are avilable in other JSON frameworks, just grad the results array and every dictionary therein has a price and currency value.