14

I'm trying to load some JSON data from a local file.

In this Apple doc it says:

Manage the data files for your app using the asset catalog. A file can contain any sort of data except device executable code generated by Xcode. You can use them for JSON files, scripts, or custom data types

So I added a new data set and dropped the JSON file inside. Now I can see it under Assets.xcassets folder (Colours.dataset folder with colours.json and Contents.json inside it)

I found this SO answer that shows how to read a JSON file and I'm using this code to read the file:

if let filePath = NSBundle.mainBundle().pathForResource("Assets/Colours", ofType: "json"), data = NSData(contentsOfFile: filePath) {

        print (filePath)

        do {
            let json = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments)
            print(json)
        }
        catch {

        }
    } else {
        print("Invalid file path")
    }

But this code is printing "Invalid file path" and not reading the file. I also tried "Colours" and "Colours.json" but to no avail.

Could anyone please tell me how to properly add a local JSON file and read it?

Thanks.

Community
  • 1
  • 1
Volkan Paksoy
  • 6,727
  • 5
  • 29
  • 40

2 Answers2

26

You can't access data asset files in the same way you access a random file using NSBundle.pathForResource. Since they can only be defined within Assets.xcassets, you need to initialize a NSDataAsset instance in order to access the contents of it:

let asset = NSDataAsset(name: "Colors", bundle: NSBundle.mainBundle())
let json = try? NSJSONSerialization.JSONObjectWithData(asset!.data, options: NSJSONReadingOptions.AllowFragments)
print(json)

Please note that NSDataAsset class was introduced as of iOS 9.0 & macOS 10.11.

Swift3 version:

let asset = NSDataAsset(name: "Colors", bundle: Bundle.main)
let json = try? JSONSerialization.jsonObject(with: asset!.data, options: JSONSerialization.ReadingOptions.allowFragments)
print(json)

Also, NSDataAsset is surprisingly located in UIKit/AppKit so don't forget to import the relevant framework in your code:

#if os(iOS)

    import UIKit

#elseif os(OSX)

    import AppKit

#endif
Ondrej Rafaj
  • 4,342
  • 8
  • 42
  • 65
Ozgur Vatansever
  • 49,246
  • 17
  • 84
  • 119
1

objC

#ifdef use_json_in_bundle
            NSString * path = [mb pathForResource:json_path ofType:@"json" inDirectory:@"JSON"];
            NSString * string = [NSString stringWithContentsOfUTF8File:path];
            NSData * data = [string dataUsingEncoding:NSUTF8StringEncoding];
#else
            NSDataAsset * asset = [[NSDataAsset alloc] initWithName:path];
            NSLog(@"asset.typeIdentifer = %@",asset.typeIdentifier);
            NSData * data = [asset data];
#endif
            NSError * booboo = nil;
            id blob = [NSJSONSerialization JSONObjectWithData:data options:0 error:&booboo];

for either branch, 'path' is just the json file name.

slashlos
  • 913
  • 9
  • 17