iOS 애플리케이션에서 n분마다 백그라운드 위치 업데이트를 받으려면 어떻게 해야 합니까?
iOS 앱에서 n분마다 배경 위치 업데이트를 받을 수 있는 방법을 찾고 있습니다.저는 iOS 4.3을 사용하고 있으며, 이 솔루션은 탈옥되지 않은 아이폰에서 작동할 것입니다.
다음 옵션을 시도/검토했습니다.
CLLocationManager startUpdatingLocation/startMonitoringSignificantLocationChanges된 속성에에서 작동하지만 는 없는 것 .NSTimer앱이 포그라운드에서 실행되고 있지만 백그라운드 작업을 위해 설계되지 않은 것처럼 보일 때 작동합니다.- 로컬 알림:로컬 알림은 n분마다 예약할 수 있지만 현재 위치를 얻기 위해 일부 코드를 실행할 수 없습니다(사용자가 알림을 통해 앱을 실행할 필요가 없음).또한 이 접근 방식은 알림을 사용해야 하는 것이 아니기 때문에 깨끗한 접근 방식이 아닌 것 같습니다.
UIApplication:beginBackgroundTaskWithExpirationHandler제가 알기로는 앱을 백그라운드로 이동할 때 "오래 실행되는" 백그라운드 프로세스를 구현하는 것보다 백그라운드에서 일부 작업을 완료하는 데 사용해야 합니다(시간 제한도 있음).
이러한 정기적인 배경 위치 업데이트를 구현하려면 어떻게 해야 합니까?
Apple 개발자 포럼의 도움을 받아 이를 구현할 수 있는 솔루션을 찾았습니다.
- 를 지정합니다.
location background mode - 다음을 작성합니다.
NSTimer에 로배으하여경을하여▁inground.UIApplication:beginBackgroundTaskWithExpirationHandler: - 때
n보다 작습니다.UIApplication:backgroundTimeRemaining그것은 잘 작동할 수 있습니다. 때n더 크다, 더 크다,location manager백그라운드 작업이 종료되는 것을 방지하기 위해 남은 시간이 없기 전에 다시 활성화(및 비활성화)해야 합니다.
이것은 위치가 허용되는 세 가지 백그라운드 실행 유형 중 하나이기 때문에 작동합니다.
참고: 저는 이것이 작동하지 않는 시뮬레이터에서 이것을 테스트하면서 시간을 좀 잃었습니다.하지만 제 핸드폰에서는 잘 작동합니다.
iOS 8/9/10에서 5분마다 백그라운드 위치를 업데이트하려면 다음을 수행합니다.
Project -> Capabilities -> Background Mode -> Location updates 선택
프로젝트로 이동 -> 정보 -> 키 NS 위치 추가항상 사용설명 빈 값(또는 선택적으로 임의의 텍스트)
앱이 백그라운드에 있을 때 위치가 작동하도록 하고 5분마다 웹 서비스로 좌표를 보내거나 웹 서비스로 무엇이든 할 수 있도록 하기 위해 아래 코드와 같이 구현합니다.
백그라운드 작업이나 타이머를 사용하지 않습니다.저는 이 코드를 iOS 8.1로 테스트했는데, iOS 8.1은 앱을 백그라운드에서 실행한 상태로 몇 시간 동안 책상 위에 놓여 있었습니다.장치가 잠겨 있고 코드가 항상 제대로 실행되고 있습니다.
@interface LocationManager () <CLLocationManagerDelegate>
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (strong, nonatomic) NSDate *lastTimestamp;
@end
@implementation LocationManager
+ (instancetype)sharedInstance
{
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
LocationManager *instance = sharedInstance;
instance.locationManager = [CLLocationManager new];
instance.locationManager.delegate = instance;
instance.locationManager.desiredAccuracy = kCLLocationAccuracyBest; // you can use kCLLocationAccuracyHundredMeters to get better battery life
instance.locationManager.pausesLocationUpdatesAutomatically = NO; // this is important
});
return sharedInstance;
}
- (void)startUpdatingLocation
{
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusDenied)
{
NSLog(@"Location services are disabled in settings.");
}
else
{
// for iOS 8
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
{
[self.locationManager requestAlwaysAuthorization];
}
// for iOS 9
if ([self.locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)])
{
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
}
[self.locationManager startUpdatingLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *mostRecentLocation = locations.lastObject;
NSLog(@"Current location: %@ %@", @(mostRecentLocation.coordinate.latitude), @(mostRecentLocation.coordinate.longitude));
NSDate *now = [NSDate date];
NSTimeInterval interval = self.lastTimestamp ? [now timeIntervalSinceDate:self.lastTimestamp] : 0;
if (!self.lastTimestamp || interval >= 5 * 60)
{
self.lastTimestamp = now;
NSLog(@"Sending current location to web service.");
}
}
@end
저는 제가 개발하고 있는 애플리케이션에서 이것을 했습니다.앱이 백그라운드에 있지만 앱이 위치 업데이트를 지속적으로 수신할 때는 타이머가 작동하지 않습니다.설명서의 어딘가에서 앱이 백그라운드에 있을 때 활성 실행 루프에서만 메서드를 호출할 수 있다는 내용을 읽었습니다(지금은 찾을 수 없습니다, 찾을 때 업데이트를 게시하겠습니다).앱 대리인은 bg에서도 실행 루프가 활성화되어 있으므로 이 작업을 수행하기 위해 사용자가 직접 생성할 필요가 없습니다.[이것이 정확한 설명인지는 모르겠지만 제가 읽은 것을 보면 그렇게 이해했습니다.]
우선, 다을추니다가합을 합니다.location 제이기 의한 쇠▁for▁key의 객체UIBackgroundModes앱의 info.plist에 있습니다.이제 앱에서 위치 업데이트를 시작해야 합니다.
CLLocationManager locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;//or whatever class you have for managing location
[locationManager startUpdatingLocation];
다음으로, 위치 업데이트를 처리하는 방법을 작성합니다.-(void)didUpdateToLocation:(CLLocation*)location앱 대리인에서.에 그다음방법을구다니현합런▁method▁the다니구 방법을 실행합니다.locationManager:didUpdateLocation:fromLocationCLLocationManagerDelegate위치 관리자를 시작한 클래스입니다(위치 관리자 위임을 '자체'로 설정했기 때문).이 방법에서는 위치 업데이트를 처리해야 하는 시간 간격이 경과했는지 확인해야 합니다.매번 현재 시간을 저장하여 이 작업을 수행할 수 있습니다.한 경우앱 합니다.
NSDate *newLocationTimestamp = newLocation.timestamp;
NSDate *lastLocationUpdateTiemstamp;
int locationUpdateInterval = 300;//5 mins
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if (userDefaults) {
lastLocationUpdateTiemstamp = [userDefaults objectForKey:kLastLocationUpdateTimestamp];
if (!([newLocationTimestamp timeIntervalSinceDate:lastLocationUpdateTiemstamp] < locationUpdateInterval)) {
//NSLog(@"New Location: %@", newLocation);
[(AppDelegate*)[UIApplication sharedApplication].delegate didUpdateToLocation:newLocation];
[userDefaults setObject:newLocationTimestamp forKey:kLastLocationUpdateTimestamp];
}
}
}
이렇게 하면 앱이 백그라운드에 있을 때도 5분마다 메서드가 호출됩니다.Imp:이하지 않은 Imp: 이은구배방전다니킵시를 . 위치 데이터의 정확성이 중요하지 않은 경우 사용해야 합니다.[locationManager startMonitoringSignificantLocationChanges]
앱에 추가하기 전에 위치 인식 프로그래밍 가이드를 읽어 보십시오.
iOS6가 출시된 이상 위치 서비스를 영구적으로 실행할 수 있는 가장 좋은 방법은...
- (void)applicationWillResignActive:(UIApplication *)application
{
/*
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.
*/
NSLog(@"to background");
app.isInBackground = TRUE;
UIApplication *app = [UIApplication sharedApplication];
// Request permission to run in the background. Provide an
// expiration handler in case the task runs long.
NSAssert(bgTask == UIBackgroundTaskInvalid, nil);
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
// Synchronize the cleanup call on the main thread in case
// the task actually finishes at around the same time.
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task.
locationManager.distanceFilter = 100;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
[locationManager startMonitoringSignificantLocationChanges];
[locationManager startUpdatingLocation];
NSLog(@"App staus: applicationDidEnterBackground");
// Synchronize the cleanup call on the main thread in case
// the expiration handler is fired at the same time.
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
});
NSLog(@"backgroundTimeRemaining: %.0f", [[UIApplication sharedApplication] backgroundTimeRemaining]);
}
방금 그렇게 테스트했습니다.
저는 앱을 시작했고, 뒤로 가서 몇 분 정도 차 안으로 이동했습니다.그런 다음 1시간 동안 집에 가서 다시 움직이기 시작합니다(앱을 다시 열지 않고).위치가 다시 시작되었습니다.그리고 나서 두 시간 동안 멈추었다가 다시 시작했습니다.모든게 다시 괜찮아졌어요...
iOS6에서 새로운 위치 서비스를 사용하는 것을 잊지 마십시오.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *loc = [locations lastObject];
// Lat/Lon
float latitudeMe = loc.coordinate.latitude;
float longitudeMe = loc.coordinate.longitude;
}
악몽을 꾸고 있는 다른 사람에게 이것을 알아내세요.간단한 해결책이 있습니다.
- raywenderlich.com ->에서 이 예를 보십시오. 샘플 코드가 있습니다. 이것은 완벽하게 작동하지만 안타깝게도 백그라운드 위치에서 타이머가 없습니다.이것은 무기한으로 실행됩니다.
다음을 사용하여 타이머 추가:
-(void)applicationDidEnterBackground { [self.locationManager stopUpdatingLocation]; UIApplication* app = [UIApplication sharedApplication]; bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ [app endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid; }]; self.timer = [NSTimer scheduledTimerWithTimeInterval:intervalBackgroundUpdate target:self.locationManager selector:@selector(startUpdatingLocation) userInfo:nil repeats:YES]; }info.plist에 "위치 업데이트를 위한 앱 레지스터"를 추가하는 것을 잊지 마십시오.
제가 사용하는 것은 다음과 같습니다.
import Foundation
import CoreLocation
import UIKit
class BackgroundLocationManager :NSObject, CLLocationManagerDelegate {
static let instance = BackgroundLocationManager()
static let BACKGROUND_TIMER = 150.0 // restart location manager every 150 seconds
static let UPDATE_SERVER_INTERVAL = 60 * 60 // 1 hour - once every 1 hour send location to server
let locationManager = CLLocationManager()
var timer:NSTimer?
var currentBgTaskId : UIBackgroundTaskIdentifier?
var lastLocationDate : NSDate = NSDate()
private override init(){
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
locationManager.activityType = .Other;
locationManager.distanceFilter = kCLDistanceFilterNone;
if #available(iOS 9, *){
locationManager.allowsBackgroundLocationUpdates = true
}
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.applicationEnterBackground), name: UIApplicationDidEnterBackgroundNotification, object: nil)
}
func applicationEnterBackground(){
FileLogger.log("applicationEnterBackground")
start()
}
func start(){
if(CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedAlways){
if #available(iOS 9, *){
locationManager.requestLocation()
} else {
locationManager.startUpdatingLocation()
}
} else {
locationManager.requestAlwaysAuthorization()
}
}
func restart (){
timer?.invalidate()
timer = nil
start()
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case CLAuthorizationStatus.Restricted:
//log("Restricted Access to location")
case CLAuthorizationStatus.Denied:
//log("User denied access to location")
case CLAuthorizationStatus.NotDetermined:
//log("Status not determined")
default:
//log("startUpdatintLocation")
if #available(iOS 9, *){
locationManager.requestLocation()
} else {
locationManager.startUpdatingLocation()
}
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if(timer==nil){
// The locations array is sorted in chronologically ascending order, so the
// last element is the most recent
guard let location = locations.last else {return}
beginNewBackgroundTask()
locationManager.stopUpdatingLocation()
let now = NSDate()
if(isItTime(now)){
//TODO: Every n minutes do whatever you want with the new location. Like for example sendLocationToServer(location, now:now)
}
}
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
CrashReporter.recordError(error)
beginNewBackgroundTask()
locationManager.stopUpdatingLocation()
}
func isItTime(now:NSDate) -> Bool {
let timePast = now.timeIntervalSinceDate(lastLocationDate)
let intervalExceeded = Int(timePast) > BackgroundLocationManager.UPDATE_SERVER_INTERVAL
return intervalExceeded;
}
func sendLocationToServer(location:CLLocation, now:NSDate){
//TODO
}
func beginNewBackgroundTask(){
var previousTaskId = currentBgTaskId;
currentBgTaskId = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({
FileLogger.log("task expired: ")
})
if let taskId = previousTaskId{
UIApplication.sharedApplication().endBackgroundTask(taskId)
previousTaskId = UIBackgroundTaskInvalid
}
timer = NSTimer.scheduledTimerWithTimeInterval(BackgroundLocationManager.BACKGROUND_TIMER, target: self, selector: #selector(self.restart),userInfo: nil, repeats: false)
}
}
저는 AppDelegate에서 다음과 같이 추적을 시작합니다.
BackgroundLocationManager.instance.start()
불행하게도, 여러분의 모든 가정이 옳은 것처럼 보이고, 저는 이것을 할 방법이 없다고 생각합니다.배터리 수명을 절약하기 위해 아이폰의 위치 서비스는 이동을 기반으로 합니다.전화기가 한 곳에 있으면 위치 서비스에 보이지 않습니다.
그CLLocationManager전화만 할 것입니다.locationManager:didUpdateToLocation:fromLocation:전화기가 위치 업데이트를 수신할 때, 이는 세 가지 위치 서비스(셀 타워, gps, wifi) 중 하나가 변경을 감지할 때만 발생합니다.
추가 솔루션에 도움이 될 수 있는 몇 가지 다른 사항:
서비스를 시작 및 중지하면 다음과 같은 문제가 발생합니다.
didUpdateToLocation합니다. 호할위메서그, 나러드newLocation오래된 타임스탬프가 있을 수 있습니다.백그라운드에서 실행하는 경우 Apple에서 "전체" 위치 서비스 지원을 승인받기 어려울 수 있습니다.제가 본 바로는, 그들이 특별히 디자인한 것은
startMonitoringSignificantLocationChanges백그라운드 위치 지원이 필요한 앱을 위한 저전력 대안으로, 앱이 절대적으로 필요하지 않는 한 개발자들이 이를 사용하도록 강력하게 권장합니다.
행운을 빕니다.
업데이트: 이러한 생각은 지금쯤 시대에 뒤떨어진 것일 수 있습니다.위의 @wjans 답변으로 사람들이 성공을 거두고 있는 것처럼 보입니다.
위치 서비스를 이용하여 앱을 작성했는데, 앱은 10초마다 위치를 전송해야 합니다.그리고 그것은 매우 잘 작동했습니다.
Apple의 문서에 따라 "여행할 때까지 지연된 위치 업데이트 허용: 제한 시간" 방법을 사용하십시오.
제가 한 일은:
필수:위치 업데이트에 대한 백그라운드 모드를 등록합니다.
작성LocationManger그리고.startUpdatingLocation,와 함께accuracy그리고.filteredDistance원하는 대로:
-(void) initLocationManager
{
// Create the manager object
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
_locationManager.delegate = self;
// This is the most important property to set for the manager. It ultimately determines how the manager will
// attempt to acquire location and thus, the amount of power that will be consumed.
_locationManager.desiredAccuracy = 45;
_locationManager.distanceFilter = 100;
// Once configured, the location manager must be "started".
[_locationManager startUpdatingLocation];
}
앱을 영구적으로 실행하려면 다음을 사용합니다.allowDeferredLocationUpdatesUntilTraveled:timeout에서 다시 시작해야 .updatingLocation앱이 백그라운드로 이동할 때 다음과 같이 새 매개 변수를 사용합니다.
- (void)applicationWillResignActive:(UIApplication *)application {
_isBackgroundMode = YES;
[_locationManager stopUpdatingLocation];
[_locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[_locationManager setDistanceFilter:kCLDistanceFilterNone];
_locationManager.pausesLocationUpdatesAutomatically = NO;
_locationManager.activityType = CLActivityTypeAutomotiveNavigation;
[_locationManager startUpdatingLocation];
}
앱은 정상적으로 위치를 업데이트합니다.locationManager:didUpdateLocations: 콜백:
-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// store data
CLLocation *newLocation = [locations lastObject];
self.userLocation = newLocation;
//tell the centralManager that you want to deferred this updatedLocation
if (_isBackgroundMode && !_deferringUpdates)
{
_deferringUpdates = YES;
[self.locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:10];
}
}
하지만 당신은 그때 데이터를 처리해야 합니다.locationManager:didFinishDeferredUpdatesWithError:의 목적을 .
- (void) locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error {
_deferringUpdates = NO;
//do something
}
5.참고: 다음의 매개 변수를 재설정해야 합니다.LocationManager앱이 백그라운드/그라운드 모드로 전환될 때마다.
if ([self.locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
}
iOS 9부터 백그라운드 위치 추적에 필요합니다.
을 얻는 (xs2bush 사용)을했습니다.timeIntervalSinceDate 그 확장했습니다. 그리고 그것에 대해 약간 확장했습니다.GPS 라디오를 필요 이상으로 켜 놓음으로써 필요한 정확도를 확보하고 배터리가 방전되지 않았는지 확인하고 싶었습니다.
다음 설정을 사용하여 위치를 계속 실행합니다.
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
locationManager.distanceFilter = 5;
이는 상대적으로 배터리 소모량이 적습니다.다음 주기적인 위치 판독을 수행할 준비가 되면 먼저 위치가 원하는 정확도 내에 있는지 확인하고, 정확한 경우 위치를 사용합니다.그렇지 않은 경우 다음과 같이 정확도를 높입니다.
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
locationManager.distanceFilter = 0;
위치를 파악한 다음 위치를 확인하면 배터리 소모를 최소화하기 위해 정확도를 다시 낮춥니다.저는 이것의 전체 작업 샘플을 작성했고, 또한 위치 데이터를 수집하고 데이터베이스에 저장하며 사용자가 실시간으로 gps 데이터를 보거나 이전에 저장된 경로를 검색하고 볼 수 있도록 서버 측 코드의 소스를 작성했습니다.저는 iOS, 안드로이드, 윈도우 폰, 그리고 자바를 위한 고객들을 가지고 있습니다.모든 클라이언트는 기본적으로 작성되며 모두 백그라운드에서 올바르게 작동합니다.이 프로젝트는 MIT 허가를 받았습니다.
iOS 프로젝트는 iOS 7의 기본 SDK를 사용하는 iOS 6을 대상으로 합니다.여기서 코드를 받을 수 있습니다.
문제가 있으면 github에 문제를 제기해주세요.감사해요.
stopUpdatingLocation이 백그라운드 감시 타이머를 트리거하는 것 같습니다. 그래서 didUpdateLocation에서 다음으로 대체했습니다.
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyThreeKilometers];
[self.locationManager setDistanceFilter:99999];
효과적으로 GPS의 전원을 끄는 것으로 보입니다.그러면 백그라운드 NSTimer의 선택기는 다음과 같습니다.
- (void) changeAccuracy {
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
}
몇 분마다 정확도가 높은 좌표를 얻기 위해 주기적으로 정확도를 전환하는 것뿐이며 locationManager가 중지되지 않았기 때문에 backgroundTimeRemaining은 최대값으로 유지됩니다.이를 통해 장치의 배터리 소비량이 시간당 최대 10%(백그라운드에서 kCL 위치 정확도 최고)에서 시간당 최대 2%로 감소했습니다.
원하는 위치 정확도로 n초마다 백그라운드 위치 업데이트를 받을 수 있는 코코팟 APS scheduled Location Manager가 있습니다.
let manager = APScheduledLocationManager(delegate: self)
manager.startUpdatingLocation(interval: 170, acceptableLocationAccuracy: 100)
저장소에는 Swift 3으로 작성된 예제 앱도 포함되어 있습니다.
iOS 9 및 watch OS 2.0에는 현재 위치를 요청할 수 있는 CLLocationManager의 새로운 방법인 CLLocationManager:requestLocation()이 있습니다.이 작업은 즉시 완료된 다음 위치를 CLLocationManager 대리인에게 반환합니다.
이제 NSTimer를 사용하여 이 메서드를 사용하여 매 분마다 위치를 요청할 수 있으므로 startUpdatingLocation 및 stopUpdatingLocation 메서드를 사용할 필요가 없습니다.
그러나 마지막 위치에서 Xm를 변경하여 위치를 캡처하려면 CLLocationManager의 distanceFilter 속성을 설정하고 X startUpdatingLocation()을 호출합니다.
첨부된 Swift 솔루션은 다음 지역에 기반을 기반으로 합니다.
정App registers for location updates 파일에서
LocationManager를 항상 실행 상태로 유지
스kCLLocationAccuracyBestForNavigation) 및 (5초간)ThreeKilometers .
이 예제는 포그라운드에서 1분마다, 백그라운드에서 15분마다 위치를 업데이트합니다.
이 예제는 iOS 7 장치에서 실행되는 Xcode 6 베타 6에서 잘 작동합니다.
App Delegate에서 (mapView는 mapView 컨트롤러를 가리키는 선택 사항입니다)
func applicationDidBecomeActive(application: UIApplication!) {
if appLaunched! == false { // Reference to mapView used to limit one location update per timer cycle
appLaunched = true
var appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
var window = appDelegate.window
var tabBar = window?.rootViewController as UITabBarController
var navCon = tabBar.viewControllers[0] as UINavigationController
mapView = navCon.topViewController as? MapViewController
}
self.startInitialPeriodWithTimeInterval(60.0)
}
func applicationDidEnterBackground(application: UIApplication!) {
self.startInitialPeriodWithTimeInterval(15 * 60.0)
}
func startInitialPeriodWithTimeInterval(timeInterval: NSTimeInterval) {
timer?.invalidate() // reset timer
locationManager?.desiredAccuracy = kCLLocationAccuracyBestForNavigation
timer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: Selector("getFirstLocationUpdate:"), userInfo: timeInterval, repeats: false)
}
func getFirstLocationUpdate(sender: NSTimer) {
let timeInterval = sender.userInfo as Double
timer?.invalidate()
mapView?.canReportLocation = true
timer = NSTimer.scheduledTimerWithTimeInterval(timeInterval, target: self, selector: Selector("waitForTimer:"), userInfo: timeInterval, repeats: true)
}
func waitForTimer(sender: NSTimer) {
let time = sender.userInfo as Double
locationManager?.desiredAccuracy = kCLLocationAccuracyBestForNavigation
finalTimer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: Selector("getLocationUpdate"), userInfo: nil, repeats: false)
}
func getLocationUpdate() {
finalTimer?.invalidate()
mapView?.canReportLocation = true
}
mapView(locationManager가 AppDelegate의 개체를 가리킴)에서
override func viewDidLoad() {
super.viewDidLoad()
var appDelegate = UIApplication.sharedApplication().delegate! as AppDelegate
locationManager = appDelegate.locationManager!
locationManager.delegate = self
canReportLocation = true
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
if canReportLocation! {
canReportLocation = false
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
} else {
//println("Ignore location update")
}
}
언급URL : https://stackoverflow.com/questions/6347503/how-do-i-get-a-background-location-update-every-n-minutes-in-my-ios-application
'programing' 카테고리의 다른 글
| 루비: 배열에서 첫 번째 요소를 제거하는 가장 쉬운 방법은 무엇입니까? (0) | 2023.06.01 |
|---|---|
| mongodb에 인덱스가 있는지 확인하는 중 (0) | 2023.06.01 |
| 일치하는 줄 뒤에서 시작하여 파일의 모든 줄을 삭제하려면 어떻게 해야 합니까? (0) | 2023.06.01 |
| 안드로이드 애플리케이션에서 충돌 데이터를 가져오려면 어떻게 해야 합니까? (0) | 2023.06.01 |
| 스토어를 여는 데 사용된 모델이 스토어를 만드는 데 사용된 모델과 호환되지 않습니다. (0) | 2023.06.01 |