Connect with us

Разработка

Реализация Shared With You в SwiftUI

Случалось ли вам терять ссылку, песню или другую рекомендацию, которую друг прислал вам в чате? Такое случается с каждым из нас, и, к счастью, именно эту проблему призвана решить функция Shared with You («Поделились с вами») на iOS.

Опубликовано

/

     
     

Случалось ли вам терять ссылку, песню или другую рекомендацию, которую друг прислал вам в чате? Такое случается с каждым из нас, и, к счастью, именно эту проблему призвана решить функция Shared with You («Поделились с вами») на iOS.

Что такое «Поделились с вами»?

Функция Shared with You позволяет пользователям легко находить контент, которым с ними поделились в Сообщениях, непосредственно в соответствующих приложениях. Например, здесь мы можем увидеть все ссылки на веб-сайты, которыми поделились со мной мои собеседники, и я могу продолжить разговор, не выходя из Safari:

Реализация Shared With You в SwiftUI

Эта функция была введена в iOS 16, но лишь немногие приложения используют ее в своих интересах. Как вы скоро увидите, ее очень легко реализовать, поэтому если в вашем приложении есть контент, которым можно поделиться, я настоятельно рекомендую добавить эту функцию в ваше приложение.

Начинаем работу

Прежде чем мы перейдем к коду, вам следует знать несколько вещей:

  • Для того чтобы ваше приложение поддерживало функцию Shared With You, оно должно поддерживать Universal Links, поскольку именно так Apple проверяет, что ссылки, которыми вы делитесь в Messages, принадлежат вашему приложению.
  • Поскольку Shared with You опирается на Messages, вам нужно будет протестировать свое приложение на физическом устройстве.
  • Фреймворк извлекает контент только из сохраненных контактов, поэтому при тестировании убедитесь, что человек, отправивший вам ссылку, сохранен в ваших контактах.

Единственный шаг по настройке — добавить возможность Shared with You в наш проект Xcode:

Реализация Shared With You в SwiftUI

Обзор реализации

В большинстве реализаций Shared with You вы увидите два компонента — полку и представление атрибуции (кто этим поделился).

Реализация Shared With You в SwiftUI

Полка

На полке в одном удобном месте хранится весь контент, которым вы поделились в «Сообщениях». Система автоматически упорядочивает эту полку, начиная с Siri Suggestions, основанных на недавних взаимодействиях с контентом, затем идут прикрепленные сообщения и, наконец, все остальное сортируется в хронологическом порядке.

Представление атрибуции

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

Насколько я знаю, наличие выделенной полки в вашей реализации не является обязательным, но Apple рекомендует ее использовать. Если вы предпочитаете, вы можете просто использовать представление атрибуции напрямую, чтобы указать общий контент в вашем приложении.

Давайте добавим поддержку Shared with You в приложение.

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

Реализация Shared With You в SwiftUI

Получение ссылок

Чтобы получить список ссылок, которыми поделился пользователь, мы создадим экземпляр SWHighlightCenter, основного класса, отвечающего за получение и управление общими ссылками.

import SharedWithYou

// Provides the application with a priority-ordered list of
// universal links which have been shared with the current user.
private let highlightCenter = SWHighlightCenter()

Далее мы воспользуемся SWHighlightCenter, чтобы получить список highlights. Они представляют собой список элементов, которыми с вами поделились, поэтому каждый раз, когда вы видите highlight, думайте, что это просто ссылка, которой поделился пользователь.

Мы сохраним highlights в свойстве @Published, которое впоследствии будем использовать для наполнения нашей полки:

import SharedWithYou

final class SharedWithYouService: NSObject, ObservableObject {

    // Each highlight represents a shared link
    @Published var highlights: [SWHighlight] = []

    // Provides the application with a priority-ordered list of universal links
    // which have been shared with the current user.
    private let highlightCenter = SWHighlightCenter()

    override init() {
        super.init()

        highlights = highlightCenter.highlights
    }
}

Затем мы реализуем функцию HighlightCenterDelegate, чтобы получать уведомления о каждом изменении в highlights:

import SharedWithYou

final class SharedWithYouService: NSObject, ObservableObject, SWHighlightCenterDelegate {

