Lauching App with URL (via UIApplicationDelegate's handleOpenURL) working under iOS 4, but not under iOS 3.2

后端 未结 4 1888
终归单人心
终归单人心 2020-12-12 16:43

I have implemented UIApplicationDelegate\'s

application:didFinishLaunchingWithOptions:

and

application:handleOpenURL:
         


        
4条回答
  •  一生所求
    2020-12-12 17:11

    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.

提交回复
热议问题