Google地图:iOS中的自定义LocationSource

Den*_*Loh 8 android google-maps google-maps-api-3 ios

我已经构建了一个Android应用程序,可以使用谷歌地图显示用户的地理位置,除了Wifi,单元格和GPS之外还有一些附加信息,例如QR码,信标或任何我用来发信号通知当前位置的信息(我不是t考虑到这些位置的实际准确性).我正在使用LocationSource它并通过setLocationSource将其传递给Google Maps API .

我必须使用Google地图,因为Apple地图在可用缩放级别方面受到限制,因此我无法放大建筑物.

是否有可能LocationManager通过某些操作提供定期更新的自定义,并将其注入Google Maps API,如LocationSource

我知道有一些黑客可以在地图上放置自定义标记,但这使得无法使用Google地图的其他功能,例如通过点击"我的位置"按钮将相机移动到用户位置.

谢谢.

Ale*_*yss 2

有一个解决方案。Google Maps API 使用 Cocoa 框架类 CLLocationManager。每个想要了解当前 GPS 位置更改的人都必须符合 CLLocationManagerDelegate 并成为 CLLocationManager 对象的委托。更新通过 locationManager:didUpdateLocations: 委托方法发送到委托对象。这是一个大家都知道的理论。因此,为了模拟位置数据,我们需要找到一种方法来调用此方法,并将我们自己的数据传递给它。幸运的是,有机会通过函数class_addMethodclass_replaceMethod动态更改任何类的行为。现在我们可以使用方法 override_abc 来更改方法 abc 的实现,该方法可以在类别中实现,如下所示:

let originalSelector = NSSelectorFromString("setDelegate:")
let newSelector = NSSelectorFromString("override_setDelegate:")

let originalMethod = class_getInstanceMethod(CLLocationManager.self, originalSelector)
let newMethod = class_getInstanceMethod(CLLocationManager.self, newSelector)

method_exchangeImplementations(originalMethod, newMethod)
Run Code Online (Sandbox Code Playgroud)

对于我们的例子,我们需要更改位置管理器委托的 setter 并添加我们自己的 setter 作为扩展:

extension CLLocationManager {
    func override_setDelegate(delegate: CLLocationManagerDelegate) {
        // save a reference to self
        GMLocationManager = self
        override_setDelegate(delegate)
    }
}
Run Code Online (Sandbox Code Playgroud)

一旦我们保存了对 Google 地图位置管理器的引用,我们现在就可以使用附加的扩展方法 SimulateLocation 来调用 locationManager:didUpdateLocations: 委托方法。

extension CLLocationManager {
    func simulateLocation(location: CLLocation) {
        self.delegate?.locationManager?(self, didUpdateLocations: [location])
    }
}
// ...

GMLocationManager?.simulateLocation(fakeLocation)
Run Code Online (Sandbox Code Playgroud)