【问题标题】:Swift Firebase TableView distance from current userSwift Firebase TableView 与当前用户的距离
【发布时间】:2017-08-24 09:59:30
【问题描述】:

我正在尝试在标签中列出从当前用户到营业地点的距离。我不断收到错误消息 "fatal error: unexpectedly found nil while unwrapping an optional value" 并且我在 firebase 行上收到此错误,但我知道事实上我的所有内容都拼写正确并且调用可以获取值。我在线收到错误: "let lat = Double(locationValue["businessLatitude"] as! String)".

任何帮助将不胜感激

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! RegisteredLocationsCell
    let user : NSDictionary?

    if searchController.isActive && searchController.searchBar.text != ""{

        user = filteredUsers[indexPath.row]

        FIRDatabase.database().reference().child("Businesses").observe(.value, with: { snapshot in
            if let locationData = snapshot.value as? NSDictionary {
                let locationValue = locationData as! [String: Any]

                let lat = Double(locationValue["businessLatitude"] as! String)
                let long = Double(locationValue["businessLongitude"] as! String)
                let businessLocation = CLLocation(latitude: lat!, longitude: long!)

                let latitude = self.locationManager.location?.coordinate.latitude
                let longitude = self.locationManager.location?.coordinate.longitude
                let userLocation = CLLocation(latitude: latitude!, longitude: longitude!)

                let distanceInMeters : Double = userLocation.distance(from: businessLocation)
                let distanceInMiles : Double = ((distanceInMeters.description as String).doubleValue * 0.00062137)
                cell.businessDistance.text = "\(distanceInMiles.string(2)) miles away"
            }
        })

    } else {

        user = self.usersArray[indexPath.row]

        FIRDatabase.database().reference().child("Businesses").observe(.value, with: { snapshot in
            if let locationData = snapshot.value as? NSDictionary {
            let locationValue = locationData as! [String: Any]

            let lat = Double(locationValue["businessLatitude"] as! String)
            let long = Double(locationValue["businessLongitude"] as! String)
            let businessLocation = CLLocation(latitude: lat!, longitude: long!)

            let latitude = self.locationManager.location?.coordinate.latitude
            let longitude = self.locationManager.location?.coordinate.longitude
            let userLocation = CLLocation(latitude: latitude!, longitude: longitude!)

            let distanceInMeters : Double = userLocation.distance(from: businessLocation)
            let distanceInMiles : Double = ((distanceInMeters.description as String).doubleValue * 0.00062137)
            cell.businessDistance.text = "\(distanceInMiles.string(2)) miles away"
            }

        })
    }

    cell.businessName.text = String(user?["businessName"] as! String)
    cell.businessStreet.text = String(user?["businessStreet"] as! String)
    cell.businessCity.text = String(user?["businessCity"] as! String)
    cell.businessState.text = String(user?["businessState"] as! String)

    //cell.configure(businessName: user?["businessName"] as! String, businessStreet: user?["businessStreet"] as! String, businessCity: user?["businessCity"] as! String, businessState: user?["businessState"] as! String, businessDistance: user?["businessDistance"] as! String )

    return cell
}

import UIKit
import Firebase
import MapKit
import CoreLocation

