我试图在标签中列出从当前用户到业务位置的距离。我不断地得到一个错误,说"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
}

swift - Swift Firebase TableView与当前用户的距离-LMLPHP
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()
}

}

最佳答案

我认为您需要添加。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"
                }
            })

更新:
您需要从FIRDatabse方法中移除cellForRowAt调用,并在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)

09-11 06:56