You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 05:48:11