У меня уже есть намерение приложения 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-адресу?
Не позволю тебе. Расширения виджетов предназначены только для SwiftUI.
Вам просто нужно сначала настроить свой 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 отредактировано для ясности: эта ошибка — моя собственная ошибка, которую я определил в своей базе кода. Я бы порекомендовал вам сделать то же самое, чтобы изящно потерпеть неудачу.
Возможно ли показать собственное представление из намерения управления виджетом?
func perform() async throws -> some ProvidesDialog & ShowsSnippetView {
.result(
dialog: "title",
view: CustomView()
)
}
импортировать UIkit? будет работать ?