class RegisteredLocationsTableView: UITableViewController, UISearchResultsUpdating, CLLocationManagerDelegate, NSUserActivityDelegate {

@IBOutlet var followUsersTableView: UITableView!
let searchController = UISearchController(searchResultsController: nil)

var loggedInUser:FIRUser?
var loggedInUserData:NSDictionary?
var usersArray = [NSDictionary?]()
var filteredUsers = [NSDictionary?]()

var locationManager = CLLocationManager()
let distanceFormatter = MKDistanceFormatter()
var locationData: NSDictionary?
var geofences = [CLCircularRegion]()
var nameKeyDict:[String:String] = [:]


var databaseRef = FIRDatabase.database().reference()

override func viewDidLoad() {
    super.viewDidLoad()

    searchController.searchResultsUpdater = self
    searchController.dimsBackgroundDuringPresentation = false
    definesPresentationContext = true
    tableView.tableHeaderView = searchController.searchBar

    locationManager.delegate = self
    locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.startUpdatingLocation()
    locationManager.stopUpdatingLocation()


    databaseRef.child("Businesses").queryOrdered(byChild: "businessName").observe(.childAdded, with: { (snapshot) in

        let key = snapshot.key
        let snapshot = snapshot.value as? NSDictionary

        snapshot?.setValue(key, forKey: "uid")

        if(key == self.loggedInUser?.uid) {
            print("Same as logged in user, so don't show!")
        } else {
            self.usersArray.append(snapshot)

            //insert the rows
            self.followUsersTableView.insertRows(at: [IndexPath(row:self.usersArray.count-1,section:0)], with: UITableViewRowAnimation.automatic)
        }

    }) { (error) in
        print(error.localizedDescription)
    }
}


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


// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if searchController.isActive && searchController.searchBar.text != ""{
        return filteredUsers.count
    }
    return self.usersArray.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! RegisteredLocationsCell
    let user : NSDictionary?

    if searchController.isActive && searchController.searchBar.text != ""{

        user = filteredUsers[indexPath.row]

        FIRDatabase.database().reference().child("Businesses").observe(.childAdded, with: { snapshot in
            if let locationValue = snapshot.value as? NSDictionary {


                let lat = Double(locationValue["businessLatitude"] as! String)
                let long = Double(locationValue["businessLongitude"] as! String)
                let businessLocation = CLLocation(latitude: lat!, longitude: long!)

                let latitude = self.locationManager.location?.coordinate.latitude
                let longitude = self.locationManager.location?.coordinate.longitude
                let userLocation = CLLocation(latitude: latitude!, longitude: longitude!)

                let distanceInMeters : Double = userLocation.distance(from: businessLocation)
                let distanceInMiles : Double = ((distanceInMeters.description as String).doubleValue * 0.00062137)
                cell.businessDistance.text = "\(distanceInMiles.string(2)) miles away"
            }
        })

    } else {

        user = self.usersArray[indexPath.row]

        FIRDatabase.database().reference().child("Businesses").observe(.childAdded, with: { snapshot in
            if let locationValue = snapshot.value as? NSDictionary {


                let lat = Double(locationValue["businessLatitude"] as! String)
                let long = Double(locationValue["businessLongitude"] as! String)
                let businessLocation = CLLocation(latitude: lat!, longitude: long!)

                let latitude = self.locationManager.location?.coordinate.latitude
                let longitude = self.locationManager.location?.coordinate.longitude
                let userLocation = CLLocation(latitude: latitude!, longitude: longitude!)

                let distanceInMeters : Double = userLocation.distance(from: businessLocation)
                let distanceInMiles : Double = ((distanceInMeters.description as String).doubleValue * 0.00062137)
                cell.businessDistance.text = "\(distanceInMiles.string(2)) miles away"
            }
        })
    }

    cell.businessName.text = String(user?["businessName"] as! String)
    cell.businessStreet.text = String(user?["businessStreet"] as! String)
    cell.businessCity.text = String(user?["businessCity"] as! String)
    cell.businessState.text = String(user?["businessState"] as! String)


    //cell.configure(businessName: user?["businessName"] as! String, businessStreet: user?["businessStreet"] as! String, businessCity: user?["businessCity"] as! String, businessState: user?["businessState"] as! String, businessDistance: user?["businessDistance"] as! String )

    return cell
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    super.prepare(for: segue, sender: sender)
    if segue.identifier == "BusinessProfiles" {
        // gotta check if we're currently searching
        if self.searchController.isActive && searchController.searchBar.text != "" {
            if let indexPath = tableView.indexPathForSelectedRow {
                let user = filteredUsers[indexPath.row]
                let controller = segue.destination as? BusinessProfilesViewController
                controller?.otherUser = user
            }
        } else {
            if let indexPath = tableView.indexPathForSelectedRow {
                let user = usersArray[indexPath.row]
                let controller = segue.destination as? BusinessProfilesViewController
                controller?.otherUser = user
            }
        }
    }
}


func updateSearchResults(for searchController: UISearchController) {

    filterContent(searchText: self.searchController.searchBar.text!)
}

