Swift Firebase TableView与当前用户的距离

问题描述:

我试图列出从当前用户到业务位置的标签中的距离。我一直在收到一个错误,说"fatal error: unexpectedly found nil while unwrapping an optional value",我在firebase线路上收到这个错误,但是我知道一个事实,我有一切拼写正确,并且调用工作来获取值。我收到了错误消息: "let lat = Double(locationValue["businessLatitude"] as! String)"Swift Firebase TableView与当前用户的距离

任何帮助,将不胜感激

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

} 
+0

请在此错误行之前添加print(locationValue)并查看它打印的内容? – 3stud1ant3

+0

user1000我刚刚添加了图片 –

+0

好的请在上面的打印后添加此打印(locationValue [“businessLatitude”])并查看打印内容?并请告诉我输出 – 3stud1ant3

我认为你需要添加.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) 
+0

一个错误说“对成员价值的歧义参考” –

+0

@LukasBimba好吧让我看看 – 3stud1ant3

+0

需要一张图片或东西?或者你要测试它? –