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

React Native中iOS Wallet Extension(含IssuerUI/NonUI)实现求助

React Native 集成iOS Wallet Issuer扩展实操指引

一、先明确分工:RN与iOS扩展的边界

RN只负责主应用的业务逻辑,IssuerNonUIExtension(后台扩展)和IssuerUIExtension(界面扩展)必须用原生iOS代码实现——这俩是iOS系统级扩展,没有RN桥接支持,只能靠原生层与RN通过「App Groups」共享数据或主应用中转交互。

二、完善IssuerNonUIExtension(解决凭证获取问题)

你已经让扩展在Wallet中显示,接下来重点补全凭证处理逻辑:

  • 确保你的NonUIExtension类正确实现PKIssuerExtensionHandler协议的核心方法,比如处理凭证请求的beginRequestWithExtensionContext:和handleAddPaymentPassRequest::
    // Objective-C示例代码
    - (void)beginRequestWithExtensionContext:(PKIssuerExtensionContext *)context {
        // 通过App Groups读取RN主应用提前存入的凭证数据
        NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.yourapp.wallet"];
        NSString *credentialRawData = [sharedDefaults objectForKey:@"wallet_credential_data"];
        
        // 按照Apple文档构造PKPaymentPass对象
        PKPaymentPass *targetPass = ...;
        
        // 完成请求,把凭证返回给Wallet
        [context completeRequestWithPaymentPass:targetPass completion:nil];
    }
    
  • 开启App Groups:在Xcode的主应用、两个扩展的「Signing & Capabilities」面板添加同一个App Group(比如group.com.yourapp.wallet),用来共享RN和扩展之间的凭证、用户信息等数据。RN侧可以通过原生模块或react-native-shared-preferences这类库读写共享存储。

三、实现IssuerUIExtension

这个扩展是Wallet内的自定义交互界面,必须用iOS原生UI框架(UIKit/SwiftUI)实现:

  1. 在Xcode中给项目新增Target,选择「Wallet Issuer UI Extension」,命名比如WalletUIExtension;
  2. 扩展的主ViewController要继承PKIssuerViewController,实现协议方法处理界面逻辑:
    // Swift示例代码
    class WalletUIViewController: PKIssuerViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            // 从App Groups读取RN传递的界面配置数据
            let sharedDefaults = UserDefaults(suiteName: "group.com.yourapp.wallet")
            let credentialName = sharedDefaults?.string(forKey: "credential_name")
            
            // 构建自定义UI,比如添加显示凭证名称的标签
            let titleLabel = UILabel(frame: CGRect(x: 20, y: 50, width: view.frame.width-40, height: 30))
            titleLabel.text = credentialName
            view.addSubview(titleLabel)
        }
    
        override func didFinish(with paymentPass: PKPaymentPass?) {
            // 完成交互后,把凭证返回给Wallet
            extensionContext?.completeRequest(withPaymentPass: paymentPass, completionHandler: nil)
        }
    }
    
  3. 给这个扩展也开启相同的App Groups,保证数据互通。

四、RN与扩展的交互方式

因为扩展无法直接调用RN桥接,只能通过两种方式交互:

  • 数据共享:RN主应用提前把凭证数据、界面配置存到App Groups,扩展启动后直接读取使用;
  • 主应用中转:如果扩展需要实时请求后端数据,可通过openURL唤起主应用,RN层处理请求后把结果存到App Groups,再通知扩展读取。

五、常见坑点解决

  • 扩展无法注册:检查Xcode的Target配置,确保扩展的Bundle ID是主应用ID的后缀(比如主应用是com.yourapp,扩展是com.yourapp.walletextension),且签名配置与主应用一致(用同一个Team);
  • 凭证无法获取:确认PKIssuerExtensionHandler的实现逻辑正确,且构造的PKPaymentPass完全符合Apple的格式要求;
  • UIExtension不显示:检查Wallet的扩展授权设置,同时确认扩展Info.plist中NSExtensionPrincipalClass字段已正确指向你的ViewController类名。

内容的提问来源于stack exchange,提问作者Marian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:30:07