我回答我自己的问题。找到解决方案花了我一段时间,非常令人沮丧。如果您进行互联网搜索,您会找到一些部分答案,但我仍然需要一段时间来制定以下解决方案,我希望它可以增加一些清晰度。
因此,首先,您的应用程序的推荐行为如下所示(请参阅Opening Supported File Types in iOS Ref Lib):
- 不要实现
applicationDidFinishLaunching:
(参见UIApplicationDelegate的注释)。
- 实现
application:didFinishLaunchingWithOptions:
并检查URL,如果可以打开则返回YES,否则返回NO,但不要打开它。
- 实现
application:handleOpenURL:
并打开URL,成功返回YES,否则返回NO。
在 iOS 4 中,将 URL 传递给应用程序会导致以下两种行为之一:
- 如果应用程序已启动
application:didFinishLaunchingWithOptions:
,则调用它,application:handleOpenURL:
如果application:didFinishLaunchingWithOptions:
返回 YES,则调用它。
- 如果应用程序从挂起状态变为活动状态,则
application:didFinishLaunchingWithOptions:
不会被调用而是application:handleOpenURL:
被调用。
但是,在 iOS 3.2 中,它似乎application:handleOpenURL:
从未被调用过!可以在处理 URL 请求中找到有关 iOS 3.2 下行为不同的提示。在那里,您会发现application:handleOpenURL:
调用 ifapplication:didFinishLaunchingWithOptions:
未实现,但applicationDidFinishLaunching:
已实现。但application:handleOpenURL:
如果application:didFinishLaunchingWithOptions:
实现则不调用。
因此,使代码在 3.2 和 4.0 下工作的一种解决方案是:
- 在 中打开 URL
application:didFinishLaunchingWithOptions:
,然后返回 NO 以防止application:handleOpenURL:
被调用。
- 打开 中的 URL
application:handleOpenURL:
,以防您低于 4.0 并且应用程序处于暂停状态。
我在另一篇文章中找到了这个解决方案,但我很困惑,因为它与 iOS Ref Lib 文档中的建议相矛盾(即我们应该在 中返回 YES application:didFinishLaunchingWithOptions:
)。(那时我没有意识到文档自相矛盾)。
我相信当前的 iOS 4.0 行为将是未来的行为我更喜欢以下解决方案:
- 不要实施
applicationDidFinishLaunching:
。
- 实现
application:didFinishLaunchingWithOptions:
并检查URL,如果可以打开则返回YES,否则返回NO,但不要打开它。如果我们使用的是 3.2,请打开 URL。
- 实现
application:handleOpenURL:
并打开URL,成功返回YES,否则返回NO。
所以总而言之,我实现了 iOS 4 行为并将以下行添加到application:didFinishLaunchingWithOptions:
if([[[UIDevice currentDevice] systemVersion] hasPrefix:@"3.2"]) {
[self application:application handleOpenURL:url];
}
这使代码在 3.2 下工作。