Почему моя сцена активируется, даже если canActivateForTargetContentIdentifierPredicate равно false?

Вопрос или проблема

  let mainSceneTargetContentIdentifier = "com.apple.gallery.mainIdentifier"

var window: UIWindow?

// MARK: - UIWindowSceneDelegate

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    print("willConnectTo") //3
    
    if let userActivity = connectionOptions.userActivities.first ?? session.stateRestorationActivity {
        if !configure(window: window, with: userActivity) {
            Swift.debugPrint("Не удалось восстановить из \(userActivity)")
        }
    }
    // Свойство 'window' будет автоматически загружено с начального контроллера представления из storyboard.
    
    // Установите предикаты активации, которые работают с 'targetContentIdentifier'.
    let conditions = scene.activationConditions
    let prefsPredicate = NSPredicate(format: "self == %@", mainSceneTargetContentIdentifier)
    // Главный предикат, который сообщает системе, какой тип контента может отображать сцена.
    conditions.canActivateForTargetContentIdentifierPredicate = prefsPredicate
    // Вторичный предикат, который сообщает системе, что эта сцена особенно заинтересована в определенном типе контента.
    conditions.prefersToActivateForTargetContentIdentifierPredicate = prefsPredicate
}

это из

сессии apple WWDC 2019 212: Введение в несколько окон на iPad

Согласно моему пониманию кода, значение targetContentIdentifier равно com.apple.gallery.openDetail, а значение mainSceneTargetContentIdentifier равно com.apple.gallery.mainIdentifier, поэтому при сравнении targetContentIdentifier и mainSceneTargetContentIdentifier в NSPredicate(format: "self == %@", mainSceneTargetContentIdentifier) возвращается false, потому что, очевидно, две строки не совпадают. Тем не менее, сцена активируется несмотря ни на что. Для целей тестирования я инициализировал NSPredicated(value:false) и присвоил его условиям сцены, и сцена была активирована.

Может кто-то объяснить, почему? Согласно документации, это должно работать, если NSPredicate возвращает true, а не наоборот.

Ответ или решение

Причины, по которым ваша сцена активируется, даже когда canActivateForTargetContentIdentifierPredicate возвращает false, могут быть связаны с несколькими аспектами механизма активации сцен в iOS. Давайте разберемся в этом вопросе подробнее.

  1. Понимание activationConditions:
    Ваша сцена настроена с помощью activationConditions, которые наполняются предикатами. В данном случае вы используете предикат для проверки совпадения идентификаторов. Однако стоит отметить, что активация сцены может происходить на основе других факторов, помимо простого сравнения идентификаторов.

  2. Разные типы предикатов:
    Обратите внимание, что canActivateForTargetContentIdentifierPredicate указывает, может ли сцена активироваться для данного идентификатора контента. Однако prefersToActivateForTargetContentIdentifierPredicate указывает, что эта сцена заинтересована в активации для конкретного идентификатора. Если система считает, что у сцены сохраняется верное состояние, она может при этом игнорировать предикат canActivateForTargetContentIdentifierPredicate.

  3. Порядок проверки предикатов:
    Система может обрабатывать предикаты в определенного рода порядке и при наличии нескольких факторов, сигнализирующих о возможной активации. Например, если у вас есть пользовательская активность, которая затем может “подтолкнуть” систему к активации сцены, это может произойти, даже если canActivateForTargetContentIdentifierPredicate не соответствует условиям.

  4. Проверка на наличие пользовательской активности:
    Если в connectionOptions или состоянии восстановления сессии передается какая-либо пользовательская активность, она также может привести к активации сцены, независимо от предикатов. Если ваше приложение обрабатывает эту активность, то это может оказаться решающим фактором при активации.

  5. Код с использованием NSPredicate(value: false):
    Интересный момент в том, что, когда вы инициализируете NSPredicate(value: false) и присваиваете его canActivateForTargetContentIdentifierPredicate, и сцена все равно активируется, это может указывать на то, что существуют другие механизмы или триггеры, которые активируют сцену. Возможно, это связано с внутренними механиками iOS, где не только предикаты предопределяют активацию, но и общая логика вашего приложения.

  6. Рекомендации по отладке:

    • Убедитесь, что вы проверили все возможные источники активностей, которые могут повлиять на активацию сцены.
    • Проверьте, нет ли других мест в коде, где состояние сцены, пользовательские действия или какие-то другие условия могут изменять логику активации.
    • Используйте отладочные сообщения для отслеживания выполнения кода, чтобы понять, какие именно активности вызывают активацию сцены.

В заключение, несмотря на то, что заданная логика со стороны предикатов актуальна, активация сцен в системе может происходить из-за других факторов. Не забывайте тщательно отслеживать и проверять весь контекст, в котором происходит активация, чтобы выявить проблему.

Оцените материал
Добавить комментарий

Капча загружается...