I'm trying to add annotations on the map using a list of locations coming from the server.
Json Data:
[{ "_id" : "589f3e299b64795df23a886b",
"name" : "Store 1",
"description" : "Most awesome store!",
"location" : {
"longitude" : -6.279025369998967,
"latitude" : 53.35487382895707
}
},
{
"_id" : "589f3e299b64795df23a886b",
"name" : "Store 2",
"description" : "Most awesome store!",
"location" : {
"longitude" : -6.267085527951536,
"latitude" : 53.33785738724761
}
}]
I am using alamo fire to send a get request from the server to get the json data above in the viewWillAppear method.
override func viewWillAppear(_ animated: Bool) {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.requestLocation()
mapView.showsUserLocation = false
var currentLocation = Location()
if let location = locationManager.location {
currentLocation = Location(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
}
//default to 10 km radius for now
let params = [
"latitude": currentLocation.getLatitude(),
"longitude": currentLocation.getLongitude(),
"radius": 10.0
] as [String : Any]
Alamofire.request("http://website.com/fyp/searchNearbyStores", parameters: params).responseJSON { response in
switch response.result {
case .success(let value):
let result = JSON(value)
print(result)
self.storeList = result.arrayValue.map({
Store(name: $0["name"].stringValue, description: $0["description"].stringValue, location: CLLocationCoordinate2D(latitude: $0["location"]["latitude"].doubleValue, longitude: $0["location"]["longitude"].doubleValue))
})
case .failure(let error):
print(error)
}
}
}
And finally in the viewDidLoad method I use the storeList with the lat/long data to add the annotations.
override func viewDidLoad() {
super.viewDidLoad()
//zoom to current user location
if let location = locationManager.location {
let span = MKCoordinateSpanMake(0.01, 0.01)
let region = MKCoordinateRegion(center: location.coordinate, span: span)
mapView.setRegion(region, animated: true)
}
for store in storeList {
let annotation = MKPointAnnotation()
annotation.title = store.getName()
annotation.subtitle = store.getDescription()
annotation.coordinate = store.getLocation()
mapView.addAnnotation(annotation)
}
}
For some reason the annotations doesnt seem to show in the map when I run it. I seem to be doing the right way of adding annotations but maybe missed a small but important bit. Can anyone help?
You are using viewWillAppear wrong. You should make a request in viewDidLoad and do this inside request function (after data is loaded)
if let location = locationManager.location {
let span = MKCoordinateSpanMake(0.01, 0.01)
let region = MKCoordinateRegion(center: location.coordinate, span: span)
mapView.setRegion(region, animated: true)
}
for store in storeList {
let annotation = MKPointAnnotation()
annotation.title = store.getName()
annotation.subtitle = store.getDescription()
annotation.coordinate = store.getLocation()
mapView.addAnnotation(annotation)
}
because viewDidLoad is called before viewWillAppear, and because Alamofire request is async, which means, that it will be finished after viewDidLoad and viewWillAppear. So what happens is your array is empty, when you add annotations, and when your data is downloaded - nothing happens
Related
I am uploading multiple images as well as JSON data using "Content-type": "multipart/form-data"
my issue is, I have nested objects to pass to the parameters
I was looking for a solution, and what I find is nested data with an array of String or Int, not another custom object (I was struggling with it for so long)
struct Car: Codable{
var id :Int,
var name:String,
var address:String,
var new:Bool
var users:[User]
}
struct User: Codable{
var id :Int,
var name:String,
var address:String,
var age:Int
}
I wanted to convert the data to do a dictionary to use it as parameters
func addNewCae(newCar:Car, images:[UIImage]){
let encoder = JSONEncoder()
let jsonData = try! encoder.encode(newCar)
let test = convertStringToDictionary(text: jsonData)
print(test)
let headers: HTTPHeaders
headers = ["Content-type": "multipart/form-data",
"Content-Disposition" : "form-data"]
AF.upload(multipartFormData: { multipartFormData in
for imageData in images {
guard let imgData = imageData.pngData() else { return }
multipartFormData.append(imgData , withName: "images[]", fileName: "image.jpeg", mimeType: "image/jpeg")
}
for (key, value) in self.convertStringToDictionary(text: jsonData)! {
multipartFormData.append("\(value)".data(using: .utf8)!, withName: key)
}
},to: "\(url)", usingThreshold: UInt64.init(),
method: .post,
headers: headers).responseString{ response in
switch response.result {
case .success(let value):
print(value)
break
case .failure(let error):
print(error)
}
}
}
func convertStringToDictionary(data: Data) -> [String:AnyObject]? {
do {
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:AnyObject]
return json
} catch {
print("Something went wrong")
}
return nil
}
As a request of my code: all the car fields are registered in the database except the users' field
(in reality, I have more fields than that)
Why the users' field is not added to the parameters?
Any idea?
The users filed normally be of type [[String: AnyObject]] in the parameters
here is the data after I convert it to a dictionary
Optional(["name":"whatever" , "address": "here", "users": <__NSArrayM 0x6000008e4f90>(
{
"name" = "hello";
"address" = "there";
"age" = 20;
},
{
"name" = "hi";
"address" = "location";
"age" = 25;
}
)
, "new": 0])
hope am clear enough, I can add any further code or information if needed to be clearer
Thanks
Update
I did the encoding manually so now I have a correct dictionary format of type [String: AnyObject] but one of them is nested :
["name":"whatever" , "address": "here", "users": [
[
"name" = "hello";
"address" = "there";
"age" = 20;
],
[
"name" = "hi";
"address" = "location";
"age" = 25;
]
]
, "new": 0]
BUT, still, the "users" field is not able to be read, I think because the parameters don't support that kind of type?
Anyone have any other idea how to deal with these nested objects?
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)
}
}
}
}
}
}
}
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 !
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.
Alamofire.request("YOUR_URL", method:.post, parameters:params, encoding:URLEncoding.default, headers: nil).responseJSON { response in
switch(response.result)
{
case .success(_):
if response.result.value != nil
{
let dict :NSDictionary = response.result.value! as! NSDictionary
print(dict)
let status = dict.value(forKey: "status")as! String
print(status)
if(status=="1")
{
self.array_placeRequestId=((dict.value(forKeyPath: "result.request_id") as! NSArray).mutableCopy() as! NSMutableArray)
}
else
{
print("Something Missed")
}
}
break
case .failure(_):
print(response.result.error)
break
}
}
I have a problem since last 2 days. I can't get my JSON transformed to a Realm Object.
I have a json like below:
{
"gender" : "male",
"id" : "123456789",
"age_range" : {
"min" : 21
},
"last_name" : "LastName"
}
I have this Realm Models:
class UserObject: Object {
dynamic var userId: String = ""
dynamic var lastName: String?
dynamic var gender: String?
var ageRange = List<AgeRangeObject>()
required convenience init?(_ map: Map) {
self.init()
}
}
class AgeRangeObject: Object {
dynamic var min: Int = 0
}
And the way I am trying to create an instance of this model with ObjectMapper to parse json to dictionary and then create the model instance:
let userJSONModel = Mapper<User>().map(jsonString)
let realm = try! Realm()
do {
try realm.write {
let dict: [String : AnyObject] = [
"userId" : (userJSONModel?.userId)!,
"ageRange" : (userJSONModel?.ageRange)!,
"lastName" : (userJSONModel?.lastName)!,
"gender" : (userJSONModel?.gender)!
]
let userModel = UserObject(value: dict)
realm.add(userModel)
}
} catch {
print("Exception")
}
The problem occurs on this line: let userModel = UserObject(value: dict)
I get the folowing error:
*** Terminating app due to uncaught exception 'RLMException', reason: 'Invalid value 'min' to initialize object of type 'AgeRangeObject': missing key 'min''
I was looking on the stackoverflow:
Nested Arrays throwing error in realm.create(value: JSON) for Swift
How to convert Realm object to JSON with nested NSDate properties?
but my case is different.
Do you know what's the problem with that age range dictionary? Why it can't parse it well?
Thank you.
In your JSON, ageRange is a dictionary, whereas the UserObject.ageRange property is a List<AgeRangeObject>. You have mismatched models.
You either need to update your models to reflect the structure of your JSON:
var ageRange = List<AgeRangeObject>()
becomes
dynamic var ageRange: AgeRangeObject? = nil
or vice versa, update your JSON to reflect the structure of your models:
{
"gender" : "male",
"id" : "123456789",
"age_range" : [{
"min" : 21
}],
"last_name" : "LastName"
}
{
"key1" : "value1",
"key2" : "value2",
"array1" : [{
"key" : value
}],
"key3" : "value3"
}
For this you could use ObjectMapper's TransformType.
Reference: https://github.com/APUtils/ObjectMapperAdditions
My Code:
#objcMembers class RealmObject: Object, Mappable {
dynamic var listValues = List<MyRealmObject>()
required convenience init?(map: Map) {
self.init()
}
// Mappable
func mapping(map: Map) {
listValues <- (map["listValues"], RealmlistObjectTransform())
}
}
#objcMembers class MyRealmObject: Object, Mappable {
required convenience init?(map: Map) {
self.init()
}
// Mappable
func mapping(map: Map) {
}
}
class RealmlistObjectTransform: TransformType {
typealias Object = List<MyRealmObject> // My Realm Object here
typealias JSON = [[String: Any]] // Dictionary here
func transformFromJSON(_ value: Any?) -> List<MyRealmObject>? {
let list = List<MyRealmObject>()
if let actors = value as? [[String: Any]] {
let objects = Array<MyRealmObject>(JSONArray: actors)
list.append(objectsIn: objects)
}
return list
}
func transformToJSON(_ value: List<MyRealmObject>?) -> [[String: Any]]? {
if let actors = value?.sorted(byKeyPath: "").toArray(ofType: MyRealmObject.self).toJSON() {
return actors
}
return nil
}
}
I am trying to query Firebase to check if any user that has waiting: "1" and then when the snapshot is returned I want to see whether it is equal to nil. I have attempted to do this but the method I have used does not work and I only have some sort of out put if the snapshot is not equal to nil. I have added the code I currently have and the JSON text from Firebase.
import UIKit
import Firebase
import Spring
class GamesViewController: UIViewController {
let ref = Firebase(url: "https://123test123.firebaseio.com")
var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
#IBAction func StartGamePressed(sender: AnyObject) {
print("test1")
var peopleWaiting: [String] = []
let userRef = Firebase(url:"https://123test123.firebaseio.com/users")
userRef.queryOrderedByChild("waiting").queryEqualToValue("1")
.observeEventType(.ChildAdded, withBlock: { snapshot in
print(snapshot.key)
if snapshot.key == nil {
print("test2")
let userData = ["waiting": "1"]
let usersRef = self.ref.childByAppendingPath("users")
let hopperRef = usersRef.childByAppendingPath("\(self.ref.authData.uid)")
hopperRef.updateChildValues(userData, withCompletionBlock: {
(error:NSError?, ref:Firebase!) in
if (error != nil) {
print("Data could not be saved.")
self.displayAlert("Oops!", message: "We have been unable to get you into a game, check you have an internet conection. If this problem carries on contect support")
} else {
print("Data saved successfully!")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let Home : UIViewController = storyboard.instantiateViewControllerWithIdentifier("continueToGame")
self.presentViewController(Home, animated: true, completion: nil)
}
})
} else {
var randomUID: String
peopleWaiting.append(snapshot.key)
let randomIndex = Int(arc4random_uniform(UInt32(peopleWaiting.count)))
randomUID = peopleWaiting[randomIndex]
print(randomUID)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let Home : UIViewController = storyboard.instantiateViewControllerWithIdentifier("continueToGame")
self.presentViewController(Home, animated: true, completion: nil)
}
})
}
func displayAlert(title: String, message: String){
let formEmpty = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
formEmpty.addAction((UIAlertAction(title: "Ok", style: .Default, handler: { (action) -> Void in
})))
self.presentViewController(formEmpty, animated: true, completion: nil)
}
func activityIndicatorFunction(){
activityIndicator = UIActivityIndicatorView(frame: CGRectMake(0, 0, 100, 100))
activityIndicator.backgroundColor = UIColor(red:0.16, green:0.17, blue:0.21, alpha:1)
activityIndicator.layer.cornerRadius = 6
activityIndicator.center = self.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge
view.addSubview(activityIndicator)
activityIndicator.startAnimating()
UIApplication.sharedApplication().beginIgnoringInteractionEvents()
}
}
JSON Data:
{
"68e42b7f-aea5-4c3f-b655-51a99cb05bb0" : {
"email" : "test1#test1.com",
"username" : "test1",
"waiting" : "0"
},
"8503d5a8-fc4a-492b-9883-ec3664898b4f" : {
"email" : "test2#test2.com",
"username" : "test2",
"waiting" : "0"
}
}
There are a few things going on here, but the most important one is that you cannot test for the existence of children with .ChildAdded. That makes sense if you think about it: the .ChildAdded event is raised when a child is added to the location. If no child is added, the event won't be raised.
So if you want to test if a child exists at a location, you need to use .Value. Once you do that, there are various way to detect existence. Here's one:
ref.queryOrderedByChild("waiting").queryEqualToValue("1")
.observeEventType(.Value, withBlock: { snapshot in
print(snapshot.value)
if !snapshot.exists() {
print("test2")
}
});
Check for NSNull. This is the code for observing a node. Queries work much the same way.
Here's a complete and tested app. To use, change the string 'existing' to some path you know exists, like your users path and the 'notexisting' to some path that does not exist
let myRootRef = Firebase(url:"https://your-app.firebaseio.com")
let existingRef = myRootRef.childByAppendingPath("existing")
let notExistingRef = myRootRef.childByAppendingPath("notexisting")
existingRef.observeEventType(.Value, withBlock: { snapshot in
if snapshot.value is NSNull {
print("This path was null!")
} else {
print("This path exists")
}
})
notExistingRef.observeEventType(.Value, withBlock: { snapshot in
if snapshot.value is NSNull {
print("This path was null!")
} else {
print("This path exists")
}
})
Please note that by using .Value, there will be a guaranteed a return result and the block will always fire. If your code used .ChildAdded then the block will only fire when a child exists.
Also, check to make sure of how your data appears in firebase.
users
user_0
waiting: 1
if different than
users
user_0
waiting: "1"
Note that "1" is not the same as 1.
Using swift 1.2, xcode 6.3 and IOS 8, Im trying to build an object from a json response using NSJSONSerialization class.
the json response is:
[{
"_id" : "5470def9e0c0be27780121d7",
"imageUrl" : "https:\/\/s3-eu-west-1.amazonaws.com\/myapi-static\/clubs\/5470def9e0c0be27780121d7_180.png",
"name" : "Mondo",
"hasVip" : false,
"location" : {
"city" : "Madrid"
}
}, {
"_id" : "540b2ff281b30f3504a1c72f",
"imageUrl" : "https:\/\/s3-eu-west-1.amazonaws.com\/myapi-static\/clubs\/540b2ff281b30f3504a1c72f_180.png",
"name" : "Teatro Kapital",
"hasVip" : false,
"location" : {
"address" : "Atocha, 125",
"city" : "Madrid"
}
}, {
"_id" : "540cd44581b30f3504a1c73b",
"imageUrl" : "https:\/\/s3-eu-west-1.amazonaws.com\/myapi-static\/clubs\/540cd44581b30f3504a1c73b_180.png",
"name" : "Charada",
"hasVip" : false,
"location" : {
"address" : "La Bola, 13",
"city" : "Madrid"
}
}]
the object class (Club.swift) with the NSJSONSerialization.JSONObjectWithData implementation is:
class Club: NSObject {
var id: String = ""
var name: String = ""
var imageUrl: String = ""
var hasVip: Bool = false
var desc: String = ""
var location: [Location] = []
init(JSONString: String) {
super.init()
var error : NSError?
let JSONData = JSONString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let JSONDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(JSONData!, options: nil, error: &error) as! NSDictionary
self.setValuesForKeysWithDictionary(JSONDictionary as [NSObject : AnyObject])
}
}
and finally the ApiClient class is
class ApiClient {
func getList(completionHandler: ([JSON]) -> ()) {
let URL = NSURL(string: "https://myapi.com/v1/clubs")
let mutableURLRequest = NSMutableURLRequest(URL: URL!)
mutableURLRequest.setValue("Content-Type", forHTTPHeaderField: "application/json")
mutableURLRequest.HTTPMethod = "GET"
mutableURLRequest.setValue("Bearer R01.iNsG3xjv/r1LDkhkGOANPv53xqUFDkPM0en5LIDxx875fBjdUZLn1jtUlKVJqVjsNwDe1Oqu2WuzjpaYbiWWhw==", forHTTPHeaderField: "Authorization")
let manager = Alamofire.Manager.sharedInstance
let request = manager.request(mutableURLRequest)
request.responseJSON { (request, response, json , error) in
if (json != nil){
var jsonObj = JSON(json!)
if let data = jsonObj["hits"].arrayValue as [JSON]?{
var aClub : Club = Club(JSONString: data)
println(aClub.name)
completionHandler(data)
}
}
}
}
}
but the problem is when I try to println(aClub.name) the error is
"cannot invoke initializer for type'Club' with an argument list of type (JSONString [JSON])"
I dont know, how could I use NSJSONSerialization class with a complex JSON response.
The jsonObj would appear to be a SwiftyJSON object, or something like that, which one uses in lieu of NSJSONSerialization, not in conjunction with it. The data variable is an array of JSON objects (i.e. it's a [JSON]), not a string.
But you're using Alamofire's responseJSON method, which does the JSON parsing for you. So you don't need to use either NSJSONSerialization or SwiftyJSON. It's already parsed it into an array of dictionaries.
If you want an array of Club objects, you could do can just iterate through this array, building Club objects from the dictionaries:
class ApiClient {
func getList(completionHandler: ([Club]?, NSError?) -> ()) {
let URL = NSURL(string: "https://myapi.com/v1/clubs")
let mutableURLRequest = NSMutableURLRequest(URL: URL!)
mutableURLRequest.setValue("Content-Type", forHTTPHeaderField: "application/json")
mutableURLRequest.HTTPMethod = "GET"
mutableURLRequest.setValue("Bearer R01.iNsG3xjv/r1LDkhkGOANPv53xqUFDkPM0en5LIDxx875fBjdUZLn1jtUlKVJqVjsNwDe1Oqu2WuzjpaYbiWWhw==", forHTTPHeaderField: "Authorization")
let manager = Alamofire.Manager.sharedInstance
let request = manager.request(mutableURLRequest)
request.responseJSON { (request, response, json, error) in
var clubs = [Club]()
if let arrayOfDictionaries = json as? [[String: AnyObject]] {
for dictionary in arrayOfDictionaries {
clubs.append(Club(dictionary: dictionary))
}
completionHandler(clubs, nil)
} else {
completionHandler(nil, error)
}
}
}
}
You obviously have to change Club to handle the dictionary object:
class Club {
var id: String!
var name: String!
var imageUrl: String!
var hasVippler: Bool!
var location: [String: String]!
init(dictionary: [String: AnyObject]) {
id = dictionary["_id"] as? String
name = dictionary["name"] as? String
imageUrl = dictionary["imageUrl"] as? String
hasVippler = dictionary["hasVip"] as? Bool
location = dictionary["location"] as? [String: String]
}
}
Finally, your table view controller could call the API:
let apiClient = ApiClient()
var clubs: [Club]!
override func viewDidLoad() {
super.viewDidLoad()
apiClient.getList() { clubs, error in
if clubs != nil {
self.clubs = clubs
self.tableView.reloadData()
} else {
println(error)
}
}
}