Ios 在挂起模式下接收推送后启动后台任务

Ios 在挂起模式下接收推送后启动后台任务,ios,objective-c,background,push-notification,Ios,Objective C,Background,Push Notification,这个问题似乎被问了好几次,但我面临着一个奇怪的问题 我已将服务器配置为发送内容可用=1标志的推送通知。 我已将我的应用程序配置为在上的后台模式下工作,用于位置更新、后台提取和远程通知。 我还实现了在后台接收推送通知和启动后台任务所需的所有代码 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(v

这个问题似乎被问了好几次,但我面临着一个奇怪的问题

我已将服务器配置为发送内容可用=1标志的推送通知。 我已将我的应用程序配置为在上的后台模式下工作,用于位置更新、后台提取和远程通知。 我还实现了在后台接收推送通知和启动后台任务所需的所有代码

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    __block UIBackgroundTaskIdentifier bg_task = background_task;
    background_task = [application beginBackgroundTaskWithExpirationHandler:^ {
        //Clean up code. Tell the system that we are done.
        [application endBackgroundTask: bg_task];
        bg_task = UIBackgroundTaskInvalid;
    }];
    //### background task starts
    [self updateLocationToServer];
    //#### background task ends
    completionHandler(UIBackgroundFetchResultNewData);
}

- (void)updateLocationToServer{

[locationManager updateLocationWithCompletionHandler:^(CLLocation *location, NSError *error, BOOL locationServicesDisabled) {
    if (error)
    {
        //  Handle error here
        if (locationServicesDisabled) {
            //  Location services are disabled, you can ask the user to enable them for example
        }
    }
    else
    {
        //  Do whatever you want with the current user's location
        NSString *deviceID = [userDefs objectForKey:@"deviceID"];
        isConnected = [[userDefs objectForKey:@"connected"] boolValue];
        if (isConnected) {
            if (deviceID) {
                [self sendLocation:deviceID];
            }
        }

        localNotif = [[UILocalNotification alloc] init];
        localNotif.fireDate = [NSDate dateWithTimeIntervalSinceNow:0.1];
        localNotif.timeZone = [NSTimeZone defaultTimeZone];
        localNotif.alertBody = [NSString stringWithFormat:@"Lat: %@ Long:%@",[NSNumber numberWithFloat:location.coordinate.latitude],[NSNumber numberWithFloat:location.coordinate.longitude]];

        [[UIApplication sharedApplication] scheduleLocalNotification:localNotif];

        NSLog(@"Lat: %@ Long:%@",[NSNumber numberWithFloat:location.coordinate.latitude],[NSNumber numberWithFloat:location.coordinate.longitude]);

        //Clean up code. Tell the system that we are done.
        [[UIApplication sharedApplication] endBackgroundTask: background_task];
        background_task = UIBackgroundTaskInvalid;}}];}
编辑:添加了结束后台任务的代码。背景任务变量是全局变量。
应用程序正常接收推送后台,直到进入暂停模式。问题是,在后台任务结束后,应用程序进入暂停模式,在收到推送通知时不会再次运行代码,但不会调用DidReceiveEmotentification:fetchCompletionHandler:。但当我打开应用程序并按home按钮退出时,它将在3分钟内再次工作,直到进入暂停模式。

在调用completionHandler之前是否调用endBackgroundTask?是的,它会在[self UpdateLocationServer]中调用;在接收到位置时结束。一切正常,但只有在应用程序进入暂停模式之前。3分钟后不启动表明您可能没有干净地结束后台任务-如果您不这样做,iOS将不会给您更多的后台时间。如何将bg_任务标识符传递给endBackgroundTask?这是一个当地的variable@Paulw11我添加了结束后台任务的代码。sendLocation:deviceID是同步任务。