Swift:即使在应用程序未运行时也能收到位置信息? [英] Swift: Receiving Location even when app is not running?

查看:145
本文介绍了Swift:即使在应用程序未运行时也能收到位置信息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

还很新,迅速并尽我所能。我来自Android背景,那里有BroadcastReceiver,即使应用程序没有运行,它也可以提供位置信息给服务。



所以我一直在寻找类似的东西在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

在使应用程序处于后台或终止状态时,我们可以停止位置管理器以进一步更新位置,并可以调用 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.

    1. For region
    2. 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屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