    // Each highlight represents a shared link
    @Published var highlights: [SWHighlight] = []

    // Provides the application with a priority-ordered list of universal links
    // which have been shared with the current user.
    private let highlightsCenter = SWHighlightCenter()

    override init() {
        super.init()

        highlights = highlightsCenter.highlights
        highlightsCenter.delegate = self
    }

    func highlightCenterHighlightsDidChange(_ highlightCenter: SWHighlightCenter) {
        highlights = highlightsCenter.highlights
    }
}

Не забудьте реализовать этот делегат, иначе вы не получите никакого контента.

Вот и все! Это весь код, который нам нужен для получения списка контента, которым поделились с пользователем. Теперь у нас есть обновляемый в реальном времени список ссылок, который мы можем использовать для наполнения нашей полки.

Осталось только отобразить представление атрибуции.

Можете пропустить следующий раздел и продолжить знакомство с деталями реализации ниже.

Более детальный взгляд на SWHighlight

SWHighlight содержит такие сведения, как кто поделился содержимым и ссылку на исходное сообщение, но единственные публичные свойства, к которым мы имеем доступ — это поля identifier и URL:

SW_EXTERN @interface SWHighlight : NSObject <NSSecureCoding, NSCopying>

/*!
    @abstract The unique identifier for this highlight
 */
@property (copy, readonly, nonatomic) id <NSSecureCoding, NSCopying> identifier;

/*!
    @abstract The surfaced content URL
 */
@property (copy, readonly, nonatomic) NSURL *URL;

- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
@end

К счастью, все, что нам действительно нужно, — это URL. Мы можем использовать информацию, содержащуюся в URL, чтобы определить, какие данные нам нужно получить из бэкенда.

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

Реализация Shared With You в SwiftUI

Отображение ссылок

Фреймворк Shared with You включает класс SWAttributionView для отображения представлений атрибуции, но он не имеет поддержки SwiftUI из коробки. Мы можем легко добавить поддержку, создав собственный UIViewRepresentable, передав в highlight свяданное представление атрибуции.

Для начала мы создадим экземпляр SWAttributionView и начнем его настраивать.

DisplayContext информирует систему о том, в каком окружении мы показываем представление атрибуции — мы хотим использовать .summary, если мы представляем представление в списке верхнего уровня, и .detail, если мы показываем представление на какой-либо странице с подробностями. Знание контекста, в котором пользователь сталкивается с представлением атрибуции, помогает системе ранжировать это выделение на полке.

struct SWAttributionViewRepresentable: UIViewRepresentable {
    let highlight: SWHighlight

    func makeUIView(context: Context) -> UIView {
        let attributionView = SWAttributionView()
        attributionView.horizontalAlignment = .leading

        // Change `.summary` to `.detail` if presenting in
        // a detail view.
        attributionView.displayContext = .summary
        attributionView.highlight = highlight
        attributionView.backgroundStyle = .default
        attributionView.menuTitleForHideAction = "Remove Article"

        return attributionView
    }

    func updateUIView(_ uiView: UIView, context: Context) {}
}

Этот вид действительно заблокирован, и единственное, что Apple позволяет нам настраивать здесь, это некоторые базовые свойства макета — ни цветов, ни шрифтов, ни даже высоты.

Мы рассмотрим некоторые возможности настройки в ближайшее время, а пока давайте закончим реализацию нашей полки.

Создание полки

Мы воспользуемся SharedWithYouService, который мы создали ранее, и SWHighlightCenter, чтобы получить список highlights (помните, что highlight — это просто способ, которым фреймворк представляет ссылку, которой поделились).

Мы интегрируем их все и создадим представление атрибуции и BlogPostRow для каждого, что даст нам следующее:

struct SharedWithYouShelf: View {
    @StateObject var sharedWithYouService = SharedWithYouService()

    var body: some View {
        NavigationView {
            List(sharedWithYouService.highlights, id: \.url.absoluteString) { highlight in
                VStack {
                    SWAttributionViewRepresentable(highlight: highlight)
                    BlogPostRow(blogPost: getBlogPostFrom(highlight))
                }
            }
        }
    }
}

Реализация Shared With You в SwiftUI

