iOS UIApplication openURL Very Slow

时间:2015-08-07 02:00:32

标签: ios objective-c freeze uiapplication openurl

I've seen this similar question: OpenUrl freezes app for over 10 seconds but it isn't dealing with my specific use case of changing a second application's install state, and none of the solutions listed there have fixed my problem, so I'm opening this question.

Short summary of the simplified situation:

We have two applications, lets call them appA and appB. In appA, we have a button that allows you to either open the app store to download appB if appB is not installed, or open appB if it is installed. Every time appA is opened / resumed, it checks if appB is installed by performing a [[UIApplication sharedApplication] canOpenURL: <<appB's URL scheme>>], if the result is true, appA's button says "Open AppB", otherwise it says "Get AppB".

When appA's button is tapped, it does the canOpenURL: check again, and either opens the App Store to appB, or opens appB via a deep link. Pretty simple stuff. Literally, the code is:

if ( [[UIApplication sharedApplication] canOpenURL:appBDeepLink] ) {

   [[UIApplication sharedApplication] openURL: appBDeepLink];

} else {

   [[UIApplication sharedApplication] openURL: appBAppStoreLink];

}

This all works as expected, however, if you change appB's installation state and go back to appA, the call to openURL freezes for 5-10 seconds on the next time it is tapped, before finally opening the URL.

For example, here are 2 scenarios to cause the freeze:

Scenario 1: Installing appB

  1. User does not have appB installed

  2. User opens appA

  3. User taps "Get AppB"

  4. User is brought to App Store and installs appB

  5. User re-opens appA (brings it to foreground, it was never closed)

  6. appA sees that appB is now installed, and changes it's button to "Open AppB"

  7. User taps "Open AppB"

8. App freezes for 5-10 seconds

  1. appA opens appB

Scenario 2: Uninstalling appB

  1. User has appB installed

  2. User opens appA

  3. User taps "Open AppB"

  4. appB is opened

  5. User closes appB

  6. User uninstalls appB

  7. User re-opens appA (brings it to foreground, it was never closed)

  8. appA sees that appB is now uninstalled, and changes it's button to "Get AppB"

  9. User taps "Get AppB"

10. App freezes for 5-10 seconds

  1. appA opens App Store

It almost seems like a given UIApplication instance doesn't update it's internal list of what apps can be opened via openURL until either the application is terminated / re-opened, or openURL is called again, and calling openURL causes the freeze as it re-configures it's internal list of what apps can be opened (I'm entirely speculating here, I don't know how this works under the hood). Regardless, the freeze is there, and I've tried numerous ways to get around it without any success, including:

  • using GCD to dispatch to the main thread

  • using GCD to dispatch to a background thread

  • performing the openURL call after a short 0.1 second delay

  • using NSThread's detachNewThreadSelector:toTarget:withObject to perform the call on a different thread

Nothing seems to work, the delay is always there until I close appB and re-open it. Searching online, there are some Stackoverflow posts that note this behavior starting in iOS 7, but their solutions (which are the solutions I've tried above) seem to be geared towards the overall delay of calling openURL from places you shouldn't be (in application:didFinishLaunchingWithOptions:, for example), and I haven't been able to find anything specifically about opening a URL after an app has been installed / uninstalled.

I am able to replicate this 100% of the time on iOS 8.4.

Has anyone else ran into this? Is there any solution?

1 个答案:

答案 0 :(得分:0)

在不推荐使用的版本中使用不推荐使用的openURL方法,我遇到了同样的问题。您应该改用open(_:options:completionHandler :)。 (对不起,语法很快)

请参阅: https://developer.apple.com/documentation/uikit/uiapplication/1622961-openurl https://developer.apple.com/documentation/uikit/uiapplication/1648685-open