Swift Firebase TableView distance from current user - swift

I am trying to list the distance in a label from the current user to the business location. I keep on getting a error saying "fatal error: unexpectedly found nil while unwrapping an optional value" and I am getting this error on a firebase line, yet I know for a fact I have everything spelled correctly and the call works to get the values. I get the error on line:
"let lat = Double(locationValue["businessLatitude"] as! String)".
Any help would be greatly appreciated
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()
}
}

I think you need to add .childAdded as observe eventtype
Try this:
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"
}
})
Update:
You need to remove the FIRDatabse calls from cellForRowAt method and modify your call in viewDidLoad as follows:
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)
}
}
Then in cellForRowAt method
add this at the end like you are assigning other values
cell.businessDistance.text = String(user?["distanceLabelText"] as! String)

Related

Firebase data and unexpected nil

My ultimate goal is to display annotations on a Map from MapKit. However, loading data from firebase does not work.
Here is the code:
var hotels = [Hotel]()
override func viewDidLoad() {
super.viewDidLoad()
map.delegate = self
checkLocationServices()
observe()
}
The function observe is the following:
func observe() {
Data().getAllHotel { (hotelA) -> (Void) in
if let hotel = hotelA {
print("hotel: ", hotel)
self.hotels.append(hotel)
let hotelAnnotation = MKPointAnnotation()
hotelAnnotation.title = "\(hotel.hotelName)"
hotelAnnotation.coordinate = CLLocationCoordinate2D(latitude: hotel.latitude, longitude: hotel.longitude)
self.map.addAnnotation(hotelAnnotation)
}
}
}
Note that the print in the if statement is not empty.
However the line hotelAnnotation.title causes a bug unexpected nil and I don't understand why.
Additionnally here is the getAllHotel function inside the Data class:
func getAllHotel(closure: HotelClosure?) {
let ref = Ref().databaseHotels
ref.observe(.childAdded) { (snapshot) in
if let dict = snapshot.value as? Dictionary<String, AnyObject> {
let hotel = self.fromDictToHotel(key: snapshot.key, dict: dict)
closure?(hotel)
} else {
closure?(nil)
}
}
}
func fromDictToHotel(key: String, dict: Dictionary<String, AnyObject>) -> Hotel? {
guard let hotelName = dict["name"] as? String else { return nil }
guard let latitude = dict["latitude"] as? Double else { return nil }
guard let longitude = dict["longitude"] as? Double else { return nil }
let hotelDescription = dict["description"] as? String
let hotelGrade = dict["grade"] as? Double
let hotelImageUrl = dict["hotelImageUrl"] as? String
let hotel = Hotel(hid: key, hotelName: hotelName, hotelDescription: hotelDescription, latitude: latitude, longitude: longitude, grade: hotelGrade, url: hotelImageUrl)
return hotel
}
Thanks in advance for your help!

How can firebase users be displayed/ranked according to their distance away from each other with CLLocation?

