Swift:即使在应用程序未运行时也能收到位置信息? [英] Swift: Receiving Location even when app is not running?
问题描述
所以我一直在寻找类似的东西在ios / swift中,似乎在这之前是不可能的,但现在可能是这样。我正在为iOS 10开发,但如果它向后兼容,它会很棒。
我发现
startMonitoringSignificantLocationChanges
我可以执行开始传送位置更新,虽然这会引发几个问题。一旦我打电话给我,我的应用程序没有运行,更新仍在发送?而且,如何唤醒应用程序?
还要重新启动手机,当它返回时,这是否意味着我仍然需要再次调用startMonitoringSignificantLocationChanges,这意味着我将不得不等待为用户执行我的应用程序。还是记得重新启动后的设置?
如何解决这个问题仍然有点困惑,我想简单解释一下我正在尝试做什么。
我想更新手机的位置,即使应用程序没有运行,也会每隔一段时间发送一次休息服务。
通过这种方式,我可以确定后端服务中是否有人也在某个人的X米范围内,并向他们发送推送通知。
任何帮助任何人都可以提供。
谢谢
可能不是一个好的解决方案,但如果我是你,我会同时使用 startMonitoringSignificantLocationChanges
和 regionMonitoring
。
先让 regionMonitoring
。当应用程序处于前台状态时,我们肯定没有问题,我们可以使用 CLLocationManager的 didUpdate
委托获取位置并将其发送到服务器。
在AppDelegate的属性中保留最新的当前位置,可以说:
var lastLocation:CLLocation?
//位置管理器
var locationManager = CLLocationManager()
我们有两个 UIApplicationDelegates
func applicationDidEnterBackground(_ application: UIApplication){
//创建一个区域
}
func applicationWillTerminate(_ application:UIApplication){
//创建一个区域
}
所以每当用户杀死应用程序或者让应用程序转到后台时,我们当然可以创建一个区域获取最新的当前位置。
func createRegion(location:CLLocation?){
如果CLLocationManager.isMonitoringAvailable(for:CLCircularRegion.self){
let coordinate = CLLocationCoordinate2DMake((location?.coordinate.latitude)!,(location?.coordinate.longitude)!)
let regionRadius = 50.0
让region = CLCircularRegion(center:CLLocationCoordinate2D(
latitude:coordinate.latitude,
longitude:coordinate.longitude),
radius:regionRadius,
identifier :aabb)
region.notifyOnExit = true
region.notifyOnEntry = true
//将提取的位置发送到服务器
//停止您的位置管理器以更新位置并启动regionMonitoring
self.locationManager?.stopUpda tingLocation()
self.locationManager?.startMonitoring(for:region)
}
else {
print(系统无法跟踪区域)
} $使用RegionDelegates
使用RegionDelegates pre> func locationManager(_ manager:CLLocationManager,didEnterRegion region:CLRegion){
print(输入区域)
}
func locationManager(_ manager:CLLocationManager,didExitRegion region:CLRegion){
print(Exited Region)
$ b $ locationManager.stopMonitoring(for:region)
/ /开始位置管理器并获取当前位置
locationManager?.startUpdatingLocation()
}
从 didUpdate
方法获取位置
$ b
func locationManager(_ manager :CLLocationManager,didUpdateLocations位置:[CLLocation]){
如果UIApplication.shared.applicationState == .act ive {
} else {
//应用程序处于BG / Killed或挂起状态
//发送位置到服务器
//创建一个包含当前获取位置的新区域
让位置= locations.last
lastLocation =位置
//制作区域并再次保持相同的循环。
self.createRegion(location:lastLocation)
}
}
我在这里做了一个半径为50米的区域圈。我已经测试了这一点,它通常在你从中心点穿过100米后被调用。
现在第二种方法可以使用 significantLocationChanges $ c
在使应用程序处于后台或终止状态时,我们可以停止位置管理器以进一步更新位置,并可以调用 startMonitoringSignificantLocationChanges code $
$ b $ pre $ self.locationManager?.stopUpdatingLocation()
self.locationManager?.startMonitoringSignificantLocationChanges()
当应用程序被终止时,位置将从 didFinishLaunching
$ launchOptions?[UIApplicationLaunchOptionsKey.location]
如果launchOptions ?[UIApplicationLaunchOptionsKey.location]!= nil {
//当应用处于死亡/未运行状态时,您有位置
}
请务必将 BackgroundModes 保留为位置更新
另外请确保要求使用该键的locationManager?.requestAlwaysAuthorization()
< key> NSLocationAlwaysUsageDescription< / key>
< string>允许位置< / string>
存放在 Info.plist中
可以通过同时 2 LocationManagers 同时获得第三种解决方案。
$ b
显着位置更改
使用 significantLocationChanges code
一旦设备从前一次通知中移动了500米
或更多,应用程序就会收到通知。它不应该比每五分钟更频繁地预期
通知。如果
设备能够从网络中检索数据,位置管理器
更有可能及时发送通知。
根据 Apple Doc
所以它完全取决于您的要求,因为取回位置取决于许多因素,例如应用程序未运行时打开的应用程序数量,电池电量,信号强度等。 / p>
请记住,要始终准确设置一个区域。
我知道这不会解决您的问题问题,但你会得到一个想法,按照你的要求前进。
Still very new to swift and trying my best. I have come from an Android background where there is BroadcastReceiver that can deliver location info to a service even though the app isn't running.
So I was looking for something similar in ios/swift and it appears that before this wasn't possible but it may be now. I am developing for iOS 10 but would be great if it was backwards compat.
I found
startMonitoringSignificantLocationChanges
which I can execute to start deliverying location updates, although this raises a few questions. Once I call this and my app is NOT running, are the updates still being sent ? And how would the app wake up to respond ?
Also restarting the phone and when it return, does this mean I still need call startMonitoringSignificantLocationChanges again meaning that I would have to wait for the user to execute my app. Or does it remember the setting after reboot ?
Still a little confused how to get around this, I suppose a brief explanation of what I am trying to do.
I would like to update the location of the phone even though the app is not running, this would be sent to a rest service every so often.
This way on the backend services I could determine if somebody is within X meters of somebody also and send them a push notification.
I would appreciate any help anyone can offer.
Thanks
解决方案 It may or may not be a good solution but if I were you I would have used both startMonitoringSignificantLocationChanges
and regionMonitoring
.
Lets take regionMonitoring
first. We have certainly no problems when the app is in foreground state and we can use the CLLocationManager's didUpdate
delegate to get the location and send it to the server.
Keep latest current location in AppDelegate's property, lets say:
var lastLocation:CLLocation?
//And a location manager
var locationManager = CLLocationManager()
We have two UIApplicationDelegates
func applicationDidEnterBackground(_ application: UIApplication) {
//Create a region
}
func applicationWillTerminate(_ application: UIApplication) {
//Create a region
}
So whenever the user kills the app or makes the app go to background, we can certainly create a region around the latest current location fetched. Here is an example to create a region.
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")
}
}
Make use of 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()
}
Grab the location from didUpdate
method
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)
}
}
Here I have made a 50m region radius circle. I have tested this and it is called generally after crossing 100m from your center point.
Now the second approach can me using significantLocationChanges
On making the app go background or terminated, we can just stop location manager for further updating locations and can call the startMonitoringSignificantLocationChanges
self.locationManager?.stopUpdatingLocation()
self.locationManager?.startMonitoringSignificantLocationChanges()
When the app is killed, the location is grabbed from didFinishLaunching
method's launchOptions?[UIApplicationLaunchOptionsKey.location]
if launchOptions?[UIApplicationLaunchOptionsKey.location] != nil {
//You have a location when app is in killed/ not running state
}
Make sure to keep BackgroundModes On for Location Updates
Also make sure to ask for locationManager?.requestAlwaysAuthorization()
by using the key
<key>NSLocationAlwaysUsageDescription</key>
<string>Allow location</string>
in your Info.plist
There can be a third solution by taking 2 LocationManagers simultaneously.
- For region
- Significant Location Changes
As using significantLocationChanges
Apps can expect a notification as soon as the device moves 500 meters
or more from its previous notification. It should not expect
notifications more frequently than once every five minutes. If the
device is able to retrieve data from the network, the location manager
is much more likely to deliver notifications in a timely manner.
as per the give Apple Doc
So it totally depends on your requirements as the location fetching depends on many factors like the number of apps opened, battery power, signal strength etc when the app is not running.
Also keep in mind to always setup a region with good accuracy.
I know that this will not solve your problem completely but you will get an idea to move forward as per your requirements.
这篇关于Swift:即使在应用程序未运行时也能收到位置信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!