我真的在努力把一个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。


当前回答

Swift 4 JSON类与可解码-为那些喜欢类

定义类如下:

class People: Decodable {
  var person: [Person]?

  init(fileName : String){
    // url, data and jsonData should not be nil
    guard let url = Bundle.main.url(forResource: fileName, withExtension: "json") else { return }
    guard let data = try? Data(contentsOf: url) else { return }
    guard let jsonData = try? JSONDecoder().decode(People.self, from: data) else { return }

    // assigns the value to [person]
    person = jsonData.person
  }
}

class Person : Decodable {
  var name: String
  var age: String
  var employed: String
}

用法,非常抽象:

let people = People(fileName: "people")
let personArray = people.person

这允许People类和Person类的方法,如果需要,变量(属性)和方法也可以标记为private。

其他回答

Swift 2.1答案(基于Abhishek):

    if let path = NSBundle.mainBundle().pathForResource("test", ofType: "json") {
        do {
            let jsonData = try NSData(contentsOfFile: path, options: NSDataReadingOptions.DataReadingMappedIfSafe)
            do {
                let jsonResult: NSDictionary = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
                if let people : [NSDictionary] = jsonResult["person"] as? [NSDictionary] {
                    for person: NSDictionary in people {
                        for (name,value) in person {
                            print("\(name) , \(value)")
                        }
                    }
                }
            } catch {}
        } catch {}
    }

在清理和抛光我的代码之后,我来到了这两个函数,你可以添加到你的项目中,并使用它们非常整洁和快速地从json文件读取数据,并将数据转换为你想要的任何类型!

public func readDataRepresentationFromFile(resource: String, type: String) -> Data? {
    let filePath = Bundle.main.path(forResource: resource, ofType: type)
    
    if let path = filePath {
        let result = FileManager.default.contents(atPath: path)
        return result
    }
    return nil
}

然后在这个函数的帮助下,你可以将你的数据转换为任何你想要的类型:

public func getObject<T: Codable>(of type: T.Type, from file: String) -> T?  {
    guard let data = readDataRepresentationFromFile(resource: file, type: "json") else {
        return nil
    }
    if let object = try? JSONDecoder().decode(type, from: data) {
        return object
    }
    return nil
}

此代码的应用示例: 在你的代码中调用这个函数,给它你的json文件的名字,这就是你所需要的!

func getInputDataFromSomeJson(jsonFileName: String) -> YourReqiuredOutputType? {
    return getObject(of: YourReqiuredOutputType.self, from: jsonFileName)
}

如果有人正在寻找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.")
}

下面的代码适用于我。我用的是Swift 5

let path = Bundle.main.path(forResource: "yourJSONfileName", ofType: "json")
var jsonData = try! String(contentsOfFile: path!).data(using: .utf8)!

然后,如果你的Person结构(或类)是可解码的(以及它的所有属性),你可以简单地做:

let person = try! JSONDecoder().decode(Person.self, from: jsonData)

我避免了所有的错误处理代码,使代码更容易读懂。

遵循以下代码:

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
      }
}