Чтение в файл JSON в Swift
Я действительно борюсь с попыткой прочитать файл 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.
19 ответов:
следуйте ниже код :
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 } }
Если кто-то ищет 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 4 с помощью декодируемого
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 }Swift 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 }
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 {} }
обновленные имена для 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 }
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 {} }
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
это отлично сработало со мной
func readjson(fileName: String) -> NSData{ let path = NSBundle.mainBundle().pathForResource(fileName, ofType: "json") let jsonData = NSData(contentsOfMappedFile: path!) return jsonData! }
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 }скопировать-вставить готовый, 3-й Рамочной самостоятельное решение партии.
использование
let json:[[String : AnyObject]] = loadJSON(name: "Stations")!
вот мое решение с помощью SwiftyJSON
if let path : String = NSBundle.mainBundle().pathForResource("filename", ofType: "json") { if let data = NSData(contentsOfFile: path) { let json = JSON(data: data) } }
Я даю другой ответ, потому что ни один из них здесь не ориентирован на загрузку ресурса из тестового пакета. Если вы используете удаленную службу, которая выпускает 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 но основная логика получения тестового пакета и загрузки файла ответ на этот вопрос.
последний 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 }
обновлено для 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) } } }
на основе ответ Абхишека, для 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
это сработало для меня с 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) } } }
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 } }
я использовал ниже код fetch JSON из FAQ-данных.файл 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 JSON Tutorial (который также охватывает удивительную альтернативу SwiftyJSON,блеск). Выдержка (которая сама по себе не полностью отвечает на плакат, но добавленная ценность этого ответа-это ссылка, поэтому нет -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 optionals и type-safety [но как] часть 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 с пробелами/отступами табуляции."
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 }

Comments