Чтение файла JSON с помощью Swift

Я действительно изо всех сил пытаюсь прочитать файл JSON в Swift, чтобы я мог поиграть с ним. Я потратил большую часть двух дней на повторный поиск и пробу различных методов, но пока безуспешно, поэтому я подписался на 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, я буду бесконечно благодарен!

С уважением,

Криввенз.


person Krivvenz    schedule 25.06.2014    source источник
comment
используйте параметр ошибки...   -  person Matthias Bauch    schedule 25.06.2014
comment
Пожалуйста, опубликуйте реальный, компилируемый код. Как и сейчас, path виден только в области if и не разрешен, когда вы используете его в NSData(contentsOfFile, options, error); у вас также есть опечатки в именах перечислений.   -  person Kreiri    schedule 25.06.2014
comment
Мой API полностью обновлен для Swift 3: github.com/borchero/WebParsing   -  person borchero    schedule 29.09.2016
comment
это ключ -> значения: %LOAD VALUE FROM tmclass.json file% и мне нужно проанализировать другой JSON из файла, тогда как я могу добиться этого в SWIFT?   -  person Mayur Shinde    schedule 17.09.2019


Ответы (28)


Следуйте приведенному ниже коду:

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

Массив «лица» будет содержать все данные ключевого человека. Повторите проходы, чтобы получить его.

Свифт 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
      }
}
person Abhishek    schedule 25.06.2014
comment
Было бы полезнее, если бы вы объяснили, почему и как это решает проблему, описанную в вопросе, вместо того, чтобы просто представить кучу кода. - person Martin R; 25.06.2014
comment
Привет, Абхишек. Спасибо за ваш ответ, но он все еще не работает. Это приводит к сбою приложения со следующей ошибкой: 2014-06-25 16:02:04.146 H & S Capture[4937:131932] *** Завершение работы приложения из-за необработанного исключения «NSInvalidArgumentException», причина: «*** - [_NSPlaceholderData initWithContentsOfFile:options:error:]: аргумент файла nil' *** Стек вызовов первого броска: есть идеи, почему это так? Для параметров jsonData: я поставил (путь, параметры: NSDataReadingOptions.DataReadingMappedIfSafe, ошибка: ноль) - person Krivvenz; 25.06.2014
comment
Ваш путь к файлу неверен. На самом деле по указанному вами пути нет файла с именем test.json. Пожалуйста, проверьте правильность расположения файла - person Abhishek; 27.06.2014
comment
Это потому, что у меня файл сохранен в каталоге документов, а не в пакете приложений... Файла JSON на самом деле не будет там при установке... он будет извлечен из сети, но я просто хотел убедиться, что смогу прочитайте файл, как только он был сохранен в папке с документами.... - person Krivvenz; 01.07.2014
comment
Удалось решить проблему, запустив новый проект и повторно сделав файл JSON. Я считаю, что в файле JSON было дополнение, и он не был чистым JSON. Я думаю, что ранее он был сохранен в формате RTF. Таким образом, приведенный выше код, упомянутый Абхишеком, работает. Так что большое спасибо! - person Krivvenz; 02.07.2014
comment
let jsonData = NSData(contentsOfFile:путь!) вместо let jsonData = NSData.dataWithContentsOfFile(путь, параметры: .DataReadingMappedIfSafe, ошибка: ноль) - person tong; 14.11.2014
comment
Как вы записываете обратно в файл? - person Van Du Tran; 25.11.2014
comment
Однако здесь лучше использовать операторы guard else вместо этой пирамиды гибели. - person Zonily Jame; 20.02.2017
comment
Начиная с MacOS 10.6 / iOS 4 (!) существует API url(forResource в (NS)Bundle, чтобы избежать дополнительного шага по созданию URL-адреса. - person vadian; 23.11.2017
comment
OMG, использование URL(string:) вместо URL(fileURLWithPath:) было моей проблемой! Большое спасибо. - person DragonCherry; 28.03.2019
comment
Рад, что это спасло мой день. Спасибо - person Manish Mahajan; 17.04.2019
comment
Bundle.main.path(forResource: test, ofType: json) возвращается как nil в Swift 5. - person Jayprakash Dubey; 11.10.2020
comment
Не забудьте добавить файл в свой пакет. stackoverflow.com/questions/41775563/ - person Akash Bhardwaj; 14.04.2021

Если кто-то ищет 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.")
}
person Aks    schedule 21.02.2015
comment
это повернуло меня к swiftyJSON и carthage! Благодарность :) - person Paul Wand; 14.03.2015
comment
я использовал его только для того, чтобы обнаружить, что в нем отсутствует сопоставление объектов, в следующий раз я попробую другую библиотеку - person Elazaron; 03.03.2016
comment
Чтобы избежать ошибки копирования и вставки в Swift 3: NSData и NSError стали Data и Error. - person selva; 12.10.2016
comment
Я попробовал несколько разных методов, и это сработало лучше всего для меня в Swift 3. - person crobicha; 16.11.2016
comment
Начиная с MacOS 10.6 / iOS 4 (!) существует API url(forResource в (NS)Bundle, чтобы избежать дополнительного шага по созданию URL-адреса. - person vadian; 23.11.2017
comment
Спасибо за помощь! - person ssowri1; 03.11.2018

Swift 4.x и 5.x с использованием 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
}
person yarlg    schedule 24.04.2016
comment
Это следует переместить в новую функцию документации или пометить как правильный ответ. - person some_id; 08.09.2016

