简体   繁体   English

如何在冷启动时将iOS 7应用还原到ViewController

[英]How to restore an iOS 7 app to a ViewController on cold start

I have coded my app to return to a specific view controller upon relaunch. 我已经对我的应用进行了编码,以便在重新启动后返回到特定的视图控制器。 I want it to pull data from Core Data. 我希望它从核心数据中提取数据。 It works fine if it the app is just backgrounded. 如果该应用仅在后台运行,则效果很好。 But if the app is terminated and starts cold, it goes to the top level view controller designated in AppDelegate. 但是,如果该应用程序终止并开始变冷,它将转到AppDelegate中指定的顶级视图控制器。 I've searched StackOverflow and other forums, but have not found anything addressing this particular issue. 我搜索了StackOverflow和其他论坛,但未找到任何解决此特定问题的方法。

The app delegate has opted in. I'm using storyboards. 应用程序代表已选择加入。我正在使用情节提要。 The view controller I want to re-launch to has a restoration ID in the storyboard. 我要重新启动的视图控制器在情节提要中具有还原ID。 The view controller also has implemented encodeRestorableStateWithCoder and decodeRestorableStateWithCoder. 视图控制器还实现了encodeRestorableStateWithCoder和decodeRestorableStateWithCoder。 I've set it up as Apple recommends, but it's not working on cold start. 我已经按照Apple的建议进行了设置,但是在冷启动时不起作用。

I have 3 questions: 我有3个问题:

  1. How do I force the app to relaunch to this specific view controller (one below the top level) on a cold launch? 如何强制应用在冷启动时重新启动到该特定的视图控制器(位于顶层以下)?

  2. Once it relaunches to the target view controller on cold launch, how do I restore the core data? 在冷启动后重新启动到目标视图控制器后,如何还原核心数据? Should the core data be written to disk and restored from there? 是否应该将核心数据写入磁盘并从那里还原? Or can I just write enough info to disk (ie, key data) to go pull the data from core data? 或者我是否可以将足够的信息(例如关键数据)写入磁盘以从核心数据中提取数据?

  3. Is there a good tutorial for restoring from a cold launch? 是否有用于从冷启动中恢复的好教程? The ones I've found are only restoring transient data and not showing how to return a non-top level view controller. 我发现的只是恢复瞬态数据,而没有显示如何返回非顶级视图控制器。

Thank you in advance! 先感谢您!

Adding applicable code from AppDelegate. 从AppDelegate添加适用的代码。 If the user was on a profile details screen, I want to return them there even from a cold start. 如果用户在个人资料详细信息屏幕上,即使是冷启动我也希望将其返回。 I'm able to confirm that the profile ID is being written to disk and I'm reading it. 我能够确认配置文件ID正在写入磁盘,并且正在读取它。 I do not have "Is Initial View Controller" checked for ProfileVC on the storyboard. 我没有在情节提要板上检查ProfileVC的“是否为初始视图控制器”。 But it still returns to ProfileVC no matter what. 但是无论如何,它仍然返回到ProfileVC。

NSDictionary *settings = [self readAppState];
if ([settings objectForKey:PROFILE_ID_DICT_NAME]) {
    NSLog(@"AppDelegate: didFinishLaunchingWithOptions: PROFILE_ID_DICT_NAME = %@",
          [settings objectForKey:PROFILE_ID_DICT_NAME]);
    ProfileDetailsVC *controller = (ProfileDetailsVC *) navigationController.topViewController;
    controller.managedObjectContext = self.managedObjectContext;
} else {
    NSLog(@"AppDelegate: didFinishLaunchingWithOptions: PROFILE_ID_DICT_NAME is null");
    ProfileVC *controller = (ProfileVC *)navigationController.topViewController;
    controller.managedObjectContext = self.managedObjectContext;
}

You must assign a unique restoration identifier to all view controllers which need to be restored. 您必须为所有需要还原的视图控制器分配唯一的还原标识符。 This includes: 这包括:

  1. The ones you're really interested in 您真正感兴趣的人
  2. The root view controller 根视图控制器
  3. Any other view controller in between 之间的任何其他视图控制器

So if you have a tab bar controller for example, with a tab containing a nav controller and it has a root controller, all 3 must have restoration identifiers for the root controller to be restored. 因此,例如,如果您有一个选项卡栏控制器,而一个选项卡包含一个nav控制器,并且它具有一个根控制器,则所有3个对象都必须具有要还原的根控制器的恢复标识符。

You can do something like this: 您可以执行以下操作:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {


    self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

    //do your core data load here

    if(your core data condition){
        UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"someViewController"];
        self.window.rootViewController = viewController;
    } else {
        UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"someOtherViewController"];
        self.window.rootViewController = viewController;
    }

    [self.window makeKeyAndVisible];

    // Override point for customization after application launch.  
    return YES;
}

Careful, instantiateViewControllerWithIdentifier refers to the storyboard identifier not the class name. 小心, instantiateViewControllerWithIdentifier引用情节提要标识符而不是类名。

First of all look at this tutorial I think you can find something useful here NSCoding 首先,看一下这个教程中,我想你可以在这里找到一些有用的东西NSCoding

And about switching between view controllers. 关于在视图控制器之间切换。 Can you provide more details so we can help you with better solution. 您能否提供更多详细信息,以便我们为您提供更好的解决方案。 What is the purpose of switching from cold start? 从冷启动切换的目的是什么? Fore example if user logged in or not. 例如,用户是否登录。

UPDATE UPDATE

Given that you are having data base to store all profiles, no matter local or remote database. 假设您具有数据库来存储所有配置文件,无论是本地数据库还是远程数据库。 When user opens profile you can save profile's id (id local data base or in user defaults) and then when application have started add check in route view controller 当用户打开配置文件时,您可以保存配置文件的ID(ID本地数据库或用户默认设置),然后在应用程序启动后在路径视图控制器中添加检查

NSString *savedProfile = [[NSUserDefaults standartDefaults] valueForKey:@"savedProfile"];
if (savedProfile) {
   //retrieve needed profile
   //open view with this profile
}

For anyone that may be interested, here's how I solved this problem. 对于任何可能感兴趣的人,这就是我解决此问题的方法。

I'm going from ProfileVC --> ProfileDetailsVC under normal circumstances. 在正常情况下,我要从ProfileVC-> ProfileDetailsVC。 However, if a user was on ProfileDetailsVC when the app was killed, I want to return them to it. 但是,如果应用程序被杀死时用户正在使用ProfileDetailsVC,我想将其返回给它。 The data on both screens is populated from core data. 两个屏幕上的数据都是从核心数据填充的。

Most of the tutorials I found show how to restore specific fields on a screen that is restored, but I couldn't find one to do exactly what I was trying to do. 我发现的大多数教程都显示了如何在还原的屏幕上还原特定字段,但是我找不到一个可以完全执行我想做的事情。

Here's the pseudo code: 这是伪代码:

    ProfileVC:
       viewWillAppear:
           if (savedProfile)
               get profile ID from disk
               read core data to get profile
               set profile in ProfileDetailsVC
               performSegueWithIdentifier(ProfileDetailsVC)

    ProfileDetailsVC:
          willMoveToParentViewController:
              remove profile ID from disk
          viewDidLoad:
              save profile ID to disk

I can post actual code if anyone needs it. 如果有人需要,我可以发布实际代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM