Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 如何使用静默推送通知按需更新用户位置?网间网操作系统_Swift_Apple Push Notifications_Core Location_Appdelegate_Ios8.3 - Fatal编程技术网

Swift 如何使用静默推送通知按需更新用户位置?网间网操作系统

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

我只想按需跟踪用户当前位置。我只需要初始位置,不需要持续更新。我认为最好的方法是向用户发送静默通知,以便一次性获取用户的当前位置。接收静默通知工作正常,但LocationManager无法对位置进行初始修复。 我的Location Manager委托类通常会实例化,但在调用Location Manager方法startUpdatingLocation()后的任何时候都不会启动didUpdateLocations函数。当应用程序从AppDelegate:didFinishLaunchingWithOptions正常启动时,LocationManager会毫无问题地更新用户的位置

我正在开发Xcode 6.3.2到iOS 8.3

My AppDelegate:DidReceivereMotentification看起来像这样:

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的事情。