I have created an iOS 18 Control Center Widget that launches my app. However I am not able to detect it in AppDelegate.swift
. I have created custom scheme funRun://beginRun
in Target => Info => URL Types
This method in AppDelegate.swift does not fire at all and I get this error in console:
Failed to open URL runFun://beginRun: Error Domain=NSOSStatusErrorDomain Code=-10814 "(null)" UserInfo={_LSLine=279, _LSFunction=-[_LSDOpenClient openURL:fileHandle:options:completionHandler:]}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
print("Scheme (url.scheme)")
print("Host (url.host)")
return true
}
I tried this answer to no avail: iOS 18 Control Widget that opens a URL
Even adding EnvironmentValues().openURL(url)
as suggested here did not help.
@MainActor
func perform() async throws -> some IntentResult & OpensIntent {
let url = URL(string: "funRun://beginRun")!
EnvironmentValues().openURL(url)
return .result(opensIntent: OpenURLIntent(url))
}
Here is my extension code:
My goal is to detect the url string from the request, so I can decide which screen to launch from AppDelegate’s open url
method. When I test this with iOS 18 RC it does not work either in simulator or on real device
import AppIntents
import SwiftUI
import WidgetKit
@available(iOS 18.0, watchOS 11.0, macOS 15.0, visionOS 2.0, *)
struct StartRunControl: ControlWidget {
var body: some ControlWidgetConfiguration {
StaticControlConfiguration(
kind: "name.funRun.StartRun",
provider: Provider()
) { value in
ControlWidgetButton("Hello",
action: MyIntent()) { hi in
Label("Start", systemImage: "sun.min.fill")
}
}
.displayName("Start run")
.description("Opens a run screen.")
}
}
@available(iOS 18.0, watchOS 11.0, macOS 15.0, visionOS 2.0, *)
extension StartRunControl {
struct Provider: ControlValueProvider {
var previewValue: Bool {
false
}
func currentValue() async throws -> Bool {
let isRunning = true // Check if the timer is running
return isRunning
}
}
}
@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 {
let url = URL(string: "funRun://beginRun")!
EnvironmentValues().openURL(url)
return .result(opensIntent: OpenURLIntent(url))
}
}
I even checked info.plist and it seems okay.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>beginRun</string>
<key>CFBundleURLSchemes</key>
<array>
<string>funRun://beginRun</string>
</array>
</dict>
</array>
Does anyone know where the problem might be?
Thanks!
2
Answers
It’s because you’re using a custom URL scheme "funRun://beginRun". OpenURLIntent can only open universal links, not custom URL scheme links.
Refer https://developer.apple.com/documentation/appintents/openurlintent
Refer to the following link to set the Target Membership of the file.
https://forums.developer.apple.com/forums/thread/758637