Свифт 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
}
person Gonzer    schedule 12.05.2020

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 {}
    }
person ben    schedule 25.09.2016

Обновлены имена для Swift 3.0

На основе ответа Абхишека и Друвы ответ

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
}
person Nick Graham    schedule 22.09.2016

Упрощение примера, предоставленного Питером Крейнцем. Работает со Свифт 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

Обратите внимание, что мы не предоставляем никаких ненужных дженериков, поэтому нам не нужно приводить результат синтаксического анализа.

person NeverwinterMoon    schedule 23.02.2019

Ответ Swift 2.1 (на основе Абхишека):

    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 {}
    }
person kjm    schedule 08.11.2015

Свифт 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
person Ashok R    schedule 13.11.2016

Это отлично сработало со мной

func readjson(fileName: String) -> NSData{

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

    return jsonData!
}
person Abdulaziz Noor    schedule 07.03.2015

Вот мое решение с использованием SwiftyJSON.

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

        let json = JSON(data: data)

    }
}
person will.fiset    schedule 30.05.2015

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
}

???????? Готовое к копированию и вставке решение, независимое от сторонней платформы.

использование ????????

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

person Maciej Banasiewicz    schedule 02.02.2017
comment
это сработало для меня. Мне нужно было жестко закодировать список лекарств с возможностью поиска в приложении. Я получил файл json из базы данных mySQL. Я поместил файл json в свой проект XCODE, работающий выше, в viewDidLoad, и бац, у меня был словарь json !!! - person Brian; 16.06.2017

Swift 4: попробуйте мое решение:

test.json

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

RequestCodable.swift

import Foundation

struct RequestCodable:Codable {
    let person:[PersonCodable]
}

PersonCodable.swift

import Foundation

struct PersonCodable:Codable {
    let name:String
    let age:String
    let employed:String
}

Декодируемый+FromJSON.swift

import Foundation

extension Decodable {

    static func fromJSON<T:Decodable>(_ fileName: String, fileExtension: String="json", bundle: Bundle = .main) throws -> T {
        guard let url = bundle.url(forResource: fileName, withExtension: fileExtension) else {
            throw NSError(domain: NSURLErrorDomain, code: NSURLErrorResourceUnavailable)
        }

        let data = try Data(contentsOf: url)

        return try JSONDecoder().decode(T.self, from: data)
    }
}

Пример:

let result = RequestCodable.fromJSON("test") as RequestCodable?

result?.person.compactMap({ print($0) }) 

/*
PersonCodable(name: "Bob", age: "16", employed: "No")
PersonCodable(name: "Vinny", age: "56", employed: "Yes")
*/
person Peter Kreinz    schedule 04.01.2019
comment
Ваша функция расширения fromJSON выбрасывает, но в примере вы вызываете ее без ключевого слова try. Этот код не будет компилироваться. - person NeverwinterMoon; 23.02.2019
comment
Кроме того, для fromJSON вы используете расширение Decodable, но не используете никакой информации из типа Decodable, но предоставляете дополнительные (совершенно бесполезные) дженерики. - person NeverwinterMoon; 23.02.2019

Я даю другой ответ, потому что ни один из приведенных здесь не предназначен для загрузки ресурса из тестового пакета. Если вы используете удаленную службу, которая выдает JSON, и хотите выполнить анализ результатов модульным тестом, не обращаясь к фактической службе, вы берете один или несколько ответов и помещаете их в файлы в папке «Тесты» в своем проекте.

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, но основная логика получения тестового пакета и загрузки файла является ответом на вопрос .

person Rob    schedule 27.05.2015

Следующий код работает для меня. Я использую 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)

Я избегал всего кода обработки ошибок, чтобы сделать код более разборчивым.

