I give an answer to my own question. Finding out the solution took me a while and was quite frustrating. If you do an internet search you find some partial answers, but it still took me a while to work out the following solution and I do hope it adds some clarity.
So first, the recommended behavior of your app appears to be the following (see Opening Supported File Types in iOS Ref Lib):
- Do not implement
applicationDidFinishLaunching:
(see the note at UIApplicationDelegate).
- Implement
application:didFinishLaunchingWithOptions:
and check the URL, return YES if you can open it, otherwise NO, but do not open it.
- Implement
application:handleOpenURL:
and open the URL, return YES if successful, otherwise NO.
In iOS 4, passing an URL to an app results in one of the following two behaviors:
- If the app is launched then
application:didFinishLaunchingWithOptions:
is called and application:handleOpenURL:
is called if and application:didFinishLaunchingWithOptions:
returned YES.
- If the app is becoming active from suspended state then
application:didFinishLaunchingWithOptions:
is not called but application:handleOpenURL:
is called.
However, in iOS 3.2 it appears as if application:handleOpenURL:
is never called! A hint that the behavior is different under iOS 3.2 can be found in Handling URL Requests. There you find that application:handleOpenURL:
is called if application:didFinishLaunchingWithOptions:
is not implemented, but applicationDidFinishLaunching:
is implemented. But application:handleOpenURL:
is not called if application:didFinishLaunchingWithOptions:
is implemented.
Hence, one solution to make the code work under 3.2 and 4.0 is:
- Open the URL in
application:didFinishLaunchingWithOptions:
, but then return NO to prevent that application:handleOpenURL:
is called.
- Open the URL in
application:handleOpenURL:
, in case you are under 4.0 and the app was in suspended state.
I found this solution in another post, but I was confused, because it contradicted the recommendation in iOS Ref Lib documentation (namely that we should return YES in application:didFinishLaunchingWithOptions:
). (At that point I did not realize that the documentation contradicts it self).
I believe that the current iOS 4.0 behavior will be the future behavior I prefer the following solution:
- Do not implement
applicationDidFinishLaunching:
.
- Implement
application:didFinishLaunchingWithOptions:
and check the URL, return YES if you can open it, otherwise NO, but do not open it. If we are on 3.2, open the URL.
- Implement
application:handleOpenURL:
and open the URL, return YES if successful, otherwise NO.
So in summary, I implement the iOS 4 behavior and added the following line to application:didFinishLaunchingWithOptions:
if([[[UIDevice currentDevice] systemVersion] hasPrefix:@"3.2"]) {
[self application:application handleOpenURL:url];
}
which make the code work under 3.2.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…