uni离线打包实现 ios 支付StoreKit 2,其实没有想象中那么复杂,不需要写原生插件,不需要转 uts

Uni离线打包 iOS 苹果支付(IAP)核心实现(仅支付片段)

本文专为 Uni离线打包 iOS 场景 定制,仅提取苹果支付(IAP)核心实现片段,剔除所有接口暴露、前端调用、对外交互相关内容,聚焦原生支付核心逻辑,适配Uni离线打包原生集成需求,可直接参考用于项目打包集成,保障支付流程稳定无异常。

一、核心定位(Uni离线打包专属)

以下代码为Uni离线打包iOS端苹果支付的核心原生实现,分为支付桥接处理和支付核心管理两部分,仅负责苹果支付全流程的原生逻辑执行,不涉及任何对外暴露的接口、回调给前端的相关代码,完全适配Uni离线打包的原生集成规范,避免打包后出现基座交互异常、崩溃等问题。

二、苹果支付核心代码片段

1. 支付桥接处理(IAPBridge.swift 核心片段)

核心作用:处理支付参数校验、线程调度,衔接支付核心逻辑与Uni离线打包基座,确保支付流程不阻塞基座UI,缓存支付结果,规避打包场景下的线程异常。

import Foundation

class IAPBridge: NSObject {
   
   
    private var lastResult: String = ""
    private let unitSep = "\u{001e}"
    
    // 苹果支付核心执行逻辑,衔接支付管理类
    private func runPurchase(productId: String, uuid: String) {
   
   
        print("[IAP][原生] 启动苹果支付流程,商品ID:\(productId),订单标识:\(uuid)")
        // 拼接支付参数(适配支付管理类参数格式)
        let paramBlob = productId + unitSep + uuid
        
        // 调用支付核心管理类,启动支付流程
        IAPManager.shared.setPurchaseParamBlob(paramBlob)
        IAPManager.shared.startPurchaseFlow()
        
        // 子线程等待支付结果,避免阻塞Uni离线打包基座UI(符合iOS线程规范)
        DispatchQueue.global().async {
   
   
            print("[IAP][原生] 等待苹果支付结果(最长120秒)")
            let result = IAPManager.shared.waitPurchaseResultMs(120000)
            print("[IAP][原生] 苹果支付结果返回:\(result)")
            // 缓存支付结果,供后续业务逻辑使用
            self.lastResult = result
            
            // 主线程处理结果(适配Uni离线打包基座线程要求,避免UI异常)
            DispatchQueue.main.async {
   
   
                print("[IAP][原生] 苹果支付流程结束,结果已缓存")
            }
        }
    }
    
    // 支付参数校验(苹果支付必要参数校验,避免无效支付请求)
    private func checkAndStartPurchase(productId: String, uuid: String) {
   
   
        guard !productId.isEmpty else {
   
   
            print("[IAP][原生] 苹果支付校验失败:缺少商品ID")
            return
        }
        guard !uuid.isEmpty else {
   
   
            print("[IAP][原生] 苹果支付校验失败:缺少订单唯一标识")
            return
        }
        // 参数校验通过,启动支付流程
        runPurchase(productId: productId, uuid: uuid)
    }
}

2. 支付核心管理(IAPManager.swift 核心片段)

核心作用:Uni离线打包场景下,真正与苹果StoreKit交互,实现商品查询、支付发起、交易管理、结果校验等苹果支付核心逻辑,采用无Block设计,避免与Uni打包基座交互时出现崩溃,保障支付流程稳定。

import Foundation
import StoreKit

/// 苹果支付核心管理类(适配Uni离线打包,无对外暴露接口,避免崩溃)
/// 核心流程:设置支付参数 → 启动支付流程 → 等待支付结果 → 处理交易
class IAPManager: NSObject {
   
   
    // 单例模式,确保支付流程全局唯一,避免多实例冲突(适配Uni打包基座)
    static let shared = IAPManager()
    
    private let lock = NSLock()
    private var paramBlobWork = ""
    private var sem: DispatchSemaphore? // 信号量,用于等待支付结果
    private var outcome: String = "__lxh_iap_not_started__" // 支付结果存储
    private let unitSep = "\u{001E}" // 支付参数分隔符
    
    /// 设置苹果支付参数(商品ID+订单标识),仅内部调用
    private func setPurchaseParamBlob(_ blob: String) {
   
   
        print("[IAP][原生][支付管理] 设置苹果支付参数")
        lock.lock()
        paramBlobWork = blob
        outcome = "__lxh_iap_not_started__"
        sem = DispatchSemaphore(value: 0) // 初始化信号量,准备等待支付结果
        lock.unlock()
    }
    
    /// 启动苹果支付流程(核心方法,仅内部调用)
    private func startPurchaseFlow() {
   
   
        print("[IAP][原生][支付管理] 启动苹果支付核心流程")
        let semCopy: DispatchSemaphore?
        let blobCopy: String
        // 加锁,避免多线程参数错乱(适配Uni打包多线程场景)
        lock.lock()
        semCopy = sem
        blobCopy = paramBlobWork
        lock.unlock()
        
        guard let waitSem = semCopy else {
   
   
            print("[IAP][原生][支付管理] 支付信号量初始化失败,终止支付")
            return
        }
        
        // 解析支付参数(商品ID、订单标识)
        guard let sepRange = blobCopy.range(of: unitSep) else {
   
   
            print("[IAP][原生][支付管理] 苹果支付参数格式无效")
            lock.lock()
            outcome = "error: invalid params"
            lock.unlock()
            waitSem.signal()
            return
        }
        
        let productId = String(blobCopy[..<sepRange.lowerBound])
        let uuid = String(blobCopy[sepRange.upperBound...])
        print("[IAP][原生][支付管理] 解析支付参数:商品ID=\(productId),订单标识=
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值