11

我已经实现了 UIApplicationDelegate 的

application:didFinishLaunchingWithOptions:

application:handleOpenURL:

根据规范,即

application:didFinishLaunchingWithOptions:
returns YES 

application:handleOpenURL: opens the URL. 

该代码在 iOS 4 下工作(在这两种情况下,即应用程序启动时和从挂起状态变为活动时)。但是,该代码在 iOS 3.2 下不起作用。

4

4 回答 4

33

我回答我自己的问题。找到解决方案花了我一段时间,非常令人沮丧。如果您进行互联网搜索,您会找到一些部分答案,但我仍然需要一段时间来制定以下解决方案,我希望它可以增加一些清晰度。

因此,首先,您的应用程序的推荐行为如下所示(请参阅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 下工作。

于 2010-08-31T19:59:39.347 回答
7

application:handleOpenURL:现在已弃用。

从 iOS 4.2 开始,您可以使用它来打开 URL:

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url 
        sourceApplication:(NSString *)sourceApplication annotation:(id)annotation

文档:

https://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIApplicationDelegate_Protocol/Reference/Reference.html

于 2012-03-14T20:50:12.820 回答
2

我开始编写使用 Dropbox api 的应用程序。为了理解概念,我使用我在 dropbox/developer文档中提到的密钥/秘密运行了一个示例应用程序。示例应用程序开始工作后,我为我的应用程序使用了相同的密钥/秘密值。

对于示例应用程序,handleOpenURL(或 iOS 4.2 上的 openURL)的实现按预期执行。出于某种奇怪的原因,我的应用程序并非如此。我的应用程序进入后台以显示 Dropbox 的登录屏幕和身份验证页面。成功登录和身份验证后,我的应用程序从未进入前台。平台模拟器和设备(iPad)都是如此

我几乎尝试了互联网上列出的所有内容,包括这篇文章。谢谢。但是,没有成功。

最后,当我执行以下操作时,它开始为我的应用程序工作:

  • 在模拟器上,选择“iOS Simulator --> Reset Content and Settings”,然后重置。
  • 在设备上,我删除了与示例应用程序相关的可执行文件,然后删除了与之关联的缓存。
于 2012-03-06T17:16:35.113 回答
0

将以下内容添加到末尾application:DidFinishLaunchingWithOptions

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

    ...    

    NSURL *url = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];
    if (url != nil && [url isFileURL]) {
        return YES;
    }  else return NO;
} // End of application:didFinishLaunchingWithOptions:

// New method starts 
-(BOOL) application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    mvc = [nc.viewControllers objectAtIndex:0];
    if (url != nil && [url isFileURL]) {
        [mvc handleOpenURL:url];
    }
    return YES;
}

其中 mvc 是我的主要 ViewController,而 nc 是我的导航控制器。

然后在 MainViewController 中,执行如下操作:

- (void)handleOpenURL:(NSURL *)url {
    [self.navigationController popToRootViewControllerAnimated:YES];

    // Next bit not relevant just left in as part of the example
    NSData *jsonData = [NSData dataWithContentsOfURL:url];        
    NSError *error;
    NSDictionary *dictionary = [[NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error] objectAtIndex:0];
    [self managedObjectFromStructure:dictionary withManagedObjectContext:self.context];
    ...
}

当然在.h 中声明handleOpenURL 之后。

感谢克里斯蒂安为此付出的努力。

于 2012-10-04T19:03:16.260 回答