我真的在努力把一个JSON文件读入Swift,这样我就可以玩它了。我花了2天的时间重新搜索和尝试不同的方法,但没有运气,所以我已经注册了StackOverFlow,看看是否有人能给我指点正确的方向.....

我的JSON文件叫做test。Json,并包含以下内容:

{
  "person":[
     {
       "name": "Bob",
       "age": "16",
       "employed": "No"
     },
     {
       "name": "Vinny",
       "age": "56",
       "employed": "Yes"
     }
  ]
}    

该文件直接存储在文档中,我使用以下代码访问它:

let file = "test.json"
let dirs : String[] = NSSearchPathForDirectoriesInDomains(
                                                          NSSearchpathDirectory.DocumentDirectory,
                                                          NSSearchPathDomainMask.AllDomainMask,
                                                          true) as String[]

if (dirs != nil) {
    let directories: String[] = dirs
    let dir = directories[0]
    let path = dir.stringByAppendingPathComponent(file)
}

var jsonData = NSData(contentsOfFile:path, options: nil, error: nil)
println("jsonData \(jsonData)" // This prints what looks to be JSON encoded data.

var jsonDict = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: nil) as? NSDictionary

println("jsonDict \(jsonDict)") - This prints nil..... 

如果有人能给我一个正确的方向,我可以反序列化JSON文件,并把它放在一个可访问的Swift对象,我会永远感激!

亲切的问候,

Krivvenz。


当前回答

这对我很有效

func readjson(fileName: String) -> NSData{

    let path = NSBundle.mainBundle().pathForResource(fileName, ofType: "json")
    let jsonData = NSData(contentsOfMappedFile: path!)

    return jsonData!
}

其他回答

这在XCode 8.3.3中是可行的

func fetchPersons(){

    if let pathURL = Bundle.main.url(forResource: "Person", withExtension: "json"){

        do {

            let jsonData = try Data(contentsOf: pathURL, options: .mappedIfSafe)

            let jsonResult = try JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers) as! [String: Any]
            if let persons = jsonResult["person"] as? [Any]{

                print(persons)
            }

        }catch(let error){
            print (error.localizedDescription)
        }
    }
}

对于那些希望在decodedable抛出错误后在调试器/ lldb中打印JSON数据的人,请尝试以下方法。

阿宝试试!JSONSerialization。jsonObject(:数据!,选项:.mutableLeaves) as?字典<字符串,任何>

遵循以下代码:

if let path = NSBundle.mainBundle().pathForResource("test", ofType: "json")
{
    if let jsonData = NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe, error: nil)
    {
        if let jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) as? NSDictionary
        {
            if let persons : NSArray = jsonResult["person"] as? NSArray
            {
                // Do stuff
            }
        }
     }
}

数组“persons”将包含关键人物的所有数据。遍历获取它。

斯威夫特4.0:

if let path = Bundle.main.path(forResource: "test", ofType: "json") {
    do {
          let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
          let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
          if let jsonResult = jsonResult as? Dictionary<String, AnyObject>, let person = jsonResult["person"] as? [Any] {
                    // do stuff
          }
      } catch {
           // handle error
      }
}

我可能还会推荐Ray Wenderlich的Swift JSON教程(它还涵盖了很棒的SwiftyJSON替代品,Gloss)。一段摘录(它本身并不能完全回答海报上的问题,但这个答案的附加价值是链接,所以请不要给它加-1):

在Objective-C中,解析和反序列化JSON相当简单:

NSArray *json = [NSJSONSerialization JSONObjectWithData:JSONData
options:kNilOptions error:nil];
NSString *age = json[0][@"person"][@"age"];
NSLog(@"Dani's age is %@", age);

在Swift中,由于Swift的可选选项和类型安全,解析和反序列化JSON有点繁琐,但作为Swift 2.0的一部分,guard语句被引入,以帮助摆脱嵌套的if语句:

var json: Array!
do {
  json = try NSJSONSerialization.JSONObjectWithData(JSONData, options: NSJSONReadingOptions()) as? Array
} catch {
  print(error)
}

guard let item = json[0] as? [String: AnyObject],
  let person = item["person"] as? [String: AnyObject],
  let age = person["age"] as? Int else {
    return;
}
print("Dani's age is \(age)")

当然,在XCode 8中。x,你只需双击空格键,然后说“嘿,Siri,请在Swift 3.0中用空格/制表符缩进为我反序列化这个JSON。”

如果有人正在寻找SwiftyJSON答案: 更新: 对于Swift 3/4:

if let path = Bundle.main.path(forResource: "assets/test", ofType: "json") {
    do {
        let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .alwaysMapped)
        let jsonObj = try JSON(data: data)
        print("jsonData:\(jsonObj)")
    } catch let error {
        print("parse error: \(error.localizedDescription)")
    }
} else {
    print("Invalid filename/path.")
}