Выполните deeplink из виджета SwiftUI одним касанием

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

Представление, которое я написал (очень простое):

HStack {
    Text("FIRST ITEM")    
    Spacer()
    Text("SECOND ITEM")
}

Я уже пробовал заменить

Text("SECOND ITEM")

с участием

Link("SECOND ITEM destination: URL(string: myDeeplinkUrl)!)

но это тоже не работает.


person Another Dude    schedule 06.10.2020    source источник


Ответы (2)


  1. В представлении Виджет вам нужно создать Link и установить его destination URL:
struct SimpleWidgetEntryView: View {
    var entry: SimpleProvider.Entry

    var body: some View {
        Link(destination: URL(string: "widget://link1")!) {
            Text("Link 1")
        }
    }
}

Обратите внимание, что Link работает только с виджетами среднего и большого. Если вы используете маленький виджет, вам необходимо использовать:

.widgetURL(URL(string: "widget://link0")!)
  1. В представлении приложения получите URL, используя onOpenURL:
@main
struct WidgetTestApp: App {
    var body: some Scene {
        WindowGroup {
            Text("Test")
                .onOpenURL { url in
                    print("Received deep link: \(url)")
                }
        }
    }
}

Также возможно получить глубокие ссылки в SceneDelegate, переопределив:

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>)

Вы можете найти более подробное объяснение того, как использовать эту функцию, в этой теме:


Вот репозиторий GitHub с различными примерами виджетов, включая виджет DeepLink.

person pawello2222    schedule 06.10.2020
comment
Как указывается ссылка на .widgetUrl? Как определить этот URL-адрес для определенного местоположения в приложении? Исправьте меня, если я ошибаюсь, но я думаю, что первая часть URL-адреса показывает схему URL-адресов, указанную в разделе информации приложения, но я не могу понять, что именно представляет собой вторая часть URL-адреса? - person Krits; 09.12.2020
comment
@Krits Каждый URL виджета будет открыт в приложении. Таким образом, scheme может быть способом отличить URL-адреса виджетов от других URL-адресов (например, из пользовательских уведомлений). Другие компоненты пути могут указывать действие / местоположение - решать вам. Вам просто нужно использовать onOpenURL(url:) в определенном представлении и проверить, пришел ли конкретный URL. - person pawello2222; 09.12.2020
comment
Итак, как упоминалось в вопросе выше, widget: // link0. Что такое link0 и link1? И как мы указываем действие и / или местоположение в этом URL-адресе? - person Krits; 09.12.2020
comment
@Krits Это просто произвольный текст, описывающий действие. В onOpenURL(url:) вы просто проверяете, какой URL пришел (если это ссылка0 или ссылка1 ...), и выполняете какое-либо действие (показываете предупреждение, активируете ссылку для навигации ...). - person pawello2222; 10.12.2020
comment
Привет, не могли бы вы указать, где именно я должен разместить onOpenUrl (url:) в моем приложении, потому что я создал свое приложение с помощью раскадровки. - person Krits; 10.12.2020

Кроме того, вы можете сделать это с помощью AppDelegate (если вы не используете SceneDelegate):

.widgetURL(URL(string: "urlsceheme://foobarmessage"))

// OR

Link(destination: URL(string: "urlsceheme://foobarmessage")!) {
    Text("Foo")
}

Установите этот код в AppDelegate

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
   let message = url.host?.removingPercentEncoding // foobarmessage
   return true
}
person Andrew    schedule 10.10.2020
comment
используя приведенный выше код, я не получаю никаких сообщений в AppDelegate о каких-либо предложениях по настройке перекрестной проверки? - person Hardik Thakkar; 21.06.2021