The page should list all users in the firebase database who are within 3 miles. Right now it just lists all the users. In addition to limiting the listing of users to those within 3 miles, it would be good to rank the displayed users, from closest to furthest.
Below is code that already works to display all the users (within 3 miles and further) from the firebase database. All users have a location in firebase - latitude and longitude.
for people in snapshot.children.allObjects as! [DataSnapshot] {
if people.key != thisUsersUid { //do not add this users info to the array
let peopleObject = people.value as? [String: AnyObject]
let peopleEducation = peopleObject?["Education"] as? String
let peopleWhatIamConsideringBuying = peopleObject?["WhatIamConsideringBuying"] as? String
let peoplePhotoPosts = peopleObject?["PhotoPosts"] as? String
let peopleimageDownloadURL = peopleObject?["imageDownloadURL"] as? String
let peoplepostID = peopleObject?["postID"] as? String
let peoplepeopleWhoLike = peopleObject?["peopleWhoLike"] as? String
let peopl = Userx(Education: peopleEducation, WhatIamConsideringBuying: peopleWhatIamConsideringBuying, PhotoPosts: peoplePhotoPosts, imageDownloadURL: peopleimageDownloadURL, postID: peoplepostID, peopleWhoLike: peoplepeopleWhoLike)
self.people.append(peopl)
}
self.table.reloadData()
}
}
})
public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ViewControllerTableViewCell
let immy = cell.viewWithTag(1) as! UIImageView
let person: Userx = people[indexPath.row]
cell.lblName.text = person.Education
cell.postID = self.people[indexPath.row].postID
if let PhotoPosts = person.PhotoPosts {
let url = URL(string: PhotoPosts)
immy.sd_setImage(with: url)
}
return cell
}
/Below makes the users locations:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let databaseRef = Database.database().reference()
let uid = Auth.auth().currentUser!.uid
guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
print("locations = \(locValue.latitude) \(locValue.longitude)")
latestLocation = ["latitude" : locValue.latitude, "longitude" : locValue.longitude]
if let locationDictionary = latestLocation {
databaseRef.child("people").child(uid).child("Coordinates").setValue(locationDictionary)
}
//Update after answer:
for people in snapshot.children.allObjects as! [DataSnapshot] {
.......
let peoplepeopleWhoLike = peopleObject?["peopleWhoLike"] as? String
let userId = people.key
let coordSnap = people.childSnapshot(forPath: "Coordinates")
let lat = coordSnap.childSnapshot(forPath: "latitude").value as! CLLocationDegrees
let lon = coordSnap.childSnapshot(forPath: "longitude").value as! CLLocationDegrees
let locCoord = CLLocationCoordinate2DMake(lat, lon)
let coordinates = CLLocationCoordinate2D(latitude: lat, longitude: lon)
let peopleLocation = (lat, lon)
print(userId, "coords: \(lat) \(lon)")
let distance = peopleLocation.distance(to: latestLocation)
let peopl = Userx(Education: peopleEducation, WhatIamConsideringBuying: peopleWhatIamConsideringBuying, PhotoPosts: peoplePhotoPosts, imageDownloadURL: peopleimageDownloadURL, postID: peoplepostID, peopleWhoLike: peoplepeopleWhoLike, distance: distance)
Right Now: All users randomly displayed below each other.
What I need: Users within 3 miles displayed underneath each other, from closest to furthest.
First of all, you need to have the distance of the retrieved users from Firebase, meaning you need to get the object "Coordinates" and store the distance from the current user inside Userx.
Then you'd do something like this:
for people in snapshot.children.allObjects as! [DataSnapshot] {
if people.key != thisUsersUid { //do not add this users info to the array
let peopleObject = people.value as? [String: AnyObject]
let peopleEducation = peopleObject?["Education"] as? String
let peopleWhatIamConsideringBuying = peopleObject?["WhatIamConsideringBuying"] as? String
let peoplePhotoPosts = peopleObject?["PhotoPosts"] as? String
let peopleimageDownloadURL = peopleObject?["imageDownloadURL"] as? String
let peoplepostID = peopleObject?["postID"] as? String
let peoplepeopleWhoLike = peopleObject?["peopleWhoLike"] as? String
let peopleLocation = ... // Map user location here using CLLocation(latitude: Double, longitude: Double)
let distance = peopleLocation.distance(to: thisUserLocation) // thisUserLocation is the one you're getting in latestLocation
let peopl = Userx(Education: peopleEducation, WhatIamConsideringBuying: peopleWhatIamConsideringBuying, PhotoPosts: peoplePhotoPosts, imageDownloadURL: peopleimageDownloadURL, postID: peoplepostID, peopleWhoLike: peoplepeopleWhoLike, distance: distance)
self.people.append(peopl)
}
people.sort(by: { (p1, p2) -> Bool in
return p1.distance < p2.distance
})
self.table.reloadData()
}

Representing Coordinates from Firebase as Annotations Swift

I am having trouble putting annotations on my map from longitudinal and latitudinal degrees I uploaded to firebase. I want to add an annotation for all of my users but cannot get xcode to recognize my userLatitude and userLongitude variables in another function.
Anything will help!
func retrieveUsers(){
let ref = Database.database().reference()
ref.child("users").queryOrderedByKey().observeSingleEvent(of: .value, with: { snapshot in
let users = snapshot.value as! [String: AnyObject]
self.user.removeAll()
for (_,value) in users {
if let uid = value["uid"] as? String {
if uid != Auth.auth().currentUser!.uid {
let userToShow = User()
if let fullName = value["full name"] as? String,
let imagePath = value["urlToImage"] as? String,
//String(format: "%f", self.currentUserLocation?.longitude ?? 0),
let userLongitude = value["long"] as? CLLocationDegrees,
let userLatitude = value["lat"] as? CLLocationDegrees
//why isnt it recognizing the users degrees
{
userToShow.fullName = value["full name"] as? String
userToShow.imagePath = value["urlToImage"] as? String
userToShow.userID = value["uid"] as? String
userToShow.userLongitude = value["long"] as? CLLocationDegrees
userToShow.userLatitude = value["lat"] as? CLLocationDegrees
self.user.append(userToShow)
}
}
}
}
DispatchQueue.main.async {
self.map.reloadInputViews()
//not sure if this is right
}
})
}
func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) {
let otherUserLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(userLatitude, userLongitude)
let userAnnotation = MKPointAnnotation()
userAnnotation.coordinate = otherUserLocation
userAnnotation.title = "fullName"
}
And if you change as? CLLocationDegrees by as? String and manage the cast in CLLocationDegrees afterwards?
Because I think, in Firebase, data is stored as String and not as Double (that is the type of data a CLLocationDegrees type is referring to).