person Abraham Simpson    schedule 17.02.2020

Используйте эту общую функцию

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
}
person Khaled Annajar    schedule 08.06.2020

Последняя версия Swift 3.0 абсолютно рабочая

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

Обновлено для Swift 3 самым безопасным способом

    private func readLocalJsonFile() {

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

        do {
            let jsonData = try Data(contentsOf: urlPath, options: .mappedIfSafe)

            if let jsonDict = try JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers) as? [String: AnyObject] {

                if let personArray = jsonDict["person"] as? [[String: AnyObject]] {

                    for personDict in personArray {

                        for (key, value) in personDict {

                            print(key, value)
                        }
                        print("\n")
                    }
                }
            }
        }

        catch let jsonError {
            print(jsonError)
        }
    }
}

введите здесь описание изображения

person iAj    schedule 02.08.2017

Swift 4 JSON на Class с Decodable - для тех, кто предпочитает занятия

Определите классы следующим образом:

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, если это необходимо.

person Marco Leong    schedule 26.03.2019

Основываясь на ответе Abhishek, для iOS 8 это будет:

let masterDataUrl: NSURL = NSBundle.mainBundle().URLForResource("masterdata", withExtension: "json")!
let jsonData: NSData = NSData(contentsOfURL: masterDataUrl)!
let jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: nil) as! NSDictionary
var persons : NSArray = jsonResult["person"] as! NSArray
person David Poxon    schedule 30.06.2015
comment
Вы используете Swift 2.0? Тогда да, так и будет. На это был дан ответ до версии 2.0. - person David Poxon; 06.02.2016

Это сработало для меня с 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)
        }
    }
}
person anoop4real    schedule 03.09.2017

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
           }
 }
person Saranjith    schedule 10.07.2018
comment
Ничего нового, даже наоборот: не используйте NSData в Swift 3+, а .allowFragments в данном случае бессмысленно. - person vadian; 10.07.2018

Я использовал приведенный ниже код для выборки JSON из файла FAQ-data.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
            }
            . . .
        ]
    }
}
person Jayprakash Dubey    schedule 27.07.2016

Я также могу порекомендовать Swift JSON Tutorial Рэя Вендерлиха (в котором также рассматривается замечательная альтернатива 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 синтаксический анализ и десериализация JSON немного утомительнее из-за опций Swift и безопасности типов [но как] часть 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, пожалуйста, десериализуй этот JSON для меня в Swift 3.0 с отступами пробела/табуляции».

person AmitaiB    schedule 01.09.2016

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
}
person Ahmed Safadi    schedule 29.01.2017

Сначала создайте код Struc следующим образом:

  struct JuzgadosList : Codable {
    var CP : Int
    var TEL : String
    var LOCAL : String
    var ORGANO : String
    var DIR : String
}

Теперь объявите переменную

 var jzdosList = [JuzgadosList]()

Читать из основного каталога

func getJsonFromDirectory() {

        if let path = Bundle.main.path(forResource: "juzgados", ofType: "json") {
            do {
                let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .alwaysMapped)
                let jList = try JSONDecoder().decode([JuzgadosList].self, from: data)
                self.jzdosList = jList

                DispatchQueue.main.async() { () -> Void in
                    self.tableView.reloadData()
                }

            } catch let error {
                print("parse error: \(error.localizedDescription)")
            }
        } else {
            print("Invalid filename/path.")
        }
    }

Читать из Интернета

func getJsonFromUrl(){

        self.jzdosList.removeAll(keepingCapacity: false)

        print("Internet Connection Available!")

        guard let url = URL(string: "yourURL")  else { return }

        let request = URLRequest(url: url, cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 60.0)
        URLSession.shared.dataTask(with: request) { (data, response, err) in
            guard let data = data else { return }
            do {
                let jList = try JSONDecoder().decode([JuzgadosList].self, from: data)
                self.jzdosList = jList

                DispatchQueue.main.async() { () -> Void in
                    self.tableView.reloadData()
                }
            } catch let jsonErr {
                print("Error serializing json:", jsonErr)
            }
        }.resume()
    }
person oscar castellon    schedule 20.10.2018

После очистки и полировки моего кода я пришел к этим двум функциям, которые вы можете просто добавить в свой проект и использовать их очень аккуратно и быстро для чтения из файла 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)
}
person div-ane    schedule 08.07.2021

Свифт 5+

Декодирование 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

Если вы на самом деле находитесь в другом пакете (например, в тесте), используйте:
let bundlePath = Bundle(for: type(of: self)).path(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
    }
person Binoy jose    schedule 21.07.2021