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

其他回答

我使用下面的代码从FAQ-data中获取JSON。Json文件存在于项目目录中。

我在Xcode 7.3中使用Swift实现。

     func fetchJSONContent() {
            if let path = NSBundle.mainBundle().pathForResource("FAQ-data", ofType: "json") {

                if let jsonData = NSData(contentsOfFile: path) {
                    do {
                        if let jsonResult: NSDictionary = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary {

                            if let responseParameter : NSDictionary = jsonResult["responseParameter"] as? NSDictionary {

                                if let response : NSArray = responseParameter["FAQ"] as? NSArray {
                                    responseFAQ = response
                                    print("response FAQ : \(response)")
                                }
                            }
                        }
                    }
                    catch { print("Error while parsing: \(error)") }
                }
            }
        }

override func viewWillAppear(animated: Bool) {
        fetchFAQContent()
    }

JSON文件结构:

{
    "status": "00",
    "msg": "FAQ List ",
    "responseParameter": {
        "FAQ": [
            {                
                "question": “Question No.1 here”,
                "answer": “Answer goes here”,  
                "id": 1
            },
            {                
                "question": “Question No.2 here”,
                "answer": “Answer goes here”,
                "id": 2
            }
            . . .
        ]
    }
}

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
    }

使用这个泛型函数

func readJSONFromFile<T: Decodable>(fileName: String, type: T.Type) -> T? {
    if let url = Bundle.main.url(forResource: fileName, withExtension: "json") {
        do {
            let data = try Data(contentsOf: url)
            let decoder = JSONDecoder()
            let jsonData = try decoder.decode(T.self, from: data)
            return jsonData
        } catch {
            print("error:\(error)")
        }
    }
    return nil
}

下面这行代码:

let model = readJSONFromFile(fileName: "Model", type: Model.self)

对于这种类型:

struct Model: Codable {
    let tall: Int
}

Swift 3.0, Xcode 8, iOS 10

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

        do {
            let jsonData = try Data(contentsOf: path, options: .mappedIfSafe)
            do {
                if let jsonResult = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions(rawValue: 0)) as? NSDictionary {
                    if let personArray = jsonResult.value(forKey: "person") as? NSArray {
                        for (_, element) in personArray.enumerated() {
                            if let element = element as? NSDictionary {
                                let name = element.value(forKey: "name") as! String
                                let age = element.value(forKey: "age") as! String
                                let employed = element.value(forKey: "employed") as! String
                                print("Name: \(name),  age: \(age), employed: \(employed)")
                            }
                        }
                    }
                }
            } catch let error as NSError {
                print("Error: \(error)")
            }
        } catch let error as NSError {
            print("Error: \(error)")
        }
    }

输出:

Name: Bob,  age: 16, employed: No
Name: Vinny,  age: 56, employed: Yes