Swift 如何使用静默推送通知按需更新用户位置?网间网操作系统
我只想按需跟踪用户当前位置。我只需要初始位置,不需要持续更新。我认为最好的方法是向用户发送静默通知,以便一次性获取用户的当前位置。接收静默通知工作正常,但LocationManager无法对位置进行初始修复。 我的Location Manager委托类通常会实例化,但在调用Location Manager方法startUpdatingLocation()后的任何时候都不会启动didUpdateLocations函数。当应用程序从AppDelegate:didFinishLaunchingWithOptions正常启动时,LocationManager会毫无问题地更新用户的位置 我正在开发Xcode 6.3.2到iOS 8.3 My AppDelegate:DidReceivereMotentification看起来像这样:Swift 如何使用静默推送通知按需更新用户位置?网间网操作系统,swift,apple-push-notifications,core-location,appdelegate,ios8.3,Swift,Apple Push Notifications,Core Location,Appdelegate,Ios8.3,我只想按需跟踪用户当前位置。我只需要初始位置,不需要持续更新。我认为最好的方法是向用户发送静默通知,以便一次性获取用户的当前位置。接收静默通知工作正常,但LocationManager无法对位置进行初始修复。 我的Location Manager委托类通常会实例化,但在调用Location Manager方法startUpdatingLocation()后的任何时候都不会启动didUpdateLocations函数。当应用程序从AppDelegate:didFinishLaunchingWith
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler handler: (UIBackgroundFetchResult) -> Void) {
var bgTask = bgManager()
bgTask.registerBackgroundTask()
LocManager.locationMngr.startUpdatingLocation() // LocManager is global variable
let delayInSeconds = 8.0
let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delayInSeconds * Double(NSEC_PER_SEC)))
dispatch_after(popTime, dispatch_get_main_queue()) {
println(LocManager.updated)
bgTask.endBackgroundTask()
handler(UIBackgroundFetchResult.NewData)
}
}
我第一次只试了一句话:
LocManager.locationMngr.startUpdatingLocation()
但当它不起作用时,我添加了后台任务,并在任务结束后发送_,以确保我的位置经理有足够的时间在终止之前检索第一个位置更新
以下是LocationManager类:
class LocationManager: NSObject, CLLocationManagerDelegate {
let locationMngr:CLLocationManager
var coord:CLLocationCoordinate2D
var updated:Bool
override init() {
locationMngr = CLLocationManager()
coord = CLLocationCoordinate2D()
updated = false
super.init()
locationMngr.delegate = self
locationMngr.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationMngr.startUpdatingLocation() //Should call didUpdateLocations after some time
}
//Doesn't get called in AppDelegate remoteNotifications method
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)
{
var loc:CLLocation = locations.first as! CLLocation
self.coord = loc.coordinate
locationMngr.stopUpdatingLocation()
updated = true
}
class bgManager:NSObject{
var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
override init(){
super.init()
}
func registerBackgroundTask() {
backgroundTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler {
[unowned self] in
self.endBackgroundTask()
}
}
func endBackgroundTask() {
UIApplication.sharedApplication().endBackgroundTask(backgroundTask)
backgroundTask = UIBackgroundTaskInvalid
}
}
和后台管理器类:
class LocationManager: NSObject, CLLocationManagerDelegate {
let locationMngr:CLLocationManager
var coord:CLLocationCoordinate2D
var updated:Bool
override init() {
locationMngr = CLLocationManager()
coord = CLLocationCoordinate2D()
updated = false
super.init()
locationMngr.delegate = self
locationMngr.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationMngr.startUpdatingLocation() //Should call didUpdateLocations after some time
}
//Doesn't get called in AppDelegate remoteNotifications method
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)
{
var loc:CLLocation = locations.first as! CLLocation
self.coord = loc.coordinate
locationMngr.stopUpdatingLocation()
updated = true
}
class bgManager:NSObject{
var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
override init(){
super.init()
}
func registerBackgroundTask() {
backgroundTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler {
[unowned self] in
self.endBackgroundTask()
}
}
func endBackgroundTask() {
UIApplication.sharedApplication().endBackgroundTask(backgroundTask)
backgroundTask = UIBackgroundTaskInvalid
}
}
接收到的远程推送的JSON:
"aps" : {
"sound" : "",
"content-available" : 1,
"priority" : 5
}
我有所有必需的plist.info键和后台模式,用于在项目功能:后台模式中启用获取、通知和位置。
plist.info代码段:
<dict>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>location-services</string>
<string></string>
<string></string>
</array>
<key>UIBackgroundModes</key>
<array>
<string>remote-notification</string>
<string>fetch</string>
<string>location</string>
</array>
<key>NSLocationAlwaysUsageDescription</key>
<string>Your location is needed for this app.</string>
...
UIRequiredDeviceCapabilities
我遇到了同样的问题,并按照OP的确切步骤进行了操作,但没有成功。最后我发现我只请求了CLLocationManager.requestWhenUseAuthorization()
,它只在应用程序位于前台时提供位置。我必须请求CLLocationManager.requestAlwaysAuthorization()
,以便应用程序在后台请求位置。还要确保在Info.plist
文件中有NSLocationAlwaysUsageDescription
条目。通过这些更改,我可以直接使用CLLocationManager.startUpdatingLocation()
,并能够在后台接收位置更新。在后台启动应用程序时,在startUpdatingLocation()
之前调用StartMonitoringSignificationLocationChanges()
请记住在完成后调用stopmoningsignificantlocationchanges()
和stopdatinglocation()
。我觉得这几乎肯定会导致你的应用被拒绝。你在制作什么样的应用?为什么需要这样做?@endy如果我找到其他方法来实现相同的功能,我会这样做。有什么建议吗?:)@我希望在需要时接收某些用户的位置。我只需要接收其他用户的位置一次,而不是在一个连续的基础上。为了避免垃圾发送可见通知,我希望以静默方式进行。您可以使用导航API在后台保持应用程序的打开状态。他们的导航栏将显示“foo在后台使用你的位置”。但是一旦他们完全关闭了你的应用程序,你就无法得到他们的位置。这是故意的。我知道我不想让一个随机的应用程序知道我在哪里,只要创建者想知道。你能发布一个代码的工作示例吗?我正在尝试做一些类似于OP的事情。