Xcode14.3.1编译报错:Product.SubscriptionInfo.RenewalInfo无renewalDate成员
问题
因为iOS16.5不支持Xcode14,我用Xcode15 Beta2开发了应用。现在要提交App Store,必须改用Xcode14.3.1(Beta版没法上传),但在Xcode14里编译时碰到了StoreKit的错误:Value of type 'Product.SubscriptionInfo.RenewalInfo' has no member 'renewalDate'
我查文档知道renewalDate属性支持iOS15+(项目目标版本是iOS16+),现在得解决这个错误才能获取StoreKit的续订信息,相关代码如下:
func mapped(from product: Product, renewal: Product.SubscriptionInfo.RenewalInfo?) { id = product.id level = setLevel(for: product.id) if let renewalInfo = renewal { renewalDate = renewalInfo.renewalDate // 错误提示这个属性不存在 billingRetry = renewalInfo.isInBillingRetry } else { Task { guard let transaction = await product.latestTransaction else { return } renewalDate = transaction.signedDate } } }
解决方案
问题出在Xcode14的SDK里根本没有Product.SubscriptionInfo.RenewalInfo.renewalDate这个属性——它是Xcode15 SDK才新增的,哪怕你的系统版本iOS16+支持,但SDK版本不匹配就识别不了。这里给你两种解决办法:
办法一:用条件编译适配不同Xcode版本
通过Swift的条件编译指令,区分Xcode版本来写不同逻辑,同时兼容Xcode14和Xcode15:
func mapped(from product: Product, renewal: Product.SubscriptionInfo.RenewalInfo?) { id = product.id level = setLevel(for: product.id) if let renewalInfo = renewal { if #available(iOS 16.0, *) { #if compiler(>=5.9) // Xcode15及以上(对应Swift 5.9+)用新属性 renewalDate = renewalInfo.renewalDate #else // Xcode14及以下用旧属性currentProductPeriodEndDate renewalDate = renewalInfo.currentProductPeriodEndDate #endif } billingRetry = renewalInfo.isInBillingRetry } else { Task { guard let transaction = await product.latestTransaction else { return } renewalDate = transaction.signedDate } } }
办法二:直接用Xcode14支持的旧属性
因为你的项目目标版本是iOS16+,而currentProductPeriodEndDate在iOS15+就已经支持,直接替换成这个属性完全能满足需求,代码还更简洁:
func mapped(from product: Product, renewal: Product.SubscriptionInfo.RenewalInfo?) { id = product.id level = setLevel(for: product.id) if let renewalInfo = renewal { renewalDate = renewalInfo.currentProductPeriodEndDate // 换成Xcode14支持的属性 billingRetry = renewalInfo.isInBillingRetry } else { Task { guard let transaction = await product.latestTransaction else { return } renewalDate = transaction.signedDate } } }
要说明的是,currentProductPeriodEndDate和renewalDate功能上是完全一样的,苹果只是在Xcode15里给它改了个名字,所以替换后不会影响业务逻辑。
内容的提问来源于stack exchange,提问作者832049823
相关产品推荐
相关产品推荐

