У нас есть приложение, которое в значительной степени полагается на возможность доступа к токену пользовательского сеанса с помощью iOS Keychain
. Когда наше приложение открывается, первое, что было проверено, - это то, доступен ли токен, а если нет, мы показываем пользователю экран входа в систему. Мы не используем для этого какую-либо стороннюю библиотеку и используем Keychain
SecItemAdd()
/SecItemCopyMatching()
напрямую со следующими параметрами:
-
kSecClassGenericPassword
-
kSecAttrAccessibleAlwaysThisDeviceOnly
Мы не видим никаких проблем с этим при нормальном использовании.
Эта проблема
У нас были пользователи, которые сообщали, что после открытия своего приложения они отображают экран входа в систему (предполагая, что Keychain
не смог найти значение), когда они действительно вошли в систему. Мы обнаружили, что в этом случае мы обнаружили, что после убийства и перезагрузка приложения, пользователи вернулись к нормальной работе (сеанс был найден в Keychain
). Как только мы это обнаружили, мы попытались добавить экспоненциальную отсрочку, чтобы продолжать запрашивать Keychain, думая, что она может быть недоступна только в течение первых нескольких секунд. Это не сработало и доказало нам, что Keychain, кажется, недоступен для всего сеанса запуска приложения. Мы не можем воспроизвести эту проблему. Кажется, это происходит очень прерывисто.
При дальнейшем расследовании мы обнаружили, что обычно пользователи получали VoIP-сигналы до возникновения этой проблемы. Мы по-прежнему не в состоянии достоверно воспроизвести эту проблему, но после отладки выяснили, что наш Keychain.session
был признан nil
при получении этих нажатий (мы также полагаемся на него), который до того, как пользователь откроет свое приложение чтобы увидеть, что они pseudo- "вышли из системы".
Мы используем PushKit и PKPushRegistry для того, чтобы сделать VoIP Push. Это требует, чтобы наше приложение включало "Фоновые режимы: голос поверх IP". Мы используем все это, как указано в документации Apple. Здесь образец:
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) {
guard let _ = Keychain.session else {
print("Session token not available")
return
}
handle(notification: payload.dictionaryPayload)
}
Этот код основывается на том, что Keychain.session
сразу доступен после получения VoIP Push. Как упоминалось ранее, мы видели случаи, когда они недоступны, и поэтому эта функция выходит из системы и просто возвращается.
Я также нашел эту важную публикацию на форуме Apple, предполагая, что это может быть ошибка iOS.
Может ли кто-нибудь помочь нам в этом вопросе? Любая помощь будет принята с благодарностью. Даже если это на самом деле ошибка iOS, мы открыты для обходных решений.