swift 3 Calculate distance to current location and sort result from closet to furthest

末鹿安然 提交于 2019-12-12 04:34:51

问题


I'm trying to to calculate the distance from an event to my current location, sort the results and populate that in a tableview. I keep getting error for optional unwrapped value distance is nil.

     private func observeEvents() {
    refHandle = ref.observe(.childAdded, with: { (snapshot) -> Void in
        let eventDetails = snapshot.value as! Dictionary<String, AnyObject>
        let eventID = snapshot.key
        let location = eventDetails["location"] as! String!

        //calculating distance
        self.forwardGeocoding(address: location!)
        let distance = self.eventLocation?.distance(from: self.currentLocation!) as Double!
        //end calculating

        let dateTime = eventDetails["dateTime"] as! String!
        let addedByUser = eventDetails["addedByUser"] as! String!
        let attending = eventDetails["attendance"] as! String!
        if let name = eventDetails["eventName"] as! String! , name.characters.count > 0
        {

            self.events.append(Events(id:eventID, name: name, location: location!, dateTime: dateTime!, addedByUser: addedByUser!, attending: attending! , distance: distance!))
            self.events.sort(by: { $0.distance < $1.distance})

            self.tableView.reloadData()
        } else {
            print("Error ! Can't load events from database")
        }
    })
} //load events data to uitableview

I created a function to return a CLLocation from an address

      func forwardGeocoding(address: String) {
    CLGeocoder().geocodeAddressString(address, completionHandler: { (placemarks, error) in
        if error != nil {
            print(error!)
            return
        }
        if (placemarks?.count)! > 0 {
            let placemark = placemarks?[0]
            self.eventLocation = placemark?.location
        }
    })
}

回答1:


I finally figured out the answer. The issue was the function for distance is called asynchronously there for the result would always be nil. I created a completion handler for the forwardGeocoding function to return latitude and longitude from the address string and call the result inside the nested firebase listener. Here is the code, I hope if someone ran into something similar problem to me will find it helpful.

  //Get lat and long

func getCoordinates(address: String, completionHandler: @escaping (_ lat: CLLocationDegrees?, _ long: CLLocationDegrees?, _ error: Error?) -> ()) -> Void {

    var _:CLLocationDegrees
    var _:CLLocationDegrees
    let geocoder = CLGeocoder()
    geocoder.geocodeAddressString(address) { (placemarks: [CLPlacemark]!, error: Error!) in

        if error != nil {

            print("Geocode failed with error: \(error.localizedDescription)")

        } else if placemarks.count > 0 {

            let placemark = placemarks[0] as CLPlacemark
            let location = placemark.location

            let lat = location?.coordinate.latitude
            let long = location?.coordinate.longitude

            completionHandler(lat, long, nil)
        }
    }
}

Nested call in firebase listener

    refHandle = ref.observe(.childAdded, with: { (snapshot) -> Void in
    let location = event["address"] as! String          
    self.getCoordinates(address: location!) { lat, long, error in
            if error != nil {
                print("Error")
            } else {
                self.latitude = lat
                self.longitude = long
                let distance = CLLocation(latitude: self.latitude!,longitude: self.longitude!).distance(from: self.currentLocation!)

                if let name = eventDetails["eventName"] as! String! , name.characters.count > 0
                {

                    self.events.append(Events(id:eventID, name: name, location: location!, dateTime: dateTime!, addedByUser: addedByUser!, attending: attending!, distance: distance))

                    self.events.sort(by: { $0.distance < $1.distance})

                    self.tableView.reloadData()
                } else {
                    print("Error ! Can't load events from database")
                }

            }
        }
    })


来源:https://stackoverflow.com/questions/42991915/swift-3-calculate-distance-to-current-location-and-sort-result-from-closet-to-fu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!