如何获取iOS键盘当前所在公开App的Bundle ID或URL Scheme?
获取iOS键盘宿主公开App标识并实现返回逻辑
一、获取宿主App的Bundle ID/URL Scheme
iOS键盘扩展无法直接获取宿主App的信息,可通过以下间接方式实现:
- 预存公开App的已知标识:Notes、Mail、Messages、WhatsApp这类公开App的Bundle ID和URL Scheme都是公开可查的,提前存入本地列表即可:
- Notes:Bundle ID
com.apple.mobilenotes,URL Schemenotes:// - Mail:Bundle ID
com.apple.mobilemail,URL Schememailto:// - Messages:Bundle ID
com.apple.MobileSMS,URL Schemesms:// - WhatsApp:Bundle ID
net.whatsapp.WhatsApp,URL Schemewhatsapp://
- Notes:Bundle ID
- 键盘上下文辅助匹配:如果遇到预存列表外的公开App,可借助
textDocumentProxy的documentContextBeforeInput等属性,结合公开的App标识库做补充匹配,但这种方法可靠性低于预存,仅作为备选方案。
二、实现启动自有App后返回原App的逻辑
- 跳转自有App时携带宿主Scheme参数:触发跳转动作时,将识别到的宿主App URL Scheme作为参数传递给自有App,通过自定义Scheme启动:
// 示例:假设自有App的Scheme为myapp://,传递returnScheme参数 let targetScheme = "notes://" // 替换为实际匹配到的宿主Scheme guard let url = URL(string: "myapp://?returnScheme=\(targetScheme)") else { return } extensionContext?.open(url, completionHandler: nil) - 自有App完成操作后返回原App:在自有App处理完业务逻辑后,解析传递的
returnScheme参数,构造URL并打开即可返回原宿主App:// 示例:在自有App中解析参数并执行跳转 guard let components = URLComponents(url: incomingUrl, resolvingAgainstBaseURL: false), let returnScheme = components.queryItems?.first(where: { $0.name == "returnScheme" })?.value, let returnUrl = URL(string: returnScheme) else { return } UIApplication.shared.open(returnUrl, options: [:], completionHandler: nil)
三、关键配置与注意事项
- 配置Scheme白名单:在自有App的
Info.plist中必须添加LSApplicationQueriesSchemes数组,将所有需要跳转的公开App Scheme纳入其中,否则会出现跳转失败:<key>LSApplicationQueriesSchemes</key> <array> <string>notes</string> <string>mailto</string> <string>sms</string> <string>whatsapp</string> </array> - 私有App逻辑隔离:私有App无法提前获取其URL Scheme,保持你已实现的弹窗动画方案即可,与公开App的逻辑分开处理,这和WisprFlow、Willow、Typeless的实现思路一致。
内容的提问来源于stack exchange,提问作者Hassan Nauman
相关产品推荐
相关产品推荐

