是否可以在 iOS 库中恢复 iOS 状态?-- 找不到名为

Is iOS state restoration possible in iOS library? -- Could not find a storyboard named

提问人:ScottyB 提问时间:4/6/2019 更新时间:4/15/2019 访问量:255

问:

我有一个带有故事板和控制器类的库,用于实现 iOS 状态保留。

为了从主应用程序的委托启动库,我使用以下命令:

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

    self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
    [self.window makeKeyAndVisible];
    self.window.rootViewController = myLibrary.sharedInstance.firstController;

    return YES;
}

然后在我的库中,firstController 是用以下命令创建的:

- ( UIViewController * _Nullable ) firstController
{
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"libraryMain"
        bundle:[NSBundle bundleForClass:self.class]];

    return [storyboard instantiateViewControllerWithIdentifier:@"firstController"];
}

目前为止,一切都好。它启动库的视图控制器,该控制器使用库的“libraryMain”情节提要。

在主应用程序的委托中,我还添加了 shouldSaveApplicationState 和 shouldRestoreApplicationState,它们都返回 YES。

当我的应用进入后台时,iOS 会在委托中正确调用 shouldSaveApplicationState,并继续调用库控制器的 encodeRestorableStateWithCoder 方法。

但是,当它尝试还原时,iOS 会正确调用主应用委托的 shouldRestoreApplicationState 方法,但随后会立即崩溃,并出现以下异常:

Exception occurred restoring state Could not find a storyboard named 'libraryMain' in bundle ... Main App.app

因此,iOS 正在主应用程序的捆绑包中寻找库主故事板。如何让 iOS 在库的捆绑包中查看?还是无法在 iOS 库中实现状态恢复?

谢谢!

ios 状态恢复 ios 库

评论

0赞 Reinhard Männer 4/13/2019
这是您问题的解决方案吗?
0赞 ScottyB 4/13/2019
谢谢。但是,不确定如何使用它。在 shouldRestoreApplicationState 方法期间,我是否将当前捆绑包更改为我的库?这看起来很骇人听闻,如果主应用程序也有一个需要恢复的故事板,会发生什么?现在,我正在寻找 stackoverflow.com/questions/26077127/......寻找可能的解决方案。
0赞 Hitesh Surani 4/16/2019
使用 [NSBundle mainBundle] 而不是 [NSBundle bundleForClass:self.class]

答:

1赞 Dmitry Bespalov 4/15/2019 #1

如果“libraryMain”是链接到主应用的静态库,则它不包含情节提要文件,并且 iOS 在主捆绑包中缺少该文件(除非你特别提供)。

原因是静态库是编译代码的存档,资源必须单独包含。在这种情况下,您需要找到一种方法来捆绑您的资源 - 要么将“libraryMain”故事板直接包含到主应用程序中,要么创建一个“资源”捆绑包。

如果“libraryMain”是一个包含故事板文件的框架,则有一些解决方法。

有关状态保留的文档指出,iOS 会检查两个位置以恢复控制器:

  1. viewControllerWithRestorationIdentifierPath:coder:恢复类(在您的问题中为 firstController 类)。您可以在此处创建和配置第一个控制器的实例
  2. application:viewControllerWithRestorationIdentifierPath:coder:应用委托。在这里,您可以根据还原路径创建类的实例。

上面的两个选项看起来都像是解决方法,因为我没有您的项目的实际设置来重现问题。

评论

0赞 ScottyB 4/16/2019
是的,我创建了一个带有名为“libraryMain”的故事板的框架。我会尝试你的建议。#2 似乎很有希望,因为我可以返回 firstController 对象。不确定它是否会起作用,因为 iOS 似乎已经忘记了框架的捆绑包。谢谢。
0赞 ScottyB 4/16/2019
是的。对不起,有什么替代方案?
0赞 Dmitry Bespalov 4/16/2019
我在想,如果没有嵌入框架,那将是找不到故事板的原因,但事实并非如此。
0赞 ScottyB 4/16/2019
在实际阅读了 developer.apple.com/documentation/uikit/view_controllers/...的文档后,第一张图清楚地表明,整个恢复过程发生在我第一次调用框架的委托中调用 application:didFinishLaunchingWithOptions: 之前。我很确定解决方案就在那里,并希望在application:willFinishLaunchingWithOptions:中调用框架可能是我需要做的全部或至少部分。今天就试试。.
0赞 ScottyB 4/17/2019
好吧,我将 application:didFinishLaunchingWithOptions 替换为 application:willFinishLaunchingWithOptions,以便在状态恢复开始之前创建库的视图控制器。它启动了应用程序,但在恢复过程中我仍然遇到同样的“找不到故事板命名”的问题。接下来,我将研究“解决方法”。再次感谢您的帮助。