UISearchBar and Firebase Database

struct postStruct {
let title : String!
let author : String!
let bookRefCode : String!
let imageDownloadString : String!
let status : String!
let reserved : String!
let category : String!
let dueDate : String!
}
'Above is where i set up the structure for the post, and below, is how i reference and retrieve the data from the firebase database.
My problem is that when you set up the searcher, i do not know how to get it to search based off of the title of the post.'
class DirectoryTableView: UITableViewController {
var posts = [postStruct]()
override func viewDidLoad() {
let databaseRef = Database.database().reference()
databaseRef.child("Books").queryOrderedByKey().observe(.childAdded, with: {
snapshot in
var snapshotValue = snapshot.value as? NSDictionary
let title = snapshotValue!["title"] as? String
snapshotValue = snapshot.value as? NSDictionary
let author = snapshotValue!["author"] as? String
snapshotValue = snapshot.value as? NSDictionary
let bookRefCode = snapshotValue!["bookRefCode"] as? String
snapshotValue = snapshot.value as? NSDictionary
let status = snapshotValue!["status"] as? String
snapshotValue = snapshot.value as? NSDictionary
let reserved = snapshotValue!["reserved"] as? String
snapshotValue = snapshot.value as? NSDictionary
let category = snapshotValue!["category"] as? String
snapshotValue = snapshot.value as? NSDictionary
let dueDate = snapshotValue!["dueDate"] as? String
snapshotValue = snapshot.value as? NSDictionary
self.posts.insert(postStruct(title: title, author: author, bookRefCode: bookRefCode, status: status, reserved: reserved, category: category, dueDate: dueDate) , at: 0)
self.tableView.reloadData()
})
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell")
let databaseRef = Database.database().reference()
let label1 = cell?.viewWithTag(1) as! UILabel
label1.text = posts[indexPath.row].title
let label2 = cell?.viewWithTag(2) as! UILabel
label2.text = posts[indexPath.row].author
let label3 = cell?.viewWithTag(3) as! UILabel
label3.text = posts[indexPath.row].bookRefCode
let label4 = cell?.viewWithTag(4) as! UILabel
label4.text = posts[indexPath.row].status
let label5 = cell?.viewWithTag(5) as! UILabel
label5.text = posts[indexPath.row].category
let image1 = cell?.viewWithTag(6) as! UILabel
image1.text = posts[indexPath.row].imageDownloadString
let label6 = cell?.viewWithTag(7) as! UILabel
label6.text = posts[indexPath.row].reserved
let label9 = cell?.viewWithTag(9) as! UILabel
label9.text = posts[indexPath.row].dueDate
return cell!
}
'Also, does anyone know how to sort the tableview cells (posts in this case) alphabetically?'
You can get all data already ordered alphabetically
databaseRef.child("Books").queryOrdered(byChild: "title").observe(.childAdded, with: { snapshot in
var snapshotValue = snapshot.value as? NSDictionary
let title = snapshotValue!["title"] as? String
snapshotValue = snapshot.value as? NSDictionary
....
}
or sort your array before reload the tableView
var sortedArray = swiftArray.sorted { $0.title.localizedCaseInsensitiveCompare($1.title) == ComparisonResult.orderedAscending }
Sample structure
for sorting data according to searchBar I had used an dictionary that having all my snapshot and I compared my searchBar text in that dict and after sorting reloaded tableView here is code that you can have a look at
//method to get all user Details in a dict
func getEmail() {
let databaseRef = Database.database().reference().child("users")
databaseRef.observe(.value, with: { (snapshot) in
if snapshot.exists(){
self.postData = snapshot.value as! [String : AnyObject]
let dictValues = [AnyObject](self.postData.values)
self.sarchDict = dictValues
}
})
}
//search bar delegate
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if self.mySearchBar.text!.isEmpty {
// set searching false
self.isSearching = false
}else{
// set searghing true
self.isSearching = true
self.names.removeAll()
self.uidArray.removeAll()
self.imageUrl.removeAll()
for key in self.sarchDict {
let mainKey = key
//I am making query against email in snapshot dict
let str = key["email"] as? String
//taking value of email from my dict lowerCased to make query as case insensitive
let lowercaseString = str?.lowercased()
//checking do my any email have entered letter or not
if(lowercaseString?.hasPrefix(self.mySearchBar.text!.lowercased()))!{
//here I have a check so to remove value of current logged user
if ((key["uID"] as! String) != (Auth.auth().currentUser?.uid)!){
//If value is found append it in some arrays
self.imageUrl.append( key["profilePic"] as! String )
self.names.append( key["name"] as! String )
self.uidArray.append( key["uID"] as! String )
//you can check which values are being added from which key
print(mainKey)
}
}
}
//reload TableView here
}
}
//TableView
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
cell = self.myTableView.dequeueReusableCell(withIdentifier: "Cell")!
if self.isSearching == true {
let imageView = (cell.viewWithTag(1) as! UIImageView)
imageView.setRounded()
if imageUrl[indexPath.row] != "" {
self.lazyImage.showWithSpinner(imageView:imageView, url:imageUrl[indexPath.row])
}
else{
imageView.image = UIImage(named: "anonymous")
}
(cell.contentView.viewWithTag(2) as! UILabel).text = self.names[indexPath.row]
}
else {
}
return cell
}
I'm sure this will be helpful to some using FireStore. Here I'm just setting my reference to point to the right collection. "name" is my field I wish to search by and is greater than will be checked chronologically on my string. The further they type the more defined the search results are.
static func searchForProgramStartingWith(string: String) {
let programsRef = db.collection("programs")
programsRef.whereField("name", isGreaterThan: string).limit(to: 10).getDocuments { (snapshot, error) in
if error != nil {
print("there was an error")
} else {
let shots = snapshot?.documents
for each in shots! {
let data = each.data()
let name = data["name"]
print("The name is \(name!)")
}
}
}
}

