Reading in a JSON file using Swift

I am really struggling with trying to read a JSON file in Swift so that I can play around with it. I spent most of 2 days searching again and trying different methods, but with no luck, so I signed up for StackOverFlow to find out if anyone could point me in the right direction .....

My JSON file is called test.json and contains the following:

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

The file is stored in the documents directly, and I access it using the following code:

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

If someone can just give me a push in the right direction, how can I de-serialize a JSON file and put it in an accessible Swift object, I will be infinitely grateful!

Respectfully,

Krivvenz.

+135
json xcode ios8 swift nsjsonserialization
Jun 25 '14 at 2:04
source share
21 answers

Follow the code below:

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

The "people" array will contain all the data for the key person. Iterate the passages to get it.

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 } } 
+207
Jun 25 '14 at 14:10
source share

If someone is looking for SwiftyJSON Answer:
Update:
For 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.") } 
+120
Feb 21 '15 at 10:02
source share

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

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 } 
+54
Apr 24 '16 at 19:38
source share

Xcode 8 Swift 3 read json from update file:

  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 {} } 
+23
25 sept. '16 at 15:33
source share

Updated Swift 3.0 Names

Based on Abhishek's Answer and Druva's Answer

 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 } 
+14
Sep 22 '16 at 21:17
source share

Swift 2.1 answer (based on Abhishek's):

  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 {} } 
+10
Nov 08 '15 at
source share

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

Output:

 Name: Bob, age: 16, employed: No Name: Vinny, age: 56, employed: Yes 
+10
Nov 13 '16 at 3:29
source share

It worked great with me.

 func readjson(fileName: String) -> NSData{ let path = NSBundle.mainBundle().pathForResource(fileName, ofType: "json") let jsonData = NSData(contentsOfMappedFile: path!) return jsonData! } 
+7
Mar 07 '15 at 16:20
source share
 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 } 

πŸ‘†πŸ» ready to copy, third-party platform-independent solution.

use πŸ‘‡πŸ»

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

+7
Feb 02 '17 at 22:27
source share

Here is my solution using SwiftyJSON

 if let path : String = NSBundle.mainBundle().pathForResource("filename", ofType: "json") { if let data = NSData(contentsOfFile: path) { let json = JSON(data: data) } } 
+6
May 30 '15 at 15:48
source share

I give a different answer, because none of them is designed to load a resource from a test package. If you use a remote service that uses JSON and want to perform unit testing, analyzing the results without affecting the real service, you take one or more answers and put them in files in the "Tests" folder in your project.

 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 is also used here, but the basic logic for getting the test package and downloading the file is the answer to the question.

+5
May 27 '15 at 5:05
source share

Latest fast 3.0 fully works

 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 } 
+3
Jan 20 '17 at 10:59 on
source share

Updated for Swift 3 in a secure way.

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

enter image description here

+2
Aug 02 '17 at 10:01 on
source share

Based on Abhishek's Answer , for iOS 8 it will be:

 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 
+1
Jun 30 '15 at 19:24
source share

This worked for me with 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) } } } 
+1
03 Sep '17 at 19:14
source share

Swift 4.1 updated 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 } } 
+1
Jul 10 '18 at 12:09
source share

Swift 4: try my solution:

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 } 

Decoded + 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) } } 

Example:

 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") */ 
+1
Jan 04 '19 at 11:03
source share

I used the code below to get JSON from the FAQ-data.json file present in the project directory.

Im implements in Xcode 7.3 using 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 file structure:

 { "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 } . . . ] } } 
0
Jul 27 '16 at 12:58
source share

I can also recommend the Ray Wenderlich Swift JSON Tutorial (which also addresses the awesome alternative to SwiftyJSON, Gloss ). Excerpt (which in itself does not give a complete answer to the poster, but the added value of this answer is a link, so there is no -1 for this, please):

In Objective-C, parsing and deserializing JSON is pretty simple:

 NSArray *json = [NSJSONSerialization JSONObjectWithData:JSONData options:kNilOptions error:nil]; NSString *age = json[0][@"person"][@"age"]; NSLog(@"Dani age is %@", age); 

In Swift, parsing and deserializing JSON is a bit tedious due to Swift's capabilities and security type [but how] Swift 2.0 introduced the guard statement to help get rid of nested 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 age is \(age)") 

Of course, in Xcode 8.x, you just double-tap the space bar and say β€œHey Siri, please deserialize this JSON for me in Swift 3.0 with spaces / tabs”.

0
Sep 01 '16 at 17:26
source share

SWIFTYJSON VERSION 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 } 
0
Jan 29 '17 at 19:07
source share

First create an encoded Struc as follows:

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

Now declare a variable

  var jzdosList = [JuzgadosList]() 

Read from the main directory

 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.") } } 

Read from the Internet

 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() } 
0
Oct. 20 '18 at 10:01
source share



All Articles