Я видел похожий вопрос: OpenUrl замораживает приложение более чем на 10 секунд но это не относится к моему конкретному варианту использования изменения состояния установки второго приложения, и ни одно из перечисленных там решений не устранило мою проблему, поэтому я открываю этот вопрос.
Краткое резюме упрощенной ситуации:
У нас есть два приложения, назовем их appA и appB. В appA у нас есть кнопка, которая позволяет либо открыть магазин приложений для загрузки appB, если appB не установлено, либо открыть appB, если оно установлено. Каждый раз, когда appA открывается/возобновляется, он проверяет, установлено ли приложение B, выполняя [[UIApplication sharedApplication] canOpenURL: <<appB's URL scheme>>]
, если результат верен, кнопка appA говорит «Открыть AppB», в противном случае она говорит «Получить AppB».
Когда кнопка приложения A нажата, оно снова выполняет проверку canOpenURL:
и либо открывает App Store для приложения B, либо открывает приложение B по внешней ссылке. Довольно простые вещи. Буквально код такой:
if ( [[UIApplication sharedApplication] canOpenURL:appBDeepLink] ) {
[[UIApplication sharedApplication] openURL: appBDeepLink];
} else {
[[UIApplication sharedApplication] openURL: appBAppStoreLink];
}
Все это работает, как и ожидалось, однако, если вы измените состояние установки appB и вернетесь к appA, вызов openURL зависнет на 5-10 секунд при следующем нажатии, прежде чем, наконец, откроется URL-адрес.
Например, вот 2 сценария, вызывающих зависание:
Сценарий 1. Установка appB
У пользователя не установлено приложение appB
Пользователь открывает appA
Пользователь нажимает «Получить AppB»
Пользователь попадает в App Store и устанавливает appB
Пользователь повторно открывает appA (выводит его на передний план, он никогда не закрывался)
appA видит, что appB теперь установлено, и меняет его кнопку на «Открыть AppB».
Пользователь нажимает «Открыть AppB»
<сильный>8. Приложение зависает на 5–10 секунд
- приложение А открывает приложение Б
Сценарий 2: удаление appB
У пользователя установлено appB
Пользователь открывает appA
Пользователь нажимает «Открыть AppB»
приложение B открыто
Пользователь закрывает приложение B
Пользователь удаляет appB
Пользователь повторно открывает appA (выводит его на передний план, он никогда не закрывался)
appA видит, что приложение B теперь удалено, и меняет его кнопку на «Получить AppB».
Пользователь нажимает «Получить AppB»
<сильный>10. Приложение зависает на 5–10 секунд
- appA открывает App Store
Похоже, что данный экземпляр UIApplication
не обновляет свой внутренний список приложений, которые можно открыть через openURL, до тех пор, пока приложение не будет завершено / повторно открыто, или снова не будет вызван openURL, а вызов openURL вызывает зависание по мере его повторного запуска. настраивает свой внутренний список приложений, которые можно открыть (здесь я полностью размышляю, я не знаю, как это работает внутри). Несмотря на это, зависание существует, и я безуспешно пробовал множество способов обойти его, в том числе:
использование GCD для отправки в основной поток
использование GCD для отправки в фоновый поток
выполнение вызова openURL после короткой задержки в 0,1 секунды
использование detachNewThreadSelector:toTarget:withObject NSThread для выполнения вызова в другом потоке
Кажется, ничего не работает, задержка всегда есть, пока я не закрою приложение B и не открою его снова. При поиске в Интернете есть несколько сообщений Stackoverflow, в которых отмечается это поведение, начиная с iOS 7, но их решения (которые я пробовал выше), похоже, направлены на общую задержку вызова openURL из мест, где вы не должны быть ( в application:didFinishLaunchingWithOptions:
, например), и я не смог найти ничего конкретно об открытии URL-адреса после установки/удаления приложения.
Я могу воспроизвести это в 100% случаев на iOS 8.4.
Кто-нибудь еще столкнулся с этим? Есть ли решение?