Connect with us

Разработка

Глубокие ссылки для локальных уведомлений в SwiftUI

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

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

/

     
     

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

В SwiftUI появился модификатор представления onOpenURL для работы с универсальными ссылками в наших приложениях. Вот краткий пример, показывающий, как использовать модификатор представления onOpenURL.

@main
struct MyApp: App {
    @State private var offerShown = false
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onOpenURL { url in
                    guard let host = url.host(), host == "offer" else {
                        return
                    }
                    offerShown = true
                }
                .sheet(isPresented: $offerShown) {
                    OfferView()
                }
        }
    }
}

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

Перед использованием модификатора представления onOpenURL необходимо зарегистрировать схему URL, которую вы хотите открывать в приложении. Перейдите в настройки проекта, выберите цель и зарегистрируйте схему URL в разделе «Типы URL».

Теперь вы готовы работать со ссылками в своем приложении. Вы можете попробовать проверить, как приложение работает со ссылками, открыв ссылку в Safari, например, myapp://offer.

Я хочу запланировать уведомление, которое покажет пользователю специальное предложение после первого запуска через 30 минут. Я написал расширение для UNUserNotificationCenter, чтобы сделать это проще.

extension UNUserNotificationCenter {
    func addOfferNotification() {
        let content = UNMutableNotificationContent()
        content.title = String(localized: "offerTitle")
        content.body = String(localized: "offerBody")
        content.userInfo = ["url": "myapp://offer"]
        
        let request = UNNotificationRequest(
            identifier: "offer", 
            content: content,
            trigger: UNTimeIntervalNotificationTrigger(
                timeInterval: 1800,
                repeats: false
            )
        )
        
        add(request)
    }
}

Как видно из примера выше, я создал функцию addOfferNotification, чтобы запланировать уведомление через 30 минут. Я указываю заголовок и тело уведомления и включаю поле URL в словарь userInfo.

Идея заключается в том, чтобы перехватывать уведомления с полем URL в словаре userInfo и открывать URL вместо запуска приложения. Тип UNUserNotificationCenter позволяет нам предоставить делегата для обработки момента, когда пользователь нажимает на уведомление.

Единственное место, где вы должны задать делегата для типа UNUserNotificationCenter, — это метод willFinishLaunchingWithOptions в AppDelegate. Итак, нам нужно определить AppDelegate для нашего приложения SwiftUI.

final class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        UNUserNotificationCenter.current().delegate = self
        return true
    }
}

extension AppDelegate: UNUserNotificationCenterDelegate {
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
        guard
            let urlString = response.notification.request.content.userInfo["url"] as? String,
            let url = URL(string: urlString)
        else { return }
        await UIApplication.shared.open(url)
    }
}

Как видите, мы определяем тип AppDelegate в соответствии с протоколом UIApplicationDelegate. Мы также соответствуем протоколу UNUserNotificationCenterDelegate и реализуем функцию didReceive. Наше приложение будет вызывать эту функцию всякий раз, когда пользователь коснется уведомления, пока приложение находится в фоновом режиме.

Это лучшее место для проверки того, что наше уведомление содержит URL для запуска и открытия этого адреса с помощью общего экземпляра типа UIApplication. Мы можем игнорировать другие уведомления, не содержащие поле URL.

@main
struct MyApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) private var delegate
    @AppStorage("launches") private var launches = 0
    @Environment(\.scenePhase) private var scenePhase
    @State private var offerShown = false
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onOpenURL { url in
                    guard let host = url.host(), host == "offer" else {
                        return
                    }
                    offerShown = true
                }
                .sheet(isPresented: $offerShown) {
                    OfferView()
                }
        }
        .onChange(of: scenePhase) {
            switch scenePhase {
            case .background where launches == 1:
                UNUserNotificationCenter.current().addOfferNotification()
            case .active:
                launches += 1
            default:
                break
            }
        }
    }
}

В приведенном выше примере мы используем обертку свойств UIApplicationDelegateAdaptor, чтобы определить AppDelegate для приложения SwiftUI. Мы также используем обозреватель, чтобы запланировать уведомление о предложении после первого запуска.

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

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

LEGALBET

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

Популярное

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

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