NSUserActivity не индексируется Spotlight

Я пытаюсь сделать так, чтобы моя NSUserActivity была проиндексирована с помощью частного индекса в Spotlight в iOS. Я выполнил все шаги, описанные в руководстве Apple по индексным операциям и навигационным точкам, но, похоже, моя активность вообще не индексируется в центре внимания.

Гид говорит, что:

Чтобы гарантировать, что действие и его метаданные будут проиндексированы, вы должны хранить строгую ссылку на действие, пока оно не будет добавлено в индекс. Есть два способа сделать это: Первый способ - назначить действие свойству в объекте контроллера, который создает действие. Второй способ - использовать свойство userActivity объекта UIResponder.

Я решил сделать первый вариант (чтобы создать свойство в моем контроллере представления для хранения NSUserActivity).

var lastSearchedUserActivity: NSUserActivity?

Идея состоит в том, что, когда пользователь что-то ищет, его последний запрос индексируется на устройстве. У меня есть следующий метод, который подготавливает активность пользователя и (предположительно) индексирует ее:

func prepareLastSearchedUserActivity(tags: [String], server: Server) {
    if Settings.applicationIndexedUserActivitiesAsShortcutTypes.contains(.LastSearched) {
        print("Get ready to index. and tags \(tags.reduce("") { "\($0) \($1)" })")
        let activity = NSUserActivity(activityType: ShortcutType.LastSearched.rawValue)

        activity.title = server.serverName
        activity.userInfo = ["tags": tags, "server name": server.serverName]

        let attributeSet = CSSearchableItemAttributeSet()
        attributeSet.contentDescription = tags.reduce("") { "\($0) \($1)" }
        attributeSet.relatedUniqueIdentifier = ShortcutType.LastSearched.rawValue

        activity.contentAttributeSet = attributeSet
        activity.keywords = Set(tags)
        activity.eligibleForSearch = true
        activity.eligibleForHandoff = false
        activity.becomeCurrent()
        self.lastSearchedUserActivity = activity
        //self.lastSearchedUserActivity?.becomeCurrent()
    }
}

Этот метод вызывается без проблем, но действие не доступно для поиска: я попытался выполнить поиск в Spotlight, используя title назначенный ему, и keywords, Деятельность никогда не обнаруживается.

Я перепробовал много решений, в том числе:

  • Переместить eligibleForSearch Позвоните сразу после создания деятельности. Руководство Apple ничего не говорит об этом напрямую, но фрагменты кода в предоставленной ссылке, кажется, подразумевают, что установка этой строки в true следует автоматически добавить активность в индекс.

  • Apple не говорит, что becomeCurrent() должен называться, а точнее, что он будет называться для вас (как? не знаю). Независимо от того, как вы можете видеть, я пытался назвать это сам. Я также попытался назвать это после присвоения его моей собственности. Нет кости. Apple говорит, что при звонке becomeCurrent() на деятельность, которая имеет eligibleForSearch как true, он будет добавлен в индекс.

  • Я даже дошел до использования контроллера представления userActivity свойство непосредственно для создания и настройки деятельности. Поскольку я использую предоставленное свойство, оно не должно быть отменено рано.

Насколько я могу судить, я делаю все, что Apple делает в своем руководстве. Я полностью потерян.

Я тестирую на iPhone 6S+, так что индексирование Spotlight доступно. Консоль также не печатает ничего, связанного с Spotlight.

Обновить:

Я просто установил делегату действия self и реализовал userActivityWillSave метод.

Согласно NSUserActivityDelegate документация, о userActivityWillSave:

Уведомляет делегата о том, что активность пользователя будет сохранена для продолжения или сохранения.

Так что этот метод делегата вызывается, но индексированный элемент нигде не найден. Вот обновленный код:

func prepareLastSearchedUserActivity(tags: [String], server: Server) {
    if Settings.applicationIndexedUserActivitiesAsShortcutTypes.contains(.LastSearched) {
        print("Get ready to index. and tags \(tags.reduce("") { "\($0) \($1)" })")
        let activity = NSUserActivity(activityType: ShortcutType.LastSearched.rawValue)

        activity.title = server.serverName
        activity.userInfo = ["tags": tags, "server name": server.serverName]
        activity.delegate = self

        let attributeSet = CSSearchableItemAttributeSet()
        attributeSet.contentDescription = tags.reduce("") { "\($0) \($1)" }
        attributeSet.relatedUniqueIdentifier = ShortcutType.LastSearched.rawValue

        activity.contentAttributeSet = attributeSet
        activity.keywords = Set(tags)
        activity.eligibleForSearch = true
        activity.eligibleForHandoff = false
        self.lastSearchedUserActivity = activity
        activity.becomeCurrent()
        //self.lastSearchedUserActivity?.becomeCurrent()
    }
}

func userActivityWillSave(userActivity: NSUserActivity) {
    print("Yep it will save")
}

1 ответ

Решение

Оказывается, установка relatedUniqueIdentifier в наборе атрибутов вызывает userInfo словарь, от которого нужно отказаться.

Я прокомментировал эту строку:

attributeSet.relatedUniqueIdentifier = ShortcutType.LastSearched.rawValue

И теперь он работает, как ожидалось. Хотя мне нужно будет найти другой способ удалить мои действия пользователя из индекса.

Обновление: дополнительная информация

Если вы должны использовать уникальный идентификатор для своей деятельности, то вам нужно сначала проиндексировать его с помощью Core Spotlight, а затем проиндексировать NSUserActivity сам. Если вы попытаетесь использовать relatedUniqueIdentifier без использования его в Spotlight, NSUserActivity не будет проиндексирован. Это была проблема в моем случае.

От relatedUniqueIdentifier документация по недвижимости в CSSearchableItemAttributeSet Ссылка на класс:

Если вы используете API-интерфейсы NSUserActivity и Core Spotlight для индексирования одного и того же элемента, задайте это свойство в действии, чтобы указать уникальный идентификатор элемента Core Spotlight, с которым связано действие, и избежать отображения дублированных результатов в Spotlight.

Если уникальный идентификатор, с которым связано действие, еще не был проиндексирован с помощью Core Spotlight, действие не будет проиндексировано.

Другие вопросы по тегам