skip to Main Content

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 URL Types setup in Xcode

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


  1. 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

    Note that you need to use a universal link for your URL representation, you can’t use a custom URL scheme. For more information about universal links, see Allowing apps and websites to link to your content.

    Login or Signup to reply.
  2. Refer to the following link to set the Target Membership of the file.

    https://forums.developer.apple.com/forums/thread/758637

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search