iOS 从后台重新检查加载位置

发布于 2024-12-04 13:07:17 字数 661 浏览 0 评论 0原文

我正在构建一个应用程序,它根据您当前的位置显示结果数据。

目前,我正在使用 UIViewController 的 viewDidLoad 方法来启动 CLLocationManager 并获取当前位置。一旦我获得了与我想要的准确度相匹配的位置,我就会向我的 Web 服务发出请求以获取结果并将其转储到 UITableView 中。

我的问题是,当您关闭应用程序时(尽管它仍在后台运行)。如果您要开车前往另一个城镇,请重新打开应用程序,数据不会更新,并继续显示您原来位置的结果。

基本上,当 UIViewController 从后台加载时,我需要能够检查用户位置,如果他们移动了很远的距离,则更新我的 UITableView 的内容。

但是,由于从后台加载应用程序时不会触发 UIViewControllerviewDidAppear,因此我不确定可以使用哪种方法。

我知道 stopMonitoringSignificantLocationChanges 方法会在发现新位置时唤醒您的应用程序。然而,这似乎有点 OTT,因为我只需要在应用程序加载后就知道。

除了使用 stopMonitoringSignificantLocationChanges 方法之外,还有其他选择吗?

I'm building an app which displays result data based on your current location.

At the moment, I'm using the viewDidLoad method of a UIViewController to start the CLLocationManager and getting the current location. Once I have the location that matches the accuracy I desire, I do a request to my web service to get the results and dump it into a UITableView.

My problem is that when you close the app (although it's still running in the background). If you were to drive to another town, re-open the app, the data doesn't get updated and continues to show the results from your old location.

Basically when the UIViewController loads from the background, I need to be able to check the users location, and if they have moved a significant distance, update the contents of my UITableView.

However, because the viewDidAppear of the UIViewController isn't triggered when you load the app from the background, I'm not sure which method I can use.

I am aware of the stopMonitoringSignificantLocationChanges method which wakes up your app when a new location is found. However, this seems a little OTT because I only need to know once the app has loaded.

Is there any alternative to using the stopMonitoringSignificantLocationChanges method?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

薆情海 2024-12-11 13:07:17

您可以在 -viewDidLoad 中注册以接收来自 UIApplication 的通知。您可能对UIApplicationDidBecomeActiveNotification感兴趣。注册通知很简单。

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

-viewDidLoad 中,我们将自己添加为 UIApplicationDidBecomeActiveNotification 的观察者,并指定在收到特定通知时要调用的选择器。

- (void)applicationDidBecomeActive:(NSNotification *)notification
{
    // Kick off your CLLocationManager
    [self updateCurrentLocation];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
}

最后,请记住在视图卸载时将自己删除为该通知的观察者。以这种方式平衡对 NSNotificationCenter 的 addObserver/removeObserver 调用是一个很好的做法。

You could register to receive notifications from UIApplication in -viewDidLoad. You may be interested in UIApplicationDidBecomeActiveNotification. Registering for notifications is easy.

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

In -viewDidLoad we add ourselves as an observer of the UIApplicationDidBecomeActiveNotification and specify a selector to be invoked when that particular notification is received.

- (void)applicationDidBecomeActive:(NSNotification *)notification
{
    // Kick off your CLLocationManager
    [self updateCurrentLocation];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
}

Finally, remember to remove yourself as an observer for this notification when the view unloads. It's good practice to balance your addObserver/removeObserver calls to NSNotificationCenter in this way.

等往事风中吹 2024-12-11 13:07:17

您可以注册您的通知视图。对于需要跟踪应用程序状态的视图,我使用这个方便的超类。

@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

You can register your view for notifications. For views that need to keep track of application state I use this handy superclass.

@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
¢蛋碎的人ぎ生 2024-12-11 13:07:17

在您的 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 会自动调用此方法。即将变得活跃。在这里您可以获得最新的位置以进行进一步处理。

In your AppDelegate.m you must have this method predefined (as in the template you created initially when starting your project in 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.
     */
}

As the description says, this method is automatically invoked by iOS when the app is about to become active. Here you could get the latest location to do further processing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文