iOS - How to properly read JSON file with umlauts - ios

I am having difficulties converting a JSON file into an NSDictionary without losing umlauts.
{
"België": "5",
"Haïti": "45"
}
This is a short version of the contents of a .json file in my supporting files in Xcode.
I need to convert them to an NSDictionary without losing those umlauts.
NSString *file =[[NSBundle mainBundle] pathForResource:#"countries_and_rates" ofType:#"json"];
NSString *cr = [NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:NULL];
After that, I give cr to this method:
+ (NSDictionary*)jsonFromData:(NSData*)data {
if([self isEmpty:data] || ![data isKindOfClass:[NSData class]])
return nil;
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if(!str)
return nil;
NSError* error;
id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
if(error)
NSLog(#"************** Error: jsonFromData: %#/%#", error.localizedDescription, error);
if([json isKindOfClass:[NSDictionary class]])
return json;
else if([json isKindOfClass:[NSArray class]])
return [NSDictionary dictionaryWithObject:json forKey:#"results"];
return #{};
}
If someone could help me and tell me what I am doing wrong.
FYI: tried all kinds of encoding, such as NSISO and NSUTF

Don't mess around with encodings, let the framework figure it out for you:
NSData *data = [NSData dataWithContentsOfFile:filepath];
NSError *error = nil;
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];

Related

JSON Serialization returns null from local file

I'm writing JSON to disk, and that works great. But when I try to read it back, it is nil.
Specifically, this line is nil: NSMutableDictionary *jsonDictFromDocuments = [NSJSONSerialization JSONObjectWithData:[jsonString2 dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&jsonError];. (I tried NSDictionary *jsonDict2 = [NSJSONSerialization JSONObjectWithData:jsonData2 options:kNilOptions error:&jsonError]; too, but still got nil.)
Every line up until that point logs the correct information from what I can tell.
// Read JSON back from disk
NSString *fileName2 = #"/myJSONFull.json";
NSLog(#"FN: %#", fileName2);
NSURL *documentsFolderURL2 = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSLog(#"dFURL2: %#", documentsFolderURL2);
NSString *filePath2 = [documentsFolderURL2.path stringByAppendingString:fileName2];
NSLog(#"FP2: %#", filePath2);
NSString *jsonString2 = [[NSString alloc] initWithContentsOfFile:filePath2 encoding:NSUTF8StringEncoding error:NULL];
NSLog(#"JSONs2: %#", jsonString2);
NSError *jsonError;
NSData *jsonData2 = [jsonString2 dataUsingEncoding:NSASCIIStringEncoding];
NSDictionary *jsonDict2 = [NSJSONSerialization JSONObjectWithData:jsonData2 options:kNilOptions error:&jsonError];
NSLog(#"JDFD2: %#", jsonDict2);
NSMutableDictionary *jsonDictFromDocuments = [NSJSONSerialization JSONObjectWithData:[jsonString2 dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&jsonError];
NSLog(#"JDFD: %#", jsonDictFromDocuments);
Any ideas?
EDIT:
This is what I have now, but it is still nil
// Read JSON back from disk
NSString *fileName2 = #"/myJSONFull.json";
NSURL *documentsFolderURL2 = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSString *filePath2 = [documentsFolderURL2.path stringByAppendingString:fileName2];
NSString *jsonString2 = [[NSString alloc] initWithContentsOfFile:filePath2 encoding:NSUTF8StringEncoding error:NULL];
NSError *jsonError;
NSData *data = [NSData dataWithContentsOfFile:filePath2];
NSMutableDictionary *jsonDictFromDocuments = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
Please try this, it uses the URL related API and logs a possible error in the deserialization.
NSString *fileName2 = #"myJSONFull.json";
NSLog(#"FN: %#", fileName2);
NSURL *documentsFolderURL2 = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSLog(#"dFURL2: %#", documentsFolderURL2);
NSURL *fileURL = [documentsFolderURL2 URLByAppendingPathComponent:fileName2];
NSLog(#"FP2: %#", fileURL);
NSData *jsonData = [NSData dataWithContentsOfURL:fileURL];
NSError *jsonError;
NSDictionary *jsonDict2 = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&jsonError];
NSLog(#"JDFD2: %# - error: %#", jsonDict2, jsonError);
Edit:
Since your JSON is PLIST in reality –
the error message JSON text did not start... means This is no JSON –
use the appropriate serialization class:
...
NSLog(#"FP2: %#", fileURL);
NSData *plistData = [NSData dataWithContentsOfURL:fileURL];
NSError *plistError;
NSArray *plistArray = (NSArray *)[NSPropertyListSerialization propertyListWithData:plistData
options:NSPropertyListImmutable
format:nil
error:&plistError];
NSLog(#"JDFD2: %# - error: %#", plistArray, jsonError);

Xcode - Special characters in JSON

Im loading a database from a website through JSON. When I download the database I use UTF8 to make all characters appear correctly and when I NSLOG them it all appears as it should. But when I analyze the data using JSON and afterwards try to filter out just a few of the words, the words with special characters become like this: "H\U00f6ghastighetst\U00e5g" where it should say: "Höghastighetståg".
I have tried to find a way to make the code convert the text back to UTF8 after filtering but somehow I can't make it happen. Would be really helpful for some answers.
NSError *error;
NSString *url1 = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://www.pumba.se/example.json"] encoding:NSUTF8StringEncoding error:&error];
NSLog(#"Before converting to NSData: %#", url1);
NSData *allCoursesData = [url1 dataUsingEncoding:NSUTF8StringEncoding];
NSMutableDictionary *JSONdictionary = [NSJSONSerialization
JSONObjectWithData:allCoursesData
options:kNilOptions
error:&error];
if( error )
{
NSLog(#"%#", [error localizedDescription]);
}
else {
NSMutableArray *allNames = [NSMutableArray array];
NSArray* entries = [JSONdictionary valueForKeyPath:#"hits.hits"];
for (NSDictionary *hit in entries) {
NSArray *versions = hit[#"versions"];
for (NSDictionary *version in versions) {
NSDictionary *properties = version[#"properties"];
NSString *status = [properties[#"Status"] firstObject];
NSString *name = [properties[#"Name"] firstObject];
if ([status isEqualToString:#"usable"]) {
[allNames addObject:name];
}
}
}
NSLog(#"All names: %#", allNames);
}}
try with
+ (NSString *)utf8StringEncoding:(NSString *)message
{
NSString *uniText = [NSString stringWithUTF8String:[message UTF8String]];
NSData *msgData = [uniText dataUsingEncoding:NSNonLossyASCIIStringEncoding];
message = [[NSString alloc] initWithData:msgData encoding:NSUTF8StringEncoding];
return message;
}
or
+ (NSString *)asciiStringEncoding:(NSString *)message
{
const char *jsonString = [message UTF8String];
NSData *jsonData = [NSData dataWithBytes:jsonString length:strlen(jsonString)];
message = [[NSString alloc] initWithData:jsonData encoding:NSNonLossyASCIIStringEncoding];
return message;
}
and this code can help you
+ (NSDictionary *)jsonStringToObject:(NSString *)jsonString
{
NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonResponse;
if (data)
jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
return jsonResponse;
}
+ (NSString *)objectToJsonString:(NSDictionary *)dict
{
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
if (jsonData.length > 0 && !error)
{
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
return jsonString;
}
return nil;
}

Cannot encode the data in ios

Cannot encode the data in ios which fetch from webservice.
- (NSData*)encodeDictionary:(NSDictionary*)dictionary {
NSMutableArray *parts = [[NSMutableArray alloc] init];
for (NSString *key in dictionary) {
NSString *encodedValue = [[NSString stringWithFormat:#"%#",[dictionary objectForKey:key]] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *encodedKey = [[NSString stringWithFormat:#"%#",key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *part = [NSString stringWithFormat: #"%#=%#", encodedKey, encodedValue];
[parts addObject:part];
}
NSString *encodedDictionary = [parts componentsJoinedByString:#"&"];
return [encodedDictionary dataUsingEncoding:NSUTF8StringEncoding];
}
It seems you are encoding NSDictionary and generate a NSString. And again Encoding that NSString and returns it.
You may do it in easy way as below.
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionaryOrArrayToOutput
options:NSJSONWritingPrettyPrinted
error:&error];
if (! jsonData) {
NSLog(#"Got an error: %#", error);
} else {
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
You may return above jsonData in your function to achieve your requirement as below.
- (NSData*)encodeDictionary:(NSDictionary*)dictionary {
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary
options:NSJSONWritingPrettyPrinted
error:&error];
if (! jsonData) {
NSLog(#"Got an error: %#", error);
} else {
return jsonData;
}
}

NSJSONSerialization Returns Error of NULL

I have the following code :
NSData * jsonData = [NSData dataWithContentsOfURL:location];
NSString* newStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSData *data = [newStr dataUsingEncoding:NSUTF8StringEncoding];
NSError *jsonError;
if (jsonError) {
NSLog(#"JSON Error %#", [jsonError localizedDescription]);
}
NSArray * jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError];
Which is parsing the following JSON String :
{"author":"Oli Riman","content":"The museum shows us a view of pre-WWI society that includes doubts, fears, political protests etc. through newspaper cartoons of the time. Really interesting for adults who enjoy history. I wouldn't suggest this for kids who haven't studied WWI history or who don't read easily.","rating":"5","placeId":"40","date":"29-June-2015","reviewId":"9905A52D-76B2-4D42-8CA8-9158225C0D07"}
However I am getting a strange error code of :
domain: (null) - code: 0
Can anyone advise on what is causing this ?
Just tested the code on my simulator. Its working. You need to check if you are getting data from server or not.
If you want to test the parsing thing, you can do one thing-
Just store the data in json file and save it in the app bundle lets say file is "data.json"
and call below method, you will get data for sure.
- (void)readJsonData {
NSString *path = [[NSBundle mainBundle] pathForResource:#"data" ofType:#"json"];
NSURL *url = [NSURL fileURLWithPath:path];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData: data
options: NSJSONReadingAllowFragments
error: &error];
NSLog(#"Parsed json data- %#", dict);
}

Json to iOS Encoding Error

Problem: I can't parse data from a JSON file to a NSArray appropriately. UTF encoding is not working as expected.
My JSON looks something like:
[
{"Name":"Marcos","Address":"1234 Brasil Av. São Paulo - SP","Latitude":"-23.000","Longitude":"-46.70"},{"Name":"Mario","Address":"1000 Washignton Luiz Av. Itú SP","Latitude":"-20.0000","Longitude":"-46.000"}
]
My Objective-C code is:
NSError *error = nil;
NSURL *jsonUrl = [[NSURL alloc]initWithString:
#"http://marcosdegni.com.br/teste/webservice_teste.php"];
NSString *jsonString = [NSString stringWithContentsOfURL:jsonUrl
encoding:NSUTF8StringEncoding error:&error];
NSLog(#"jsonString: %# , Error:%#:" ,jsonString, error); //(1)
if (!error) {
NSError *error2 = nil;
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSArray * jsonArray = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error2];
NSLog(#"\n\nArray: %#" \nError:$#, jsonArray, error2); //(2)
//(*1*) This log show the content's as they are expected: note the characters ã and ú on the address fields.
//(*2*) The logs from the array and the dictionary show this charters as it's UNIX codes:\U00e and \U00fa respectively.
You can give this a try. The id json you get will be a NSArray, you can use it from there.
NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSArray * array = json;
for (NSDictionary *dict in array) {
NSString *string = [dict objectForKey:#"Address"];
NSLog(#"%#",string);
}
From here, and I get the right result if I obtain the value of the key and log it, instead of logging the NSArray directly.

Resources