使用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:
的URLapplication:didFinishLaunchingWithOptions:
application:handleOpenURL:
但是然后返回NO来阻止该application:handleOpenURL:
被调用。 - 在
application:handleOpenURL:
打开URLapplication: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
文档:
我开始编写使用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为此付出了努力。