iOS перепроверить местоположение при загрузке из фона - PullRequest
4 голосов
/ 13 сентября 2011

Я создаю приложение, которое отображает результаты в зависимости от вашего текущего местоположения.

В настоящее время я использую viewDidLoad метод UIViewController для запуска CLLocationManager и получения текущего местоположения. Как только у меня есть местоположение, которое соответствует желаемой точности, я делаю запрос в свой веб-сервис, чтобы получить результаты и вывести его в UITableView.

Моя проблема в том, что когда вы закрываете приложение (хотя оно все еще работает в фоновом режиме). Если вам нужно ехать в другой город, заново откройте приложение, данные не обновляются и продолжают показывать результаты из вашего старого местоположения.

Обычно, когда UIViewController загружается из фона, мне нужно иметь возможность проверять местоположение пользователей, и, если они переместились на значительное расстояние, обновить содержимое моего UITableView.

Однако, поскольку viewDidAppear из UIViewController не запускается при загрузке приложения из фона, я не уверен, какой метод я могу использовать.

Мне известен метод stopMonitoringSignificantLocationChanges, который активирует ваше приложение при обнаружении нового местоположения. Тем не менее, это выглядит немного OTT, потому что мне нужно знать только после загрузки приложения.

Есть ли альтернатива использованию метода stopMonitoringSignificantLocationChanges?

Ответы [ 3 ]

12 голосов
/ 13 сентября 2011

Вы можете зарегистрироваться для получения уведомлений от UIApplication в -viewDidLoad.Вы можете быть заинтересованы в UIApplicationDidBecomeActiveNotification.Регистрация для уведомлений проста.

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
}

В -viewDidLoad мы добавляем себя в качестве наблюдателя UIApplicationDidBecomeActiveNotification и указываем селектор, который будет вызываться при получении этого конкретного уведомления.

Наконец, не забудьте удалить себя в качестве наблюдателя для этого уведомления, когда представление выгружается.Это хорошая практика, чтобы сбалансировать ваши вызовы addObserver / removeObserver к NSNotificationCenter таким образом.

2 голосов
/ 14 сентября 2011

Вы можете зарегистрировать свой вид для уведомлений. Для представлений, которые должны отслеживать состояние приложения, я использую этот удобный суперкласс.

@implementation BackgroundAwareObject

-init
{
    if(self=[super init])
    {
        NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
        [center addObserver:self selector:@selector(notifyApplicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
        [center addObserver:self selector:@selector(notifyApplicationWillEnterForeground:) name: UIApplicationWillEnterForegroundNotification object:nil];
        [center addObserver:self selector:@selector(notifyApplicationDidFinishLaunching:) name: UIApplicationDidFinishLaunchingNotification object:nil];
        [center addObserver:self selector:@selector(notifyApplicationDidBecomeActive:) name: UIApplicationDidBecomeActiveNotification object:nil];
        [center addObserver:self selector:@selector(notifyApplicationWillResignActive:) name: UIApplicationWillResignActiveNotification object:nil];
        [center addObserver:self selector:@selector(notifyApplicationDidReceiveMemoryWarning:) name: UIApplicationDidReceiveMemoryWarningNotification object:nil];
        [center addObserver:self selector:@selector(notifyApplicationWillTerminate:) name: UIApplicationWillTerminateNotification object:nil];
    }
    return self;
}

-(void)notifyApplicationDidEnterBackground:(NSNotification*)n
{
    [self applicationDidEnterBackground:[UIApplication sharedApplication]];
}

-(void)notifyApplicationWillEnterForeground:(NSNotification*)n
{
    [self applicationWillEnterForeground:[UIApplication sharedApplication]];
}

-(void)notifyApplicationDidFinishLaunching:(NSNotification*)n
{
    [self application:[UIApplication sharedApplication] didFinishLaunchingWithOptions: [n userInfo]];
}

-(void)notifyApplicationDidBecomeActive:(NSNotification*)n
{
    [self applicationDidBecomeActive:[UIApplication sharedApplication]];
}

-(void)notifyApplicationWillResignActive:(NSNotification*)n
{
    [self applicationWillResignActive:[UIApplication sharedApplication]];
}

-(void)notifyApplicationDidReceiveMemoryWarning:(NSNotification*)n
{
    [self applicationDidReceiveMemoryWarning:[UIApplication sharedApplication]];
}

-(void)notifyApplicationWillTerminate:(NSNotification*)n
{
    [self applicationWillTerminate:[UIApplication sharedApplication]];
}

-(void)configurationChanged
{
    // User has update application configuration panel

}

- (void)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{    
    // Override point for customization after application launch.  

}


- (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.
     */
}


- (void)applicationDidEnterBackground:(UIApplication *)application 
{
    /*
     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, called instead of applicationWillTerminate: when the user quits.
     */
    _background = YES;
}


- (void)applicationWillEnterForeground:(UIApplication *)application 
{
    /*
     Called as part of  transition from the background to the active state: here you can undo many of the changes made on entering the background.
     */
}


- (void)applicationDidBecomeActive:(UIApplication *)application 
{
    /*
     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.
     */
    _background = NO;
}


/**
 applicationWillTerminate: saves changes in the application's managed object context before the application terminates.
 */
- (void)applicationWillTerminate:(UIApplication *)application
{
}

// try to clean up as much memory as possible. next step is to terminate app
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
}

-(void)dealloc
{
    [[NSNotificationCenter defaultCenter]removeObserver:self];
    [super dealloc];
}

@end
1 голос
/ 13 сентября 2011

В вашем AppDelegate.m этот метод должен быть предопределен (как в шаблоне, который вы создали изначально при запуске проекта в XCode) -

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    /*
     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.
     */
}

Как сказано в описании, этот метод автоматически вызывается iOS, когда приложение собирается стать активным. Здесь вы можете получить последнее местоположение для дальнейшей обработки.

...