如何在Xcode的Swift插件中判断App是否从Widget启动?
判断Ionic App从Widget还是常规图标启动的Swift实现
要区分App是从Widget启动还是常规图标启动,核心是利用**Widget跳转App时会携带特定标识(如自定义URL Scheme)**的特性,结合Capacitor插件的上下文信息来判断,以下是两种可行方案:
方案一:全局标记法(兼容iOS全版本)
1. 在AppDelegate/SceneDelegate中记录启动来源
首先在AppDelegate中添加静态变量存储启动状态,并处理Widget跳转的URL:
import UIKit import Capacitor @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { // 全局标记:是否从Widget启动 static var isLaunchedFromWidget = false // 处理iOS 12及以下的URL跳转 func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { // 匹配Widget约定的URL Scheme(示例:myapp://widget) if url.scheme == "myapp" && url.host == "widget" { AppDelegate.isLaunchedFromWidget = true } return ApplicationDelegateProxy.shared.application(app, open: url, options: options) } // 处理iOS 13+的Scene场景启动 func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { // 检查启动上下文的URL if let urlContext = options.urlContexts.first, urlContext.url.scheme == "myapp" && urlContext.url.host == "widget" { AppDelegate.isLaunchedFromWidget = true } return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) } }
2. 在Capacitor插件中读取标记
修改你的Plugin.swift,直接读取全局标记判断启动来源:
import Foundation import Capacitor @objc(MyService) public class MyService: CAPPlugin { @objc func routeProfile(_ call: CAPPluginCall) { let isFromWidget = AppDelegate.isLaunchedFromWidget if isFromWidget { print("App从Widget启动") call.resolve(["launchedFrom": "widget"]) // 可选:如果需要重置标记(避免后台唤醒时误判) // AppDelegate.isLaunchedFromWidget = false } else { print("App从常规图标启动") call.resolve(["launchedFrom": "normal"]) } } }
方案二:直接读取Capacitor启动URL(更简洁)
Capacitor的bridge对象提供了launchUrl属性,可以直接获取App启动时的URL,无需全局变量:
import Foundation import Capacitor @objc(MyService) public class MyService: CAPPlugin { @objc func routeProfile(_ call: CAPPluginCall) { // 检查启动URL是否匹配Widget约定的Scheme if let launchUrl = bridge?.launchUrl, launchUrl.scheme == "myapp" && launchUrl.host == "widget" { print("App从Widget启动") call.resolve(["launchedFrom": "widget"]) } else { print("App从常规图标启动") call.resolve(["launchedFrom": "normal"]) } } }
关键注意事项
- Widget跳转配置:确保Widget中跳转App时使用约定好的URL Scheme,示例代码如下(Widget的Swift文件中):
if let url = URL(string: "myapp://widget") { extensionContext?.open(url) } - 后台唤醒处理:如果App从后台被Widget唤醒,需要在
SceneDelegate的scene(_:willConnectTo:options:)或scene(_:openURLContexts:)方法中重新更新启动标记,避免状态残留。
内容的提问来源于stack exchange,提问作者Mikber
相关产品推荐
相关产品推荐

