【发布时间】:2014-03-05 13:47:15
【问题描述】:
我有一个将数据发布到服务器的应用程序。仅当用户在某个位置的一定距离内时才会发布此数据。我注册了后台位置更新,希望这能让我保持后台运行。但大约 17-18 分钟后,后台停止执行。
我认为这可能是因为 locationManager.pauseslocationupdatesautomatically。但即使我将其设置为 false,应用程序仍会在 17 分钟左右终止。这是我的应用委托的代码。
//
// BAAppDelegate.m
// Beacon App
//
// Created by Huy Ly on 2/10/13.
// Copyright (c) 2013 Placesign. All rights reserved.
//
#import "BAAppDelegate.h"
@implementation BAAppDelegate
@synthesize backgroundAnnouncementRevision, backgroundAnnouncementText, backgroundOfferDescription, backgroundOfferName, backgroundOfferPrice, backgroundOfferRevision, isAnnouncing, isOffering, locationManager, targetLocation, currentLocation, beaconTimer;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
NSLog(@"Application will resign active");
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(@"Application entered background");
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager setPausesLocationUpdatesAutomatically:YES];
[locationManager startUpdatingLocation];
NSLog(@"Starting timer for posting in background");
/*
//Runs the Timer on a background task main thread
UIApplication *app = [UIApplication sharedApplication];
//create new uiBackgroundTask
__block UIBackgroundTaskIdentifier bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];*/
//and create new timer with async call:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//run function methodRunAfterBackground
beaconTimer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(sendBeacon) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:beaconTimer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
});
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSLog(@"Application entered foreground");
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
[beaconTimer invalidate];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSLog(@"Application became active");
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
[beaconTimer invalidate];
}
- (void)applicationWillTerminate:(UIApplication *)application
{
NSLog(@"Application will terminate");
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
[beaconTimer invalidate];
}
-(void) sendBeacon{
NSLog(@"Beacon Background Send Started");
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
if ([[NSUserDefaults standardUserDefaults]valueForKey:@"PlaceID"]== nil) {
isAnnouncing = FALSE;
isOffering = FALSE;
}
//Do a single distance check to see if user is still within bounds
//Get the current location
[locationManager startUpdatingLocation];
//Compare current location with target location
CLLocationDistance distance = [currentLocation distanceFromLocation:targetLocation];
distance=distance/1000;
//If user is within location boundary, posts to server
if (distance < 0.1 || true) {
NSLog(@"Background Sent");
//Set Up the NSURL
NSString *urlString = [standardUserDefaults valueForKey:@"statusUpdate"];
NSURL *url = [NSURL URLWithString:urlString];
NSString *jsonString = [[NSString alloc] initWithFormat:@"{\"Announcement\":{\"Text\":\"%@\",\"ElementContext\":{\"Revision\":%@,\"Source\":{\"ID\":0,\"Type\":0}}},\"Offer\":{\"Description\":\"%@\",\"ElementContext\":{\"Revision\":%@,\"Source\":{\"ID\":0,\"Type\":0}},\"Name\":\"%@\",\"Price\":%@},\"OpStatus\":{\"ElementContext\":{\"Revision\":0,\"Source\":{\"ID\":0,\"Type\":0}},\"Value\":0},\"PlaceID\":%@,\"ResourcesOnPremise\":[{\"ElementContext\":{\"Revision\":0,\"Source\":{\"ID\":%@,\"Type\":1}},\"OnPremiseStatus\":2,\"Resource\":{\"ID\":%@,\"Type\":1}}],\"SignalSources\":[{\"LastSignal\":0,\"Source\":{\"ID\":0,\"Type\":0}}]}", backgroundAnnouncementText, backgroundAnnouncementRevision, backgroundOfferDescription, backgroundOfferRevision, backgroundOfferName, backgroundOfferPrice, [[NSUserDefaults standardUserDefaults]valueForKey:@"PlaceID"], [[NSUserDefaults standardUserDefaults]valueForKey:@"UserID"], [[NSUserDefaults standardUserDefaults]valueForKey:@"UserID"]];
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
//setup the request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:[NSString stringWithFormat:@"%d", [jsonString length]] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:jsonData];
NSURLConnection *requestConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[requestConnection start];
}
else{
}
}
-(void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(@"Location Manager failed with error %@", error);
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
currentLocation = [locations lastObject];
NSLog(@"Manager did update location");
}
-(void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager{
NSLog(@"Location Manager Paused");
}
-(void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager{
NSLog(@"Location Manager Resumed");
}
@end
【问题讨论】:
标签: ios iphone ios7 background core-location