Geofirestore 1.2.0

Geofirestore 1.2.0

Dhruv Shah 维护。



 
依赖
Firebase~> 5.4
GeoFire~> 3.0
FirebaseCore~> 5.0
FirebaseFirestore~> 0.12
 

  • Dhruv Shah 和 Nikhil Sridhar 提供

GeoFirestore for iOS — 使用 Firestore 进行实时位置查询

GeoFirestore 是一个基于 Swift 的开源库,允许您基于地理位置存储和查询一系列文档。

GeoFirestore 的核心功能是简单地存储带有字符串键的位置。然而,其主要优势在于能够实时查询给定地理区域内的文档。

GeoFirestore 使用 Firestore 数据库进行数据存储,允许查询结果在数据更改时实时更新。GeoFirestore 仅选择性地加载特定位置的附近数据,即使数据集非常大,也能保持应用程序轻量和响应。

将 GeoFirestore 集成到您的数据中

GeoFirestore 被设计成一个轻量级的 Firestore 扩展。但是,为了保持简单,GeoFirestore 在 Firestore 数据库中以其自己的格式和位置存储数据。这使得您现有的数据格式和安全规则保持不变,您可以将 GeoFirestore 作为一种简单易用的地理查询解决方案添加,而无需修改现有数据。

示例使用

假设你正在构建一个用来评分酒吧的应用程序,并将酒吧的所有信息(例如:名称、营业时间和价格范围)存储在 collection(bars).document(bar-id) 中。之后,你想为用户提供搜索附近酒吧的功能。这就需要用到 GeoFirestore。你可以使用 GeoFirestore 存储每个酒吧文档的位置信息,GeoFirestore 使得你能够轻松地查询附近的酒吧。

示例

要运行示例项目,首先从仓库克隆项目,然后从 Example 目录中运行 pod install

在 iOS 中下载 GeoFirestore

如果你使用的是 CocoaPods,请将以下内容添加到你的 Podfile 中

pod ‘Geofirestore'

开始使用 Firestore

GeoFirestore 需要使用 Firestore 数据库来存储位置数据。你可以在 这里了解更多关于 Firestore 的信息。

使用 GeoFirestore

GeoFirestore

使用 GeoFirestore 对象来读取和写入 Firestore 数据库中的地理位置数据以及创建查询。为了创建一个新的 GeoFirestore 实例,需要将其附加到一个 Firestore 收藏引用上

let geoFirestoreRef = Firestore.firestore().collection("my-collection")
let geoFirestore = GeoFirestore(collectionRef: geoFirestoreRef)

设置位置数据

要设置一个文档的位置,只需调用 setLocation 方法。

geoFirestore.setLocation(location: CLLocation(latitude: 37.7853889, longitude: -122.4056973), forDocumentWithID: "que8B9fxxjcvbC81h32VRjeBSUW2") { (error) in
    if (error != nil) {
        print("An error occured: \(error)")
    } else {
        print("Saved location successfully!")
    }
}

或者使用 GeoPoint 设置位置。

geoFirestore.setLocation(geopoint: GeoPoint(latitude: 37.7853889, longitude: -122.4056973), forDocumentWithID: "que8B9fxxjcvbC81h32VRjeBSUW2") { (error) in
    if (error != nil) {
        print("An error occured: \(error)")
    } else {
        print("Saved location successfully!")
    }
}

要删除位置并从数据库中删除位置,只需调用

geoFirestore.removeLocation(forDocumentWithID: "que8B9fxxjcvbC81h32VRjeBSUW2") 

检索位置

检索位置是通过回调实现的。如果文档不在 GeoFirestore 中,回调将被调用并传回 nil。如果发生错误,回调将传回错误,位置将是 nil

geoFirestore.getLocation(forDocumentWithID: "que8B9fxxjcvbC81h32VRjeBSUW2") { (location: CLLocation?, error) in
    if (error != nil) {
        print("An error occurred: \(error)")
    } else if (location != nil) {
        print("Location: [\(location!.coordinate.latitude), \(location!.coordinate.longitude)]")
    } else {
        print("GeoFirestore does not contain a location for this document")
    }
}

