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


当前回答

在清理和抛光我的代码之后,我来到了这两个函数,你可以添加到你的项目中,并使用它们非常整洁和快速地从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)
}

其他回答

Swift 5.1, Xcode 11

你可以用这个:


struct Person : Codable {
    let name: String
    let lastName: String
    let age: Int
}

func loadJson(fileName: String) -> Person? {
   let decoder = JSONDecoder()
   guard
        let url = Bundle.main.url(forResource: fileName, withExtension: "json"),
        let data = try? Data(contentsOf: url),
        let person = try? decoder.decode(Person.self, from: data)
   else {
        return nil
   }

   return person
}

斯威夫特 5+

用Struct解码jsonData

if let jsonData = readFile(forName: <your file name>) {

do {
                let decodedData = try JSONDecoder().decode(<your struct name>.self, from: jsonData)
                return decodedData.<what you expect>
            } catch { print("JSON decode error") }
}

这将读取文件并返回jsonData

如果你实际上在另一个bundle中(例如test),使用: let bundlePath = Bundle(for: type(of: self))。路径(forResource: name, ofType: "json")

private func readFile(forName name: String) -> Data? {
        do {

            if let bundlePath = Bundle.main.path(forResource: name, ofType: "json"),
                let jsonData = try String(contentsOfFile: bundlePath).data(using: .utf8) {
                return jsonData
            }
        } catch {
            print(error)
        }
        return nil
    }

Swift 4.1更新了Xcode 9.2

if let filePath = Bundle.main.path(forResource: "fileName", ofType: "json"), let data = NSData(contentsOfFile: filePath) {

     do {
      let json = try JSONSerialization.jsonObject(with: data as Data, options: JSONSerialization.ReadingOptions.allowFragments)        
        }
     catch {
                //Handle error
           }
 }

在清理和抛光我的代码之后,我来到了这两个函数,你可以添加到你的项目中,并使用它们非常整洁和快速地从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

func loadJson(fileName: String) -> JSON {

    var dataPath:JSON!

    if let path : String = Bundle.main.path(forResource: fileName, ofType: "json") {
        if let data = NSData(contentsOfFile: path) {
             dataPath = JSON(data: data as Data)
        }
    }
    return dataPath
}