使用Swift读取JSON文件

 史彩哲 发布于 2023-01-07 17:20

我真的很想尝试将一个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.

12 个回答
  • 如果有人在寻找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.")
    }
    

    2023-01-07 17:20 回答
  • 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 {}
        }
    

    2023-01-07 17:20 回答
  • Xcode 8 Swift 3从文件更新中读取json:

        if let path = Bundle.main.path(forResource: "userDatabseFakeData", ofType: "json") {
            do {
                let jsonData = try NSData(contentsOfFile: path, options: NSData.ReadingOptions.mappedIfSafe)
                do {
                    let jsonResult: NSDictionary = try JSONSerialization.jsonObject(with: jsonData as Data, options: JSONSerialization.ReadingOptions.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 {}
        }
    

    2023-01-07 17:20 回答
  • Swift 4使用Decodable

    struct ResponseData: Decodable {
        var person: [Person]
    }
    struct Person : Decodable {
        var name: String
        var age: String
        var employed: String
    }
    
    func loadJson(filename fileName: String) -> [Person]? {
        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(ResponseData.self, from: data)
                return jsonData.person
            } catch {
                print("error:\(error)")
            }
        }
        return nil
    }
    

    斯威夫特3

    func loadJson(filename fileName: String) -> [String: AnyObject]? {
        if let url = Bundle.main.url(forResource: fileName, withExtension: "json") {
            do {
                let data = try Data(contentsOf: url)
                let object = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
                if let dictionary = object as? [String: AnyObject] {
                    return dictionary
                }
            } catch {
                print("Error!! Unable to parse  \(fileName).json")
            }
        }
        return nil
    }
    

    2023-01-07 17:20 回答
  • 这对我有用

    func readjson(fileName: String) -> NSData{
    
        let path = NSBundle.mainBundle().pathForResource(fileName, ofType: "json")
        let jsonData = NSData(contentsOfMappedFile: path!)
    
        return jsonData!
    }
    

    2023-01-07 17:20 回答
  • 更新了Swift 3.0的名称

    根据Abhishek的回答和Druva的回答

    func loadJson(forFilename fileName: String) -> NSDictionary? {
    
        if let url = Bundle.main.url(forResource: fileName, withExtension: "json") {
            if let data = NSData(contentsOf: url) {
                do {
                    let dictionary = try JSONSerialization.jsonObject(with: data as Data, options: .allowFragments) as? NSDictionary
    
                    return dictionary
                } catch {
                    print("Error!! Unable to parse  \(fileName).json")
                }
            }
            print("Error!! Unable to load  \(fileName).json")
        }
    
        return nil
    }
    

    2023-01-07 17:20 回答
  • 请遵循以下代码:

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

    数组"人员"将包含关键人物的所有数据.迭代通过获取它.

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

    2023-01-07 17:20 回答
  • 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
    

    2023-01-07 17:20 回答
  • fileprivate class BundleTargetingClass {}
    func loadJSON<T>(name: String) -> T? {
      guard let filePath = Bundle(for: BundleTargetingClass.self).url(forResource: name, withExtension: "json") else {
        return nil
      }
    
      guard let jsonData = try? Data(contentsOf: filePath, options: .mappedIfSafe) else {
        return nil
      }
    
      guard let json = try? JSONSerialization.jsonObject(with: jsonData, options: .allowFragments) else {
        return nil
      }
    
      return json as? T
    }
    

    copy-paste ready,第三方框架独立解决方案.

    用法

    let json:[[String : AnyObject]] = loadJSON(name: "Stations")!

    2023-01-07 17:20 回答
  • 这是我使用SwiftyJSON的解决方案

    if let path : String = NSBundle.mainBundle().pathForResource("filename", ofType: "json") {
        if let data = NSData(contentsOfFile: path) {
    
            let json = JSON(data: data)
    
        }
    }
    

    2023-01-07 17:20 回答
  • 简化Peter Kreinz提供的示例。适用于Swift 4.2。

    扩展功能:

    extension Decodable {
      static func parse(jsonFile: String) -> Self? {
        guard let url = Bundle.main.url(forResource: jsonFile, withExtension: "json"),
              let data = try? Data(contentsOf: url),
              let output = try? JSONDecoder().decode(self, from: data)
            else {
          return nil
        }
    
        return output
      }
    }
    

    示例模型:

    struct Service: Decodable {
      let name: String
    }
    

    用法示例:

    /// service.json
    /// { "name": "Home & Garden" }
    
    guard let output = Service.parse(jsonFile: "service") else {
    // do something if parsing failed
     return
    }
    
    // use output if all good
    

    该示例也适用于数组:

    /// services.json
    /// [ { "name": "Home & Garden" } ]
    
    guard let output = [Service].parse(jsonFile: "services") else {
    // do something if parsing failed
     return
    }
    
    // use output if all good
    

    注意,我们如何不提供任何不必要的泛型,因此我们不需要转换解析结果。

    2023-01-07 17:22 回答
  • 我提供了另一个答案,因为这里的所有答案都不适合从测试包中加载资源.如果您正在使用一个发出JSON的远程服务,并且想要在不触及实际服务的情况下对结果进行单元测试,则需要一个或多个响应并将它们放入项目的Tests文件夹中的文件中.

    func testCanReadTestJSONFile() {
        let path = NSBundle(forClass: ForecastIOAdapterTests.self).pathForResource("ForecastIOSample", ofType: "json")
        if let jsonData = NSData(contentsOfFile:path!) {
            let json = JSON(data: jsonData)
            if let currentTemperature = json["currently"]["temperature"].double {
                println("json: \(json)")
                XCTAssertGreaterThan(currentTemperature, 0)
            }
        }
    }
    

    这也使用SwiftyJSON,但获取测试包和加载文件的核心逻辑是问题的答案.

    2023-01-07 17:22 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有