В документации Apple говорится, что ваша полка должна предлагать предварительный просмотр содержимого, включая миниатюру, заголовок, подзаголовок и представление атрибуции, которое, как вы видите, мы реализовали здесь для каждого highlight.

Apple хочет, чтобы отображение этих представлений атрибуции было безопасным и не раскрывало никакой информации о получателях или разговорах, поэтому Apple создает эти представления от вашего имени «вне процесса». Это означает, что представление создается отдельным процессом вне основного потока, поэтому вы можете добавить эту функцию в свое приложение, не беспокоясь о том, что она действительно повлияет на производительность вашего приложения.

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

Настройка меню

В нашей текущей реализации при длительном нажатии на SWAttributionView мы увидим дополнительное меню с некоторыми действиями по умолчанию:

  • Reply приведет к появлению соответствующего сообщения в беседе, что позволит нам ответить, не выходя из приложения.
  • Remove Article удалит эту ссылку из Shared with You.

Реализация Shared With You в SwiftUI

Несмотря на то, что функция Shared with You в целом очень закрыта, Apple предоставляет некоторые возможности настройки, которые позволяют нам добавить еще несколько опций в это меню.

Чтобы сделать это, нам нужно обновить нашу реализацию UIViewRepresentable, описанную ранее.

Сначала мы добавим ряд rfcnjvys[ UIActions, которые мы хотим добавить в это меню. Они будут зависеть от конкретного случая использования, но в случае со списком записей блога мы, возможно, захотим отобразить действия для сохранения в списке чтения, перевода статьи и добавления ее в закладки.

func makeUIView(context: Context) -> UIView {
    let attributionView = SWAttributionView()
    ... 

    // Action to save the article to a reading list
    let saveToReadingListAction = UIAction(
        title: "Save to Reading List",
        image: UIImage(systemName: "book")
    ) { _ in ... }

    // Action to translate the article
    let translateAction = UIAction(
        title: "Translate",
        image: UIImage(systemName: "globe")
    ) { _ in ... }

    // Action to bookmark the article
    let bookmarkAction = UIAction(
        title: "Bookmark",
        image: UIImage(systemName: "bookmark")
    ) { _ in ... }

Затем мы можем просто определить наше новое меню, указать заголовок и дочерние элементы для показа и назначить его свойству supplementalMenu представлению атрибуции.

func makeUIView(context: Context) -> UIView {
    let attributionView = SWAttributionView()
    ... 

    // Action to save the article to a reading list
    let saveToReadingListAction = UIAction(
        title: "Save to Reading List",
        image: UIImage(systemName: "book")
    ) { _ in ... }

    // Action to translate the article
    let translateAction = UIAction(
        title: "Translate",
        image: UIImage(systemName: "globe")
    ) { _ in ... }

    // Action to bookmark the article
    let bookmarkAction = UIAction(
        title: "Bookmark",
        image: UIImage(systemName: "bookmark")
    ) { _ in ... }

    attributionView.supplementalMenu = UIMenu(
        title: "Extras",
        children: [
            saveToReadingListAction,
            translateAction,
            bookmarkAction
        ]
    )
    return attributionView
}

Теперь у нас есть эти кастомные опции, появляющиеся каждый раз, когда мы взаимодействуем с SWAttributionView.

Реализация Shared With You в SwiftUI

Тестирование

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

  • В приложении «Настройки» перейдите в раздел «Сообщения» и убедитесь, что функция Shared with You включена на всех устройствах. Это должно быть так по умолчанию, но не лишним будет перепроверить.
  • Apple позволяет пользователям отключать автоматический шаринг как глобально, так и для отдельных приложений, поэтому убедитесь, что функция «Поделились с вами» включена и для вашего приложения.
  • Сохранение контента в Messages — отличный способ проверить, как работает эта функция, поскольку она автоматически предоставляет разрешение Shared with You. Если вы закрепили сообщение от известного контакта и не видите результатов в HighlightCenter, проблема, скорее всего, кроется в вашей реализации.

Реализация Shared With You в SwiftUI

Если вы пропустили, вот запись моего выступления на SwiftCraft в начале этого года:

Источник

Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.

Наши партнеры:

LEGALBET

Мобильные приложения для ставок на спорт
Telegram

Популярное

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: