0

I'm learning swift.

I have a json from server.

[
  {
    "dId": 1,
    "vendor": {
      "vendorId": 1,
      "name": "Gems",
      "about": "Get Good quality stones",
      "address": "JacksonVille Road",
      "latitude": 12.232323,
      "longitude": 77.230802,
    },
    "name": "Gems Delight",
  }
]

I'm unable to parse this json and get the data from lat and lon and name from vendor.

My url method and my for loop how can I exactly get the latitude and longitude from the loop and put them on the map ?

My View did load method

       override func viewDidLoad() {
        super.viewDidLoad()

        guard let gitUrl = URL(string: "localhost:8080/deals") else { return }
        URLSession.shared.dataTask(with: gitUrl) { (data, response
            , error) in
            guard let data = data else { return }
            do {
                let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)

                var lat:Double
                var lon:Double
                var nam = ""
                for items in json as! [AnyObject]{
//                    let te = type(of: items)
//                    print(te)
                    let new = items["vendor"]

                    for (it,key) in new as! [String:Any]{
//                        print(it,key)
//                        print(it["longitude"])

                        if it == "longitude"{
                            print(it,key)
                            lon = key as! Double
                        }
                        if it == "latitude"{
                            print(it,key)
                            lat = key as! Double
                        }

                        if it == "name"{
                            nam = key as! String


                        }

                            if (nam.isEmpty == false){
                            print("falsdalsdasldasd")
                            self.locationManager.delegate = self
                            self.locationManager.requestWhenInUseAuthorization()
                            self.locationManager.startUpdatingLocation()
                            let camera = GMSCameraPosition.camera(withLatitude:lat, longitude:lon, zoom: 4.0)
                            let subView = GMSMapView.map(withFrame: self.view.bounds,camera:camera)
                            let marker = GMSMarker()
                            marker.position = CLLocationCoordinate2D(latitude:lat, longitude:lon)
                            marker.title = nam
                            //                        marker.snippet = "Australia"
                            marker.map = subView

                            self.mapView.addSubview(subView)
                        }




//                        print(it["longitude"])

                    }
//                    let te = type(of: items)
//                    for it in new as![AnyObject]{
////                        print(it"])
//                        print(it)
//
//                    }
//                    print(items["vendor"].["latitude"])
//                    print(items.vendor)
//                    print(items[""])
//                    let nam = items["name"];
//                    let desc = items["description"];
//                    self.locationNames.append(nam as! String)
//                    self.locationDescription.append(desc as! String)
//

                }
//                self.colecVw.delegate = self
//                self.colecVw.dataSource = self
//                self.colecVw.reloadData()

                //                }

            } catch let err {
                print("Err", err)
            }
            }.resume()


        print("coming here")


        //         Create a GMSCameraPosition that tells the map to display the
        //         coordinate -33.86,151.20 at zoom level 6.
        //       let mapView = GMSMapView(frame: CGRect(x: 0, y: 64, width: self.currentDeviceSize.width, height: self.bottomBgView.frame.minY - 64))
//        view = mapView
//
//        // Creates a marker in the center of the map.
//        let marker = GMSMarker()
//        marker.position = CLLocationCoordinate2D(latitude: -33.86, longitude: 151.20)
//        marker.title = "Sydney"
//        marker.snippet = "Australia"
//        marker.map = mapView    
    }

Please help me as I'm learning to code my code might not be correct can please dont mind and load the data of lat and long onto the map. Should I construct an object and put them there ?

Variable 'lon' used before being initialized
Variable 'lat' used before being initialized

This is the error I get from the code.

5
  • what does the print(it,key) print? Commented Dec 6, 2018 at 11:00
  • It prints correctly once it goes through if condition Commented Dec 6, 2018 at 11:03
  • Then what is the issue if it prints correctly? Commented Dec 6, 2018 at 11:05
  • I need to put the lat and long on the google map Commented Dec 6, 2018 at 11:07
  • let camera = GMSCameraPosition.camera(withLatitude:lat, longitude:lon, zoom: 4.0) in the line here! Commented Dec 6, 2018 at 11:07

3 Answers 3

3

The errors occur because lat and lon must have a value in the line

let camera = GMSCameraPosition.camera(withLatitude:lat, longitude:lon, zoom: 4.0)

which is not guaranteed if the key comparisons fail.

The condition is fulfilled if you write

var lat = 0.0 // The type Double is inferred
var lon = 0.0

But rather than enumerating the dictionary get the values for the keys directly and safely with optional binding

do {
    // no mutableContainers !!
    let json = try JSONSerialization.jsonObject(with: data) as! [[String:Any]]

    for item in json {
        if let vendor = item["vendor"] as? [String:Any],
            let lat = vendor["latitude"] as? Double,
            let lon = vendor["longitude"] as? Double,
            let name = item["name"] as? String, !name.isEmpty {

            print("falsdalsdasldasd")
            // self.locationManager.delegate = self
            // self.locationManager.requestWhenInUseAuthorization()
            // self.locationManager.startUpdatingLocation()
            let camera = GMSCameraPosition.camera(withLatitude:lat, longitude:lon, zoom: 4.0)
            let subView = GMSMapView.map(withFrame: self.view.bounds,camera:camera)
            let marker = GMSMarker()
            marker.position = CLLocationCoordinate2D(latitude:lat, longitude:lon)
            marker.title = name
            marker.map = subView
            self.mapView.addSubview(subView)
        }
    }
} catch {
    print("Err", error)
}

And it's nonsensical to call the LocationManager methods in each iteration. Call them once at the beginning of viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()
    self.locationManager.delegate = self
    self.locationManager.requestWhenInUseAuthorization()
    self.locationManager.startUpdatingLocation()

...
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks ++ it helped me
1

You can try

struct Root: Codable {
    let dID: Int
    let vendor: Vendor
    let name: String

    enum CodingKeys: String, CodingKey {
        case dID = "dId"
        case vendor, name
    }
}

struct Vendor: Codable {
    let vendorID: Int
    let name, about, address: String
    let latitude, longitude: Double

    enum CodingKeys: String, CodingKey {
        case vendorID = "vendorId"
        case name, about, address, latitude, longitude
    }
}

--

let arr = try? JSONDecoder().decode([Root].self, from:data)

print(arr?.forEach {$0.vendor.latitude })

Comments

0

See this one

 let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)

Pass json to

 if let data = json as? NSArray {
    for data in data {
        if let data = data as? [String: AnyObject] {
            let dataID = data["dId"] as? Int

            if let data = data[“vendor”] as? [String: AnyObject] {
                let vendorID = data["vendorId"] as? Int
            }
        }
    }
}

enter image description here

9 Comments

It still doesn't work. And don't use NSArray and mutableContainers in Swift anyway (which is not the failure reason by the way).
if you pass proper json then definately it will work. I have tried it
It cannot work with the given JSON in the question. Don't adjust the JSON. Adjust the code! 😉 And in Swift 3+ a JSON value is never AnyObject, it's Any
For your clarification I have added image. Please look into it. May be I would be wrong with some standard but its working
No, it doesn't, print vendorID. And data in data is confusing and bad habit (along with the other bad habits).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.