Search code examples
iosarraysjsonswiftcllocation

Print Array By Location shows up empty


The objective is this:

  • Calculate the lat and long of each item in my array
  • Append the lat and long to an array
  • Print all items in the array in the max distance.

Here is how I'm pulling data in:

import Foundation
import SwiftyJSON

class restaurant {

    //Json
     var id: Int!
     var name: String!
     var address: String!
     var city: String!
     var logo: String!
     var state: String!
     var postKey: String!


    //Second
    var ids: Int!
    var names: String!
    var aAddress: String!
    var citys: String!
    var logos: String!
    var states: String!

    var distance : Double = 0

    //Importing data from server. Bring moto. Make sure you are able to get details in postman prior to adding any other variables
    init(json: JSON) {
        self.id = json["id"].int
        self.name = json["dispensary_name"].string
        self.address = json["street_address"].string
        self.logo = json["logo"].string
        self.city = json["city"].string
        self.state = json["state"].string
    }

    init(postKey: String, postData: Dictionary<String, AnyObject>) {
        self.postKey = postKey

//        self.ids = postData[self.id]?.int
        self.names = postData[self.name]?.string
        self.aAddress = postData[self.address]?.string
        self.citys = postData[self.city]?.string
        self.logos = postData[self.logo]?.string
        self.states = postData[self.state]?.string
    }
}

Here is my array: //Loads list of restaurants.

func loadRestaurants() {
    Helpers.showActivityIndicator(activityIndicator, view)

    APIManager.shared.getRestaurants { (json) in
        if json != nil {
            self.restaurants = []
                //Adds all items into the array list dist then goes through them all.
            if let listDis = json["restaurant"].array {
                for item in listDis {

                    let address = item["street_address"].string! + ", " + item["city"].string! + ", " + item["state"].string!

                    self.getLocation(address, { (dis) in
                                        self.disLocation = dis
                    })

                    //snap = item, snapshot = listdict

                    if let snapValue = item.array as? [String:AnyObject],
                       let venueLat = self.disLocation?.coordinate.latitude,
                       let venueLong = self.disLocation?.coordinate.longitude {
                        print("snapValue ,", snapValue)
                        let distance = self.calculateDistance(userlat: self.userLatt, userLon: self.userLonn, venueLat: venueLat, venueLon: venueLong)

                        if distance <= 15 {
                            let key = item.string
                            let restaurant = Restaurant(postKey: key!, postData: snapValue)
                            restaurant.distance = distance
                            self.restaurants.append(restaurant)
                            print("restaurant :", snapValue)
                        }
                    }
                }

                if self.restaurants.count == 0 {
                    let alert = UIAlertController(title: "Oh No!!!", message: "We Only Deliver To New Jersey", preferredStyle: UIAlertControllerStyle.alert)
                    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
                         }))
                    self.present(alert, animated: true, completion: nil)
                }
                self.restaurants.sort {                                
                    $0.distance < $1.distance
                }
            }
            self.restaurants.reloadData()
            Helpers.hideActivityIndicator(self.activityIndicator)
        }
    }
}

I'm not sure what I should do here. Any advice would be helpful.

Output of Item:

"state" : "New Jersey",
  "city" : "Highland Park",
  "id" : 3,
  "dispensary_name" : "Down South Taste",
  "street_address" : "4422 knotwood ct",
  "zip_Code" : 56430,
  "phone" : "444-334-0888",


Solution

  • The init method you use for your Restaurant object (the second one) is clearly wrong and will lead to a runtime crash since you are unwrapping nil values.

    self.names = postData[self.name]?.string 
    

    name is nil here but declared as

    var name: String!
    

    I don't really understand what you're trying to achieve when reading a dictionary using properties as keys instead of string constants?

    Maybe do something like

    let nameKey = "dispensary_name"
    ...
    
    self.names = postData[nameKey]?.string 
    

    If I understand it correctly your program doesn't crash which tells us that the constructor is never called. My guess is that it is the condition in the surrounding if statement that fails and the first part of the condition looks wrong where you call .array on your json item and typecast the result as a dictionary

    if let snapValue = item.array as? [String:AnyObject], ...
    

    .array. looks wrong here and while I don't know your json format you earlier access the item property as a dictionary, isn't it item that is your dictionary.

    Hopefully this will help you to move forward.