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),订单标识=


613

被折叠的 条评论
为什么被折叠?



