在自定义 iOS 键盘中检测应用程序

问题描述 投票:0回答:3

如何检测我的自定义键盘在哪个应用程序中使用并显示不同的按钮? 例如。在 Twitter 中,我会将 @ 添加到我发布到输入字段的字符串中,在 Reddit /r/

ios objective-c cocoa-touch keyboard ios-extensions
3个回答
10
投票

可以通过以下代码实现。因为您将获得使用自定义键盘的应用程序的捆绑标识符。

斯威夫特

    let hostBundleID = self.parentViewController!.valueForKey("_hostBundleID")
    let currentHostBundleID = String(hostBundleID)
    print(currentHostBundleID);

从捆绑包标识符中,您可以轻松找到应用程序名称。


3
投票

编辑:见上文。事情已经改变了。

这是不可能的。 扩展运行沙盒,并且仅从 API 获取信息,无法访问其他任何内容。键盘只能接收文本上下文更改并激活/停用呼叫。能够检测到位于扩展沙箱之外的应用程序,因此是不可能的。


0
投票

这是也支持 iOS 16 和 17 的更新解决方案:

extension KeyboardViewController {
    var hostBundleId: String? {
        if let id = hostBundleIdValueBefore16 { return id }
        return hostBundleIdValueFor16
    }
    
    private var hostBundleIdValueBefore16: String? {
        let value = parent?.value(forKey: "_hostBundleID") as? String
        return value != "<null>" ? value: nil
    }
    
    private var hostBundleIdValueFor16: String? {
        guard let pid = parent?.value(forKey: "_hostPID") else { return nil }
        let selector = NSSelectorFromString("defaultService")
        guard let anyClass: AnyObject = NSClassFromString("PKService"),
           let pkService = anyClass as? NSObjectProtocol,
           pkService.responds(to: selector),
           let serverInis = pkService.perform(selector).takeUnretainedValue() as? NSObjectProtocol
        else { return nil }
        let lities = serverInis.perform(NSSelectorFromString("personalities")).takeUnretainedValue()
        let bundleId = Bundle.main.bundleIdentifier ?? ""
        guard let infos = lities.object(forKey: bundleId) as? AnyObject,
           let info = infos.object(forKey: pid) as? AnyObject,
           let con = info.perform(NSSelectorFromString("connection")).takeUnretainedValue() as? NSObjectProtocol
        else { return nil }
        let xpcCon = con.perform(NSSelectorFromString("_xpcConnection")).takeUnretainedValue()
        let handle = dlopen("/usr/lib/libc.dylib", RTLD_NOW)
        let sym = dlsym(handle, "xpc_connection_copy_bundle_id")
        typealias xpcFunc = @convention(c) (AnyObject) -> UnsafePointer<CChar>
        let cFunc = unsafeBitCast(sym, to: xpcFunc.self)
        let response = cFunc(xpcCon)
        let hostBundleId = NSString(utf8String: response)
        return hostBundleId as String?
    }
}

请注意,您可能会因使用此代码而被 Apple 拒绝。不过,有些应用程序成功通过了 Apple 审核。

来源:键盘套件

用途:

print(hostBundleId)
// Output in Apple Notes: com.apple.mobilenotes

确保您位于 KeyboardController 类中。

© www.soinside.com 2019 - 2024. All rights reserved.