Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c iOS从后台加载时重新检查位置_Objective C_Ios_Geolocation_Core Location_Cllocationmanager - Fatal编程技术网

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

Objective c iOS从后台加载时重新检查位置,objective-c,ios,geolocation,core-location,cllocationmanager,Objective C,Ios,Geolocation,Core Location,Cllocationmanager,我正在开发一个应用程序,根据您当前的位置显示结果数据 目前,我正在使用UIViewController的viewDidLoad方法启动CLLocationManager并获取当前位置。一旦我找到了与我期望的准确度相匹配的位置,我就向我的web服务发出请求,以获取结果并将其转储到UITableView 我的问题是,当你关闭应用程序时(尽管它仍在后台运行)。如果你要开车去另一个城镇,请重新打开应用程序,数据不会更新,并会继续显示来自旧位置的结果 基本上,当UIViewController从后台加载时

我正在开发一个应用程序,根据您当前的位置显示结果数据

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

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

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

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

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


除了使用
stopmoningsignificantlocationchanges
方法外,还有其他方法吗?

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

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
}
-viewDidLoad
中,我们将自己添加为
uiapplicationidbecomeactivityfication
的观察者,并指定在收到特定通知时要调用的选择器

- (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调用是一种很好的做法

在您的
AppDelegate.m
中,必须预定义此方法(如在Xcode中启动项目时最初创建的模板中所述)——


如描述所述,当应用程序即将激活时,iOS会自动调用此方法。在这里,您可以获得最新的位置进行进一步处理。

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

@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

一旦我从那里获得了更新的位置,是否有办法使我的UIViewController知道位置已更改?您可以在此处导入UIViewController.h文件并将该位置传递回,或者将位置变量设置为单例(即,将其作为应用程序委派的一部分)。其实有很多种方法…好的,谢谢。用这种方法,比马克·亚当斯建议的答案有什么优势吗。就个人而言,它似乎更容易,因为它都在UIView中管理。是的,这更干净。这就是为什么有这些方法。这正适合你的需要。你也可以按照马克的建议去做,但为什么呢?这样更干净…好吧,我只是想实现这个方法。在将值传递回UIViewController时,我有点困惑。为了能够触发更新,我需要在UIViewController上调用一个方法,并在调用时传回位置。如何从AppDelegate访问UIViewController的活动实例?感谢您的回答,工作非常顺利。这似乎比使用AppDelegate方法要好,因为它将所有内容都保存在同一个UIViewController中。谢谢,看起来很棒。我要试一试。我认为你应该在GitHub中发布这个,这样你就可以收到关于如何扩展它或将它作为一个可共享资源的评论。谢谢分享。
@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