Show marker address (street-Address) with clicking in swift

I have a latitude and longitude location of marker in google maps that I want to convert to the location name String in Swift. What is the best way to do this?
i want to show markers' location address and i don't know how to do it .
here is my code that i used to add marker and get latitude and longitude:
func mapView(mapView: GMSMapView, didLongPressAtCoordinate coordinate: CLLocationCoordinate2D) {
if counterMarker < 2
{
counterMarker += 1
let marker = GMSMarker(position: coordinate)
marker.appearAnimation = kGMSMarkerAnimationPop
marker.map = mapView
marker.position.latitude = coordinate.latitude
marker.position.longitude = coordinate.longitude
print(marker.position.latitude)
print(marker.position.longitude)
}
}
func mapView(mapView: GMSMapView, didLongPressAtCoordinate coordinate: CLLocationCoordinate2D) {
if counterMarker < 2
{
counterMarker += 1
let marker = GMSMarker(position: coordinate)
marker.appearAnimation = kGMSMarkerAnimationPop
marker.map = mapView
marker.position.latitude = coordinate.latitude
marker.position.longitude = coordinate.longitude
self.getAddressForLatLng(String(format: "%#",marker.position.latitude), longitude:String(format: "%#",marker.position.longitude)
}
}
func getAddressForLatLng(latitude: String, longitude: String) {
let url = NSURL(string: "https://maps.googleapis.com/maps/api/geocode/json?latlng=\(latitude),\(longitude)&key=YOUR-APIKEY")
let data = NSData(contentsOfURL: url!)
let json = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as! NSDictionary
if let result = json["results"] as? NSArray {
if let address = result[0]["address_components"] as? NSArray {
let number = address[0]["short_name"] as! String
let street = address[1]["short_name"] as! String
let city = address[2]["short_name"] as! String
let state = address[4]["short_name"] as! String
let zip = address[6]["short_name"] as! String
print("\n\(number) \(street), \(city), \(state) \(zip) \(address)")
}
}
}