Виджет управления iOS 18, открывающий URL-адрес

У меня уже есть намерение приложения iOS 17, которое работает с URL-адресом:

@available(iOS 16, *)
struct MyAppIntent: AppIntent {
    static let title : LocalizedStringResource = "My App Inent"
    static let openAppWhenRun   : Bool = true
    
    @MainActor
    func perform() async throws -> some IntentResult{
        await UIApplication.shared.open(URL(string: "myapp://myappintent")!)
        return .result()
    }
}

Теперь, с iOS 18 и виджетами управления, я хочу создать кнопку виджета управления, которая просто открывает приложение с тем же URL-адресом. Однако код UIApplication не разрешен внутри расширений. Для этого Apple предлагает использовать OpenIntent, который показан здесь:

Ссылка на документацию

Пример кода Apple по ссылке:

import AppIntents

struct LaunchAppIntent: OpenIntent {
    static var title: LocalizedStringResource = "Launch App"
    @Parameter(title: "Target")
    var target: LaunchAppEnum
}


enum LaunchAppEnum: String, AppEnum {
    case timer
    case history


    static var typeDisplayRepresentation = TypeDisplayRepresentation("Productivity Timer's app screens")
    static var caseDisplayRepresentations = [
        LaunchAppEnum.timer : DisplayRepresentation("Timer"),
        LaunchAppEnum.history : DisplayRepresentation("History")
    ]
}

Видео сеанса WWDC, посвященное этому, не описывает подробно этот конкретный метод, а также этот пример кода немного сбивает с толку.

Итак, как я могу изменить этот код, чтобы просто открывать приложение по URL-адресу?

импортировать UIkit? будет работать ?

Shivbaba's son 07.07.2024 14:13

Не позволю тебе. Расширения виджетов предназначены только для SwiftUI.

Gizmodo 07.07.2024 15:48
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
309
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вам просто нужно сначала настроить свой ControlWidget, а затем связать свой OpenIntent.

Что-то вроде:

struct OpenAppnButton: ControlWidget {
    var body: some ControlWidgetConfiguration {
        
        StaticControlConfiguration(
            kind: "your_id"
        ) {
            ControlWidgetButton(action: LaunchAppIntent()) { // <-- HERE
                Label("Something, image: "arrow.up")
            }
        }
        .displayName("Open app")
    }
}
Ответ принят как подходящий

Я использую OpenURLIntent, и он работает отлично.

@available(iOS 18.0, watchOS 11.0, macOS 15.0, visionOS 2.0, *)
struct MyIntent: AppIntent {
    static let title: LocalizedStringResource = "My Intent"
    static var openAppWhenRun: Bool = true

    init() {}

    @MainActor
    func perform() async throws -> some IntentResult & OpensIntent {
        guard let url = URL(string: "myapp://myappintent") else {
            // throw an error of your choice here
        }

        return .result(opensIntent: OpenURLIntent(deepLink))
    }
}

На данный момент это очень близко. Я получаю сообщение «Не найдено» AppIntentsError.invalidURL

Gizmodo 17.07.2024 22:44

@Gizmodo отредактировано для ясности: эта ошибка — моя собственная ошибка, которую я определил в своей базе кода. Я бы порекомендовал вам сделать то же самое, чтобы изящно потерпеть неудачу.

podomunro 18.07.2024 02:21

Возможно ли показать собственное представление из намерения управления виджетом?

func perform() async throws -> some ProvidesDialog & ShowsSnippetView {
    .result(
        dialog: "title",
        view: CustomView()
    )
}

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