Parsing JSON data from alamofire into Array with Dictionary
Solution 1
First of all you should create a class that is your model of Schedule
like this
class Schedule: NSObject {
var departureTime: String
var destination: String
var trainType: String
init(jsonDic : NSDictionary) {
self.departureTime = jsonDic["departureTime"] != nil ? jsonDic["departureTime"] as! String! : nil
self.destination = jsonDic["destination"] != nil ? jsonDic["destination"] as! String! : nil
self.trainType = jsonDic["trainType"] != nil ? jsonDic["trainType"] as! String : nil
}
}
And in your view controller your going to need an array of the Schedule
object and after you could parse your Json you do it like this:
class ScheduleController: UIViewController {
// The two object use to show the spinner loading
var loadingView: UIView = UIView()
var spinner = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge)
// Array of your objects
var arrSchedule: [Schedule] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.getInfoSchedule()
}
func getInfoSchedule() {
showActivityIndicator()
Alamofire.request("https://api.mynexttrainschedule.net/", method: .get, parameters: nil, encoding: URLEncoding.default, headers: nil).responseJSON {
response in
self.hideActivityIndicator()
switch response.result {
case .success:
if let objJson = response.result.value as! NSArray? {
for element in objJson {
let data = element as! NSDictionary
if let arraySchedule = data["schedule"] as! NSArray? {
for objSchedule in arraySchedule {
self.arrSchedule.append(Schedule(jsonDic: objSchedule as! NSDictionary))
}
}
}
}
case .failure(let error):
print("Error: \(error)")
}
}
}
//Those two method serves to show a spinner when the request is in execution
func showActivityIndicator() {
DispatchQueue.main.async {
self.loadingView = UIView()
self.loadingView.frame = CGRect(x: 0.0, y: 0.0, width: self.view.frame.width, height: self.view.frame.height)
self.loadingView.center = self.view.center
self.loadingView.backgroundColor = UIColor(rgba: "#111111")
self.loadingView.alpha = 0.9
self.loadingView.clipsToBounds = true
self.spinner = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge)
self.spinner.frame = CGRect(x: 0.0, y: 0.0, width: 80.0, height: 80.0)
self.spinner.center = CGPoint(x:self.loadingView.bounds.size.width / 2, y:self.loadingView.bounds.size.height / 2)
self.loadingView.addSubview(self.spinner)
self.view.addSubview(self.loadingView)
self.spinner.startAnimating()
}
}
func hideActivityIndicator() {
DispatchQueue.main.async {
self.spinner.stopAnimating()
self.loadingView.removeFromSuperview()
}
}
}
Maybe is not the more efficient way to do it, but it worked for me. I'm using swift3 with xcode 8.1.
Hope it helps !
Solution 2
Basically what you have is an array of schedules. You can map it using ObjectMapper. Install its pod and just create a new Swift file. and Write this
import ObjectMapper
class TrainSchedules: Mappable {
var mySchedules: [Schedules]
required init?(_ map: Map) {
mySchedules = []
}
func mapping(map: Map) {
mySchedules <- map["schedule"]
}
}
class Schedules: Mappable {
var departureTime: String
var destination: String
var trainType: String
required init?(_ map: Map) {
departureTime = ""
destination = ""
trainType = ""
}
func mapping(map: Map) {
departureTime <- map["departureTime"]
destination <- map["destination"]
trainType <- map["trainType"]
}
}
Now you can use it like
if let data = Mapper<TrainSchedules>().map(json){
// now data is an array containt=g all the schedules
// access departureTimelike below
print(data[0].departureTime)
}
I hope it helps, Letme know if you find any difficulty.
El Tomato
Updated on June 08, 2022Comments
-
El Tomato over 1 year
I'm trying to parse JSON data from alamorefire as follows.
import UIKit import Alamofire import SwiftyJSON class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() Alamofire.request(.GET, "https://api.mynexttrainschedule.net/") .responseJSON { response in guard let object = response.result.value else { print("Oh, no!!!") return } let json = JSON(object);print(json) let schedule = json[0]["schedule"] } } }
If I print json, I have a data structure like the following (stated concisely).
[ { "schedule" : [ {"departureTime" : "05:09", "destination" : "Boston", "trainType" : "Express"}, {"departureTime" : "05:19", "destination" : "Portland", "trainType" : "Rapid"}, {"departureTime" : "05:29", "destination" : "Boston", "trainType" : "Express""} ], "station" : "Grand Central", "direction" : "North" }, { "schedule" : [ {"departureTime" : "05:11","destination" : "Washington, "trainType" : "Express""}, {"departureTime" : "05:23","destination" : "Baltimore, "trainType" : "Express""}, {"departureTime" : "05:35","destination" : "Richmond, "trainType" : "Local""} ], "station" : "Grand Central", "direction" : "South" } ]
Now, how can I save the schedule array with a dictionary (departureTime, destination...) through or not through SwiftyJSON?
Thanks.
UPDATE
The following is my own solution.
import Alamofire import SwiftyJSON class ViewController: UIViewController { var scheduleArray = [Dictionary<String,String>]() override func viewDidLoad() { super.viewDidLoad() Alamofire.request(.GET, "https://api.mynexttrainschedule.net/") .responseJSON { response in guard let object = response.result.value else { print("Oh, no!!!") return } let json = JSON(object) if let jArray = json.array { if let westHolidayArray = jArray[0]["schedule"].array { for train in westHolidayArray { if let time = train["departureTime"].string, let dest = train["destination"].string, let type = train["trainType"].string { let dict = ["time":time, "dest":dest, "type": type] self.scheduleArray.append(d) } } } } } } }
-
El Tomato almost 7 yearsThanks. I get an error on '.map' (above print). It says 'Cannot invoke 'map' with an argument list of type (JSON)
-
Umair Afzal almost 7 yearsyou basically have to pass your jsonObject (result of service) to the function
-
El Tomato almost 7 yearsThanks. Where does 'dir' as in self.arrSchedule.append(Schedule(jsonDic: dir as! NSDictionary)) come from?
-
Snoobie almost 7 yearsI updated my answer it was
objSchedule
instead ofdir
sorry -
El Tomato almost 7 yearsThe app crashes with the following message: nw_host_stats_add_src recv too small, received 24, expected 28 . I saw the same error a few days. I don't remember what it was for, but I think it made me switch to Swift 2.3 under Xcode 7.
-
Snoobie almost 7 yearsWhich version of xcode you were using ? Because the version 8.0 has lot of troubles. Maybe it could be the reason.
-
El Tomato almost 7 yearsI get the error above under Xcode 8.1. I don't have trouble with alamofire 3.5.1 under Xcode 7.3.1.
-
Snoobie almost 7 yearsWell normally the logic is the same, just you should change the prototype of the
Alamofire.request
. Let me know if you could not solve it, and I will try to adapt the code with the version of Xcode and Swift that you have. -
El Tomato almost 7 yearsarrSchedule returns an empty array.
-
Snoobie almost 7 yearsHave you found a solution ? If it's not the case
https://api.mynexttrainschedule.net/
is the API that give you that Json ? -
El Tomato almost 7 yearsI have come up with my solution above. No, that's not an actual URL.
-
El Tomato over 6 yearsThere's already a solution if you read the question carefully.
-
Varinder Singh iPhone Dev over 3 yearswahh.. nice Answer