代码之家  ›  专栏  ›  技术社区  ›  Lukas Bimba

与当前用户的Swift Firebase TableView距离

  •  0
  • Lukas Bimba  · 技术社区  · 7 年前

    "fatal error: unexpectedly found nil while unwrapping an optional value" "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
    }
    

    Added "print(locationValue)"

    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()
    }
    
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   3stud1ant3    7 年前

    我认为你需要补充一点。儿童添加为观察事件类型 试试这个:

     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)
        }
    }
    

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