Как настроить просмотр таблиц для размещения магазинов, ближайших к моему текущему местоположению, используя геопоинт в Cloud Firestore? - PullRequest
3 голосов
/ 29 октября 2019

То, что я пытаюсь сделать, это организовать свои ячейки по магазину, ближайшему к моему текущему местоположению, используя Geopoint в Cloud Firestore.

Я просмотрел весь стек, но не могу найти, как настроить просмотр таблицы вViewController для отображения ближайшего ко мне цветочного магазина из моего текущего местоположения с использованием геопункта в Cloud Firestore

. Это то, что мне нужно в настоящее время для настройки данных для передачи в VC, чтобы они организовывали данные из Firestore в хранилища. ближайший к моему текущему местоположению

ниже у меня есть изображение коллекции в моем Firestore и изображение моего ViewController для того, как мое приложение настроено

enter image description hereenter image description here

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 SDWebImage
import Firebase

class StoreCell: UITableViewCell {

    weak var stores: Store!

    @IBOutlet weak var imageUrl: UIImageView!
    @IBOutlet weak var storeName: UILabel!

    func configure(withStore stores: Store) {
        storeName.text = product.dispensaryName
        productImage.sd_setImage(with: URL(string: product.imageUrl))
    }

    override func layoutSubviews() {
        super.layoutSubviews()
    }
}

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

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return stores.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "StoreCell") as?
        StoreCell else { return UITableViewCell() }

        cell.configure(withStore: stores[indexPath.row])

        return cell
    }

}

enter image description here

1 Ответ

2 голосов
/ 29 октября 2019

Я считаю, что этот ответ должен работать, хотя, возможно, я что-то пропустил.

Что вы захотите сделать, это сделать свойство location в Store типа 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 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()
        }

    }

    ...

}
...