swift - 如何使用 Cloud Firestore 中的地理点设置 tableview 以放置离我当前位置最近的商店?
问题描述
我想要做的是使用 Cloud Firestore 中的 Geopoint 在离我当前位置最近的商店组织我的单元格
我已经查看了整个堆栈,但我找不到如何在 ViewController 中设置 tableview 以使用 Cloud Firestore 中的地理点显示离我当前位置最近的花店
这是我目前必须设置的数据以传递给 VC,以便它将数据从 Firestore 组织到离我当前位置最近的商店
下面我有一个 Firestore 中的集合图像和我的 ViewController 的图像,以了解我的应用程序是如何设置的
import Foundation
import UIKit
class Store {
var id: String
var storeName: String
var imageUrl: String
var location: ??
init(id: String,
storeName: String,
imageUrl: String,
location:??) { //
self.id = id
self.storeName = storeName
self.imageUrl = imageUrl
self.location = location //
}
convenience init(dictionary: [String : Any]) {
let id = dictionary["id"] as? String ?? ""
let storeName = dictionary["storeName"] as? String ?? ""
let imageUrl = dictionary["imageUrl"] as? String ?? ""
let location = dictionary["location"] as? String ?? "" //
self.init(id: id,
storeName: storeName,
imageUrl: imageUrl,
location: location) //
}
}
import UIKit
import CoreLocation
import Firebase
import FirebaseFirestore
class ViewController: UIViewController, CLLocationManagerDelegate {
var locationManager: CLLocationManager?
@IBOutlet weak var tableView: UITableView!
var stores: [Store] = []
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.requestWhenInUseAuthorization()
tableView.dataSource = self
tableView.delegate = self
fetchStores { (stores) in
self.stores = stores
self.tableView.reloadData()
}
}
func fetchStores(_ completion: @escaping ([Store]) -> Void) {
let ref = Firestore.firestore().collection("storeName")
ref.addSnapshotListener { (snapshot, error) in
guard error == nil, let snapshot = snapshot, !snapshot.isEmpty else {
return
}
completion(snapshot.documents.compactMap( {Store(dictionary: $0.data())} ))
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse {
if CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self){
if CLLocationManager.isRangingAvailable() {
// do Stuff
}
}
}
}
}
解决方案
我相信这个答案应该有效,尽管我可能错过了一些东西。
您要做的是将location
属性Store
设置为 type CLLocationCoordinate2D
。这需要导入CoreLocation
. 您还想添加一个名为的属性,该属性distanceFromUser
使用CLLocation.distance(from:)
方法来查找用户当前位置和商店位置之间的距离(以米为单位):
import Foundation
import UIKit
import CoreLocation
import Firebase
import FirebaseFirestore
class Store {
var id: String
var storeName: String
var imageUrl: String
var location: CLLocationCoordinate2D
var distanceFromUser: Double
init(id: String,
storeName: String,
imageUrl: String,
location: CLLocationCoordinate2D) {
self.id = id
self.storeName = storeName
self.imageUrl = imageUrl
self.location = location
self.distanceFromUser = (CLLocationManager().location?.distance(from: CLLocation(latitude: location.latitude, longitude: location.longitude)))!
}
convenience init(dictionary: [String : Any]) {
let id = dictionary["id"] as? String ?? ""
let storeName = dictionary["storeName"] as? String ?? ""
let imageUrl = dictionary["imageUrl"] as? String ?? ""
//We now have to convert Firestore's "location" property from a GeoPoint to a CLLocationCoordinate2d
let geoPoint = dictionary["location"] as! GeoPoint
let latitude = geoPoint.latitude
let longitude = geoPoint.longitude
let location = CLLocationCoordinate2D(latitude: latitude!, longitude: longitude!)
self.init(id: id,
storeName: storeName,
imageUrl: imageUrl,
location: location)
}
}
然后,您需要distanceFromUser
在ViewController
's中对商店进行排序viewDidLoad
:
import UIKit
import CoreLocation
import Firebase
import FirebaseFirestore
class ViewController: UIViewController, CLLocationManagerDelegate {
...
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.requestWhenInUseAuthorization()
tableView.dataSource = self
tableView.delegate = self
fetchStores { (stores) in
self.stores = stores.sorted(by: { $0.distanceFromUser < $1.distanceFromUser })
self.tableView.reloadData()
}
}
...
}
推荐阅读
- python - 使用 Homebrew 安装 python3 后,Homebrew 不会在 /usr/bin/local 中创建 python 的符号链接
- asp.net-core - 从任何地方检索 SignalR 3.0 中的集线器上下文的最佳方式
- sql - 替换 select 语句中的特殊字符
- android - 具有静态浮动操作按钮的相对布局内的网格布局上的滚动视图
- visual-studio - Unity GUI 元素 - 我如何选择 whos 在顶部?
- node.js - 即使状态为 200 的响应准确,也会触发 catch 块
- java - 从 Docker 容器的 maven Quarkus 项目的资源文件夹中读取 txt 文件
- vim - 如何在 Vim 中列出 autocmd 组?
- angular - 如何解决 Ionic Angular 应用程序中的 CORS 策略问题?
- vba - 确定夏令时是否对 VBA 中的特定时区有效