Sheikh Muhammad Umar Sheikh Muhammad Umar - 7 months ago 318
Swift Question

Trying to read from a JSON file in swift 2 overload error showing up

Hi so here's the boilerplate code for parsing JSON files in Swift 2. Ive used this before and it works but for some reason its broken in the latest version of Xcode 7.1 and Swift 2. Any thoughts about this guys? The error is "Argument labels '(contentsOfFile:, options:, error:)' do not match any available overloads"

import Foundation

extension Dictionary {
static func loadJSONFromBundle(filename: String) -> Dictionary<String, AnyObject>? {
if let path = NSBundle.mainBundle().pathForResource(filename, ofType: "json") {

var error: NSError?
let data = NSData(contentsOfFile: path, options: NSDataReadingOptions, error: &error)
if let data = data {
let dictionary: AnyObject? = NSJSONSerialization.JSONObjectWithData(data,
options: NSJSONReadingOptions(), error: &error)
if let dictionary = dictionary as? Dictionary<String, AnyObject> {
return dictionary
} else {
print("Level file '\(filename)' is not valid JSON: \(error!)")
return nil
}
} else {
print("Could not load level file: \(filename), error: \(error!)")
return nil
}
} else {
print("Could not find level file: \(filename)")
return nil
}
}
}

Answer

You were using a not up to date swift code,

I corrected your code, notice that you should select the best NSDataReadingOption that suites u, i choose NSDataReadingOptions.DataReadingMapped

Plus some api don't take the error as an input, so i deleted it.

Notice that when you catch the error, you can use the object error which having it declared explicitly, that is why i removed your error variable

Finally, the new apis for parsing json, should be in a try catch, that is why i added a try catch

import Foundation

extension Dictionary {
    static func loadJSONFromBundle(filename: String) -> Dictionary<String, AnyObject>? {
        if let path = NSBundle.mainBundle().pathForResource(filename, ofType: "json") {


            do{
                let data = try NSData(contentsOfFile: path, options: NSDataReadingOptions.DataReadingMapped)
                do{
                    let dictionary: AnyObject? = try NSJSONSerialization.JSONObjectWithData(data,
                        options: NSJSONReadingOptions())
                    if let dictionary = dictionary as? Dictionary<String, AnyObject> {
                        return dictionary
                    } else {
                        print("Level file '\(filename)' is not valid JSON")
                        return nil
                    }
                }catch {
                    print("Level file '\(filename)' is not valid JSON: \(error)")
                    return nil
                }


            }catch {
                print("Could not load level file: \(filename), error: \(error)")
                return nil
            }

        } else {
            print("Could not find level file: \(filename)")
            return nil
        }
    }
}

So basically:

  1. The NSData(contentsOfFile: path, options: doesn't take error anymore.
  2. The dictionary: AnyObject? = try NSJSONSerialization.JSONObjectWithData(data, options doesn't take error anymore.
  3. Getting NSData from file needs a try catch
  4. Getting json object from NSData needs a try catch