使用URL(通过UIApplicationDelegate的handleOpenURL)在iOS 4下工作,但不在iOS 3.2下

我已经实现了UIApplicationDelegate的

application:didFinishLaunchingWithOptions: 

 application:handleOpenURL: 

根据规范,即,

 application:didFinishLaunchingWithOptions: returns YES 

 application:handleOpenURL: opens the URL. 

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

我回答了我自己的问题。 找出解决scheme花了我一段时间,是非常沮丧。 如果你做了networkingsearch,你会发现一些不完整的答案,但是我花了一段时间才弄出下面的解决scheme,我希望它能增加一些清晰度。

因此,首先,应用程序的build议行为如下所示(请参阅在iOS Ref Lib中打开支持的文件types ):

  • 不要实现applicationDidFinishLaunching:参见UIApplicationDelegate的注释)。
  • 实现application:didFinishLaunchingWithOptions:并检查URL,如果可以打开它,则返回YES;否则,不要打开它。
  • 实现application:handleOpenURL:并打开URL,如果成功则返回YES,否则返回NO。

在iOS 4中,将URL传递给应用程序会导致以下两种行为之一:

  • 如果应用程序启动,则application:didFinishLaunchingWithOptions:被调用, application:handleOpenURL:被调用,如果和application:didFinishLaunchingWithOptions:返回YES。
  • 如果应用程序正从挂起状态变为活动状态,则application:didFinishLaunchingWithOptions:不会被调用,而application:handleOpenURL:被调用。

但是,在iOS 3.2中看起来application:handleOpenURL:永远不会被调用! 有关iOS 3.2下的行为不同的提示,请参阅处理URL请求 。 如果application:didFinishLaunchingWithOptions:未实现,但是applicationDidFinishLaunching:已实现,则会发现application:handleOpenURL:被调用。 但application:handleOpenURL:如果application:didFinishLaunchingWithOptions:不被调用。

因此,使代码在3.2和4.0下工作的一个解决scheme是:

  • 打开application:didFinishLaunchingWithOptions:的URL application:didFinishLaunchingWithOptions: application:handleOpenURL:但是然后返回NO来阻止该application:handleOpenURL:被调用。
  • application:handleOpenURL:打开URL application:handleOpenURL:如果你在4.0以下,应用程序处于挂起状态。

我在另一篇文章中发现了这个解决scheme,但是我感到困惑,因为它与iOS Ref Ref文档中的build议相矛盾(即,我们应该在application:didFinishLaunchingWithOptions:返回YES application:didFinishLaunchingWithOptions: 。 (在那个时候,我并没有意识到这个文件与它自己相矛盾)。

我相信当前的iOS 4.0行为将是未来行为,我更喜欢以下解决scheme:

  • 不要实现applicationDidFinishLaunching:
  • 实现application:didFinishLaunchingWithOptions:并检查URL,如果可以打开它,则返回YES;否则,不要打开它。 如果我们在3.2上,打开URL。
  • 实现application:handleOpenURL:并打开URL,如果成功则返回YES,否则返回NO。

所以总之,我实现了iOS 4的行为,并添加了以下行到application:didFinishLaunchingWithOptions:

    如果([[[UIDevice currentDevice] systemVersion] hasPrefix:@“3.2”]){
         [self application:application handleOpenURL:url];
     }

使代码在3.2下工作。

application:handleOpenURL:现在是DEPRECATED。

从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

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

对于示例应用程序,handleOpenURL(或iOS 4.2上的openURL)的实现按预期执行。 由于一些奇怪的原因,我的应用程序并非如此。 我的应用程序进入后台为了显示login屏幕和authentication页面的Dropbox。 成功login和authentication后,我的应用程序从未进入前台。 平台模拟器和设备(iPad)都是如此,

我尝试了几乎所有列在互联网上的东西,包括这个帖 谢谢。 虽然没有成功。

最后,我开始为我的申请工作,当我做了以下:

  • 在模拟器上,select“iOS模拟器 – >重置内容和设置”,然后重置。
  • 在设备上,我删除了示例应用程序相关的可执行文件,然后删除与之关联的caching。

将以下内容添加到application:DidFinishLaunchingWithOptions的末尾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之后。

感谢Christian为此付出了努力。