如何使用Swift扩展获取IAP内购商品的当地货币价格
SKProduct本地货币价格格式化正确使用方法
核心错误点
regularPrice是SKProduct的实例计算属性,仅能通过已拉取到完整数据的SKProduct实例调用,直接通过类调用SKProduct.regularPrice属于语法错误- 无法直接传入商品ID获取价格,必须先通过StoreKit接口向苹果服务器拉取对应商品的SKProduct实例,实例才包含
price、priceLocale等价格格式化必填字段 - 赋值语法错误:UILabel的文本内容需要赋值给
text属性,label = product.regularPrice是修改label对象本身,而非显示文本
完整实现步骤
1. 项目中添加SKProduct扩展
import StoreKit extension SKProduct { /// 返回适配本地货币规则的格式化价格字符串 var regularPrice: String? { let formatter = NumberFormatter() formatter.numberStyle = .currency formatter.locale = self.priceLocale return formatter.string(from: self.price) } }
2. 发起商品请求拉取SKProduct实例
必须先通过SKProductsRequest异步拉取商品数据,不能硬编码或直接通过ID生成实例:
import StoreKit class YourIAPManager: NSObject, SKProductsRequestDelegate { // 替换为你自己的商品ID private let targetProductID = "com.afafaf.2323" // 用于展示价格的UILabel,根据你的业务修改关联 @IBOutlet weak var priceLabel: UILabel! func loadProductPrice() { let productSet = Set([targetProductID]) let request = SKProductsRequest(productIdentifiers: productSet) request.delegate = self request.start() } // 商品请求成功回调 func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { // 筛选对应ID的商品 guard let targetProduct = response.products.first(where: { $0.productIdentifier == targetProductID }) else { DispatchQueue.main.async { self.priceLabel.text = "价格获取失败" } return } // 异步回到主线程更新UI DispatchQueue.main.async { // 正确调用扩展属性赋值给标签text self.priceLabel.text = targetProduct.regularPrice ?? "暂未查询到价格" } } }
3. 触发价格拉取
在页面加载或需要展示价格的时机调用loadProductPrice()方法即可。
注意事项
- 商品请求为异步操作,必须在请求成功回调中更新UI,发起请求后立刻读取商品数据会拿到空值
- 沙箱测试环境下价格会跟随测试Apple ID的所属地区显示,和正式App Store表现一致
- 无需手动处理货币符号、千分位/小数点规则,系统NumberFormatter会自动适配全球各地区的货币显示习惯
内容的提问来源于stack exchange,提问作者Freedlun
相关产品推荐
相关产品推荐