func filterContent(searchText:String) {
    self.filteredUsers = self.usersArray.filter { user in

        let username = user!["businessName"] as? String

        return(username?.lowercased().contains(searchText.lowercased()))!
    }
    tableView.reloadData()
}

}

【问题讨论】:

  • 请在此错误行前加上 print(locationValue) 看看它打印了什么?
  • user1000 我刚刚添加了图片
  • 好的,请在上面的打印之后添加这个 print(locationValue["businessLatitude"]) 看看它打印了什么?请告诉我输出
  • 它为零
  • 如果你替换 let locationValue = locationData 为! [String: Any] with let locationValue = locationData as! [[String: Any]] 然后添加 let singleDictionary = locationValue[0] 然后添加 print(singleDictionary) ,看看它打印了什么

标签: swift uitableview firebase location distance


【解决方案1】:

我认为您需要添加 .childAdded 作为观察事件类型 试试这个:

 FIRDatabase.database().reference().child("Businesses").observe(.childAdded, with: { snapshot in
                if let locationValue = snapshot.value as? [String: AnyObject] {


                    let lat = Double(locationValue["businessLatitude"] as! String)
                    let long = Double(locationValue["businessLongitude"] as! String)
                    let businessLocation = CLLocation(latitude: lat!, longitude: long!)

                    let latitude = self.locationManager.location?.coordinate.latitude
                    let longitude = self.locationManager.location?.coordinate.longitude
                    let userLocation = CLLocation(latitude: latitude!, longitude: longitude!)

                    let distanceInMeters : Double = userLocation.distance(from: businessLocation)
                    let distanceInMiles : Double = ((distanceInMeters.description as String).doubleValue * 0.00062137)
                    cell.businessDistance.text = "\(distanceInMiles.string(2)) miles away"
                }
            })

更新:

您需要从cellForRowAt 方法中删除FIRDatabse 调用,并修改您在viewDidLoad 中的调用,如下所示:

databaseRef.child("Businesses").queryOrdered(byChild: "businessName").observe(.childAdded, with: { (snapshot) in

        let key = snapshot.key


        if(key == self.loggedInUser?.uid) {
            print("Same as logged in user, so don't show!")
        } else {
            if let locationValue = snapshot.value as? [String: AnyObject] {
             let lat = Double(locationValue["businessLatitude"] as! String)
                    let long = Double(locationValue["businessLongitude"] as! String)
                    let businessLocation = CLLocation(latitude: lat!, longitude: long!)

                    let latitude = self.locationManager.location?.coordinate.latitude
                    let longitude = self.locationManager.location?.coordinate.longitude
                    let userLocation = CLLocation(latitude: latitude!, longitude: longitude!)

                    let distanceInMeters : Double = userLocation.distance(from: businessLocation)
                    let distanceInMiles : Double = ((distanceInMeters.description as String).doubleValue * 0.00062137)
             let distanceLabelText = "\(distanceInMiles.string(2)) miles away"

             var singleChildDictionary = locationValue
             singleChildDictionary["distanceLabelText"] = distanceLabelText
             self.usersArray.append(singleChildDictionary)

}


            //insert the rows
            self.followUsersTableView.insertRows(at: [IndexPath(row:self.usersArray.count-1,section:0)], with: UITableViewRowAnimation.automatic)
        }

    }) { (error) in
        print(error.localizedDescription)
    }
}

然后在 cellForRowAt 方法中

像分配其他值一样在末尾添加它

cell.businessDistance.text = String(user?["distanceLabelText"] as! String)

【讨论】:

  • 由于某种原因,在快照上它会出现错误提示“对成员值的模糊引用”
  • @LukasBimba 好的,让我看看
  • 需要图片或其他什么?还是你要测试一下??
  • @LukasBimba 你能告诉我如果让 locationValue = snapshot.value as 在这一行会发生错误吗?字典?还是其他地方?
  • 没关系,我重写了它,它编译得很好。现在唯一的问题是它显示所有位置的距离相同
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-15
  • 1970-01-01
  • 1970-01-01
  • 2018-02-02
  • 2018-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多