简体   繁体   English

通过Widget Tap打开URL Scheme(iOS 16 Widget Kit)

[英]Open URL Scheme through Widget Tap (iOS 16 Widget Kit)

Here is the code I currently have however, it does not seem to be working.这是我目前拥有的代码,但它似乎不起作用。 This example says I want to open the calc app.这个例子说我想打开 calc 应用程序。 My goal is to open an app once a widget is clicked.我的目标是在单击小部件后打开一个应用程序。

@main App Code: @main 应用代码:

var body: some Scene {
    WindowGroup {
        ContentView()
            .onOpenURL { url in
                print("Received deep link: \(url)")
            }
    }
}

Widget Code:小部件代码:

Gauge(value: 50), in: 0.0...100.0) {
            } currentValueLabel: {
                Text(Open App)
            }
            .gaugeStyle(.accessoryCircularCapacity)
            .widgetURL(URL(string: "calc://")!)

Then you need to do this in a 2 step process.然后,您需要分两步执行此操作。 First, you need to set up your app to receive custom URLs from your widget.首先,您需要设置您的应用程序以接收来自您的小部件的自定义 URL。 This is shockingly well explained by Apple here . Apple 在这里很好地解释了这一点。 Once you have your app's custom url scheme set up, it is time to set up your widget.设置应用程序的自定义 url 方案后,就该设置小部件了。 Essentially what you are going to do is send a URL with a query that is the URL you want to open.本质上,您要做的是发送一个 URL 查询,该查询是您要打开的 URL。 Back in your app, you receive that URL, parse it out, and then call openUrl() with the URL you want to open, and that app will open.回到您的应用程序,您收到 URL,将其解析出来,然后使用您要打开的 URL 调用openUrl() ,然后该应用程序将打开。

Your code above is close.您上面的代码很接近。 Following Apple's example above, try this:按照上面苹果的例子,试试这个:

In your widget create a deep link URL:在您的小部件中创建一个深层链接 URL:

func createDeeplinkForCalc() -> URL {
    var components = URLComponents()
    components.scheme = "myphotoapp"
    components.host = "com.example.myphotoapp"
    components.path = "/calc"
    components.queryItems = [
        URLQueryItem(name: "open", value: "calc://")
    ]
    
    return components.url!
}

Then, in .widgetURL , pass this: .widgetURL(createDeeplinkForCalc())然后,在.widgetURL中,传递这个: .widgetURL(createDeeplinkForCalc())

In your main app:在您的主应用程序中:

var body: some Scene {
    WindowGroup {
        ContentView()
            .onOpenURL { url in
                handleURL(url: URL)
            }
    }
}

func handleURL(_ url:URL) {
    // This makes sure you got the correct URL
     guard url.scheme == "myphotoapp",
         url.host == "com.example.myphotoapp"
     else { return }
        
     let query = parseQuery(url: url)

     guard let urlString = query["open"],
           !urlString.isEmpty else { return } // make sure something exists in the value

     if let calcURL = URL(string: urlString) {
         openURL(calcURL) // this calls "calc://" and opens the calculator
    }

    private func parseQuery(url: URL) -> Query {
         guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
               let queryItems = components.queryItems
         else { return ["":""] }
        
          return queryItems.reduce(into: Query()) { (result, item) in
            result[item.name] = item.value
        }
    }
}

The above has not been tested, but should work.以上尚未经过测试,但应该可以工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM