Dakata Dakata - 1 year ago 50
JSON Question

How to compare user'r current location to other locations and display them in UITable View?

I am developing an app in swift and I have to compare user's current location to the other locations taken from a JSON file. Then I have to display all of the locations which are in a certain range from the user's location. This range I take from a UISlider. I mean when the user selects 25km in the slider, the app has to determine the current user's location and display all of the fruits which are in this range.

import UIKit
import SwiftyJSON
import MapKit
import CoreLocation

class TableViewController: UITableViewController,CLLocationManagerDelegate {
@IBOutlet weak var Bar: UIToolbar!

@IBOutlet weak var LabelTest: UILabel! // this is the slider value, I segue it from the previous viewcontroller
var manager = CLLocationManager()

struct Fruit {
let name : String
let location : CLLocation
let imageURL : NSURL
let description : String
var fruits = [Fruit]()

func parseFruits() {
guard let url = NSBundle.mainBundle().URLForResource("cities", withExtension: "json"), jsonData = NSData(contentsOfURL: url) else {
print("Error finding JSON File")

let jsonObject = JSON(data: jsonData)

let fruitArray = jsonObject["fruits"].arrayValue
for aFruit in fruitArray {
let name = aFruit["Name"].stringValue
let latitude = city["Latitude"] as! Double
let longitude = city["Longitude"] as! Double
let location = CLLocation(latitude: latitude, longitude: longitude)
let imageURL = aFruit["Picture"].stringValue
let description = aFruit["Description"].stringValue

let fruit = Fruit(name: name,location: location,imageURL: NSURL(string:imageURL)!, description: description )


override func viewDidLoad() {

// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false

// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()

override func didReceiveMemoryWarning() {
// Dispose of any resources that can be recreated.

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fruits.count

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: TableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") as! TableViewCell
let fruit = fruits[indexPath.row]
cell.CellTitle.text = fruit.name
cell.CellDescription.text = fruit.description

let image = UIImage(data: NSData(contentsOfURL:(string: fruit.imageURL))!)
cell.CellImage.image = image

return cell

Currently I am not calculating the user's current location and I am not comparing it, I would be glad if someone can show me how to do that.


func CalculateDistance() {
let userLocation = CLLocation(latitude: lat, longitude: long)
let destinationLocation = CLLocation(latitude:latitude, longitude: longitude)// latitude and longitude from the json file
let distance = userLocation.distanceFromLocation(destinationLocation)

Answer Source

When you want to calculate the distance between two locations you can do the following:

let userLocation = CLLocation(latitude: lat, longitude: long)
let destinationLocation = CLLocation(latitude: (dest.lat as NSString).doubleValue, longitude: (dest.long as NSString).doubleValue)
let distance = userLocation.distanceFromLocation(destinationLocation)

Get the userLocation which is the current location of the user. Then you have the location of the destination and then calculate the distance with the help of the distanceFromLocation function which is a part of CoreLocation.

Then I have done a method that rounds the distance to nearest 5 meters:

var distanceToFive = roundToFive(distance)

private func roundToFive(x : Double) -> Int {
    return 5 * Int(round(x / 5.0))

You can of course change this to 10, 20 etc.

And to get the current location:
Add the CLLocationManagerDelegate to the class inheritance. Declare var locationManager = CLLocationManager() and two variables one for lat and one for long. In viewDidLoad do

    if CLLocationManager.locationServicesEnabled() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest

And then to get the location for the user declare the following methods:

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location:CLLocationCoordinate2D = manager.location!.coordinate
        lat = location.latitude
        long = location.longitude

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {