0

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];
SRMR
  • 3,064
  • 6
  • 31
  • 59
  • @vadian `jsonError` says `nil` – SRMR Jul 19 '16 at 16:06
  • Right, the issue is: You cannot pass `NSString` to `JSONObjectWithData` (jsonString2) – vadian Jul 19 '16 at 16:07
  • @vadian Is that supposed to be `NSData` instead or something? – SRMR Jul 19 '16 at 16:08
  • Yes, as the name *...With**Data*** implies. I don't understand the second deserialization anyway. – vadian Jul 19 '16 at 16:08
  • @vadian I was trying to do something related to that in my code with `NSData *jsonData2 = [jsonString2 dataUsingEncoding:NSASCIIStringEncoding];` and this `NSDictionary *jsonDict2 = [NSJSONSerialization JSONObjectWithData:jsonData2 options:kNilOptions error:&jsonError];` but I couldn't get that working either? – SRMR Jul 19 '16 at 16:10
  • 1
    Use always `NSUTF8StringEncoding`. You can also read the data directly from disk: `[NSData dataWithContentsOfFile]` – vadian Jul 19 '16 at 16:11
  • What `jsonString2` looks like? How did you save your data at the first place? Note that `jsonDictFromDocuments` shouldn't be mutable (could lead to a unrecognized selector afterwards). – Larme Jul 19 '16 at 16:13
  • @Larme `jsonString2` looks like `JSONs2: `... Does that make sense or not? – SRMR Jul 19 '16 at 16:15
  • It seems that you save a `NSDictionary`, so you created a `.plist`. Just do `NSDictionary *jsonDict2 = [NSDictionary dictionaryWithContentsOfFile: filePath2];` – Larme Jul 19 '16 at 16:16
  • @vadian so change the `dataUsingEncoding` to `NSUTF8StringEncoding`? When you say `[NSData dataWithContentsOfFile]` that should be replacing which part? – SRMR Jul 19 '16 at 16:18
  • `dataWithContentsOfFile` replaces `stringWithContentsOfFile` and the subsequent conversion to `NSData`. – vadian Jul 19 '16 at 16:20
  • After furthermore checking, your .plist seems to have a `NSArray` (we see ``) at top level, so `NSArray *jsonArray = [NSArray arrayWithContentsOfFile:filePaths2];` So you are clearly messing a lot of stuff. Show how you save your data and be sure of what kind of data. Because since the file is a plist, you save the serialized JSON. – Larme Jul 19 '16 at 16:28
  • @vadian I updated my code and added it in my question, but am still getting `nil`, what part am I missing that you're telling me to do? I know you're right but somehow I must be totally missing some thing you're saying. – SRMR Jul 19 '16 at 16:31
  • @Larme I must be messing a lot of stuff, and I'm trying to fix, but still a bit confused, do you mind posting an answer so I can see clearly in order which things you're saying? – SRMR Jul 19 '16 at 16:33
  • 1
    Use my last answer (the one with NSArray), it should work. – Larme Jul 19 '16 at 16:37
  • @Larme will definitely do, thanks again for the help – SRMR Jul 19 '16 at 17:06

1 Answers1

1

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);
vadian
  • 274,689
  • 30
  • 353
  • 361
  • Thanks for putting an answer here so I could see if there was anything I was missing. I get `JDFD2: (null) - error: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}` – SRMR Jul 19 '16 at 16:43
  • I tried to add `NSJSONReadingAllowFragments` per this answer http://stackoverflow.com/questions/14171111/cocoa-error-3840-using-json-ios but then got `JDFD2: (null) - error: Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}` – SRMR Jul 19 '16 at 16:47
  • @vadian: The author saved the serialized JSON, so it's a plist, and furthermore, it's a NSArray at top level. Even though your answer should be the correct one (using directly `dataWithContentOfURL:` instead of dragging `NSString`), it won't work until the user doesn't save the JSON unserialized. – Larme Jul 19 '16 at 17:18