或者将位置作为 GeoPoint 获取。

geoFirestore.getLocation(forDocumentWithID: "que8B9fxxjcvbC81h32VRjeBSUW2") { (location: GeoPoint?, error) in
    if (error != nil) {
        print("An error occurred: \(error)")
    } else if (location != nil) {
        print("Location: [\(location!.latitude), \(location!.longitude)]")
    } else {
        print("GeoFirestore does not contain a location for this document")
    }
}

GeoFirestore 查询

GeoFirestore 允许您使用 GFSQuery 对象查询地理区域内的所有文档。随着文档位置的变化,查询会实时更新,并触发事件通知您是否有任何相关文档移动。GFSQuery 参数以后可以更新以更改查询区域的范围和中心。

// Query using CLLocation
let center = CLLocation(latitude: 37.7832889, longitude: -122.4056973)
// Query locations at [37.7832889, -122.4056973] with a radius of 600 meters
var circleQuery = geoFirestore.query(withCenter: center, radius: 0.6)

// Query using GeoPoint
let center2 = GeoPoint(latitude: 37.7832889, longitude: -122.4056973)
// Query locations at [37.7832889, -122.4056973] with a radius of 600 meters
var circleQuery2 = geoFirestore.query(withCenter: center2, radius: 0.6)

// Query location by region
let span = MKCoordinateSpanMake(0.001, 0.001)
let region = MKCoordinateRegionMake(center.coordinate, span)
var regionQuery = geoFirestore.query(inRegion: region)

接收地理查询事件

可能与地理查询发生三种类型的事件

  1. 文档进入:一个文档的位置现在符合查询标准。
  2. 文档退出:一个文档的位置不再符合查询标准。
  3. 文档移动:一个文档的位置发生了变化,但仍然符合查询标准。

对于符合查询的所有文档,以及任何后来进入查询的文档,将会触发文档进入事件。文档移动和文档退出事件将保证在文档进入事件之前触发。

要观察地理查询的事件,您可以使用 observe:with: 注册一个回调。

let queryHandle = query.observe(.documentEntered, with: { (key, location) in
    print("The document with documentID '\(key)' entered the search area and is at location '\(location)'")
})

要取消一个或所有地理查询的回调,分别调用 removeObserver:withHandle:removeAllObservers:

等待查询“就绪”

有时您想了解当所有初始文档的数据已从服务器加载,并且相应的事件被这些文档触发时。例如,您可能想在数据完全加载后隐藏加载动画。GFSQuery 提供了一个方法来监听这些就绪事件

query.observeReady {
    print("All initial data has been loaded and events have been fired!")
}

注意,在初始加载数据时位置可能会改变,因此文档移动和文档退出事件可能仍然会在就绪事件触发之前发生。

当查询条件更新时,现有的位置将被重新查询,并且一旦触发更新查询的所有事件,就绪事件将被再次触发。这包括不再符合查询的文档的文档退出事件。

更新查询条件

要更新查询条件,您可以在 GFSQuery 对象上使用 centerradius 属性。对于在旧检索区域和新检索区域之间移动的文档,将分别触发文档退出和文档进入事件。由于查询条件发生变化,不会触发文档移动事件;然而,文档移动事件可能独立发生。

方便的扩展

为了便于在 GeoPointCLLocation 之间转换,我们提供了一些有用的扩展

let cllocation = CLLocation(latitude: 37.7832889, longitude: -122.4056973)
let geopoint = GeoPoint(latitude: 37.7832889, longitude: -122.4056973)

// Converting from CLLocation to Geopoint
let loc1: GeoPoint = cllocation.geopointValue()
let loc2: GeoPoint = GeoPoint.geopointWithLocation(location: cllocation)

// Converting from Geopoint to CLLocation
let loc3: CLLocation = geopoint.locationValue()
let loc4: CLLocation = CLLocation.locationWithGeopoint(geopoint: geopoint)

API参考与文档

完整的API参考和文档在此处可用:点击 here

许可证

GeoFirestore可在MIT许可证下使用。更多信息请参阅LICENSE文件。

版权所有 © 2018 Imperium Labs