Mar*_*tin 5 geolocation ios swift swift3
对Swift来说还是一个新手.我来自Android背景,其中有BroadcastReceiver,即使应用程序未运行,也可以向服务提供位置信息.
所以我在iOS/Swift中寻找类似的东西,看起来在此之前不可能,但现在可能.我正在为iOS 10开发,但如果它是向后兼容的话会很棒.
我发现
startMonitoringSignificantLocationChanges
Run Code Online (Sandbox Code Playgroud)
我可以执行以开始提供位置更新,虽然这提出了一些问题.一旦我调用此应用程序并且我的应用程序未运行,是否仍在发送更新?应用程序如何醒来响应?
还重新启动手机,当它返回时,这是否意味着我仍然需要再次调用startMonitoringSignificantLocationChanges,这意味着我将不得不等待用户执行我的应用程序.或者重启后会记住设置吗?
还有点困惑如何解决这个问题,这里是对我要做的事情的简要解释.
我想更新手机的位置,即使应用程序没有运行,也会经常发送到休息服务.
这样在后端服务上我可以确定某人是否在某人的X米范围内并向他们发送推送通知.
Raj*_*ari 17
它可能是也可能不是一个好的解决方案,但如果我是你,我会同时使用startMonitoringSignificantLocationChanges和regionMonitoring.
让我们regionMonitoring先行.当app处于前台状态时,我们当然没有问题,我们可以使用CLLocationManager的 didUpdate委托来获取位置并将其发送到服务器.
在AppDelegate的财产中保留最新的当前位置,让我们说:
var lastLocation:CLLocation?
//And a location manager
var locationManager = CLLocationManager()
Run Code Online (Sandbox Code Playgroud)
我们有两个 UIApplicationDelegates
func applicationDidEnterBackground(_ application: UIApplication) {
//Create a region
}
func applicationWillTerminate(_ application: UIApplication) {
//Create a region
}
Run Code Online (Sandbox Code Playgroud)
因此,每当用户杀死应用程序或使应用程序转到后台时,我们当然可以在获取的最新当前位置周围创建一个区域.以下是创建区域的示例.
func createRegion(location:CLLocation?) {
if CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self) {
let coordinate = CLLocationCoordinate2DMake((location?.coordinate.latitude)!, (location?.coordinate.longitude)!)
let regionRadius = 50.0
let region = CLCircularRegion(center: CLLocationCoordinate2D(
latitude: coordinate.latitude,
longitude: coordinate.longitude),
radius: regionRadius,
identifier: "aabb")
region.notifyOnExit = true
region.notifyOnEntry = true
//Send your fetched location to server
//Stop your location manager for updating location and start regionMonitoring
self.locationManager?.stopUpdatingLocation()
self.locationManager?.startMonitoring(for: region)
}
else {
print("System can't track regions")
}
}
Run Code Online (Sandbox Code Playgroud)
利用RegionDelegates
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
print("Entered Region")
}
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
print("Exited Region")
locationManager?.stopMonitoring(for: region)
//Start location manager and fetch current location
locationManager?.startUpdatingLocation()
}
Run Code Online (Sandbox Code Playgroud)
从didUpdate方法中获取位置
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if UIApplication.shared.applicationState == .active {
} else {
//App is in BG/ Killed or suspended state
//send location to server
// create a New Region with current fetched location
let location = locations.last
lastLocation = location
//Make region and again the same cycle continues.
self.createRegion(location: lastLocation)
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我制作了一个50米的区域半径圆.我测试了这个,一般在从你的中心点穿过100米后调用它.
现在我可以使用第二种方法 significantLocationChanges
在使应用程序进入后台或终止时,我们可以停止位置管理器以进一步更新位置,并可以调用 startMonitoringSignificantLocationChanges
self.locationManager?.stopUpdatingLocation()
self.locationManager?.startMonitoringSignificantLocationChanges()
Run Code Online (Sandbox Code Playgroud)
当应用程序被杀死时,该位置将从didFinishLaunching方法中获取launchOptions?[UIApplicationLaunchOptionsKey.location]
if launchOptions?[UIApplicationLaunchOptionsKey.location] != nil {
//You have a location when app is in killed/ not running state
}
Run Code Online (Sandbox Code Playgroud)
还要确保locationManager?.requestAlwaysAuthorization()使用密钥要求
<key>NSLocationAlwaysUsageDescription</key>
<string>Allow location</string>
Run Code Online (Sandbox Code Playgroud)
在您的Info.plist中
通过同时使用2个LocationManage可以有第三种解决方案.
正如使用 significantLocationChanges
只要设备从之前的通知移动500米或更长时间,应用就会收到通知.它不应该比每五分钟更频繁地预期通知.如果设备能够从网络检索数据,则位置管理器更有可能及时发送通知.
因此,它完全取决于您的要求,因为位置提取取决于许多因素,例如应用程序未运行时打开的应用程序数量,电池电量,信号强度等.
另外请记住始终设置一个准确度高的区域.
我知道这不会完全解决您的问题,但您可以根据自己的要求提出建议.
| 归档时间: |
|
| 查看次数: |
6288 次 |
| 最近记录: |