内容简介:In-App Purchase:应用内购买服务,简称IAP。是苹果为App内的虚拟商品和服务的交易定制的系统。所谓应用内购买,是指在操作虚拟商品交易的时候,不允许使用类似微信/支付宝/Apple Pay第三方支付手段,如果通过另类方式避开的话,会被下架。请参考前一篇文章 《
In-App Purchase:应用内购买服务,简称IAP。是苹果为App内的虚拟商品和服务的交易定制的系统。
所谓应用内购买,是指在操作虚拟商品交易的时候,不允许使用类似微信/支付宝/Apple Pay第三方支付手段,如果通过另类方式避开的话,会被下架。
配置内购信息
请参考前一篇文章 《 iOS打包上架最新(含内购)2019年 》
创建商品类型
消耗型:使用一次并耗尽,可以重复购买。类似于宝箱,武器皮肤
非消耗型:只需购买一次,不会过期。类似于地图,电子书
自动续期订阅:购买一次后服务或内容会自动续订,直到用户决定取消。类似于Apple music
非续期订阅:购买一次后,不会自动续订,并且可以再次购买,等同于购买一段时间的服务可以叠加。类似于会员,一定数量钻石
StoreKit
通过StoreKit框架使应用程序连接到App Store,以提示并安全地处理付款。
先遵循SKProductsRequestDelegate,SKPaymentTransactionObserver协议。
//添加支付监听 SKPaymentQueue.default().add(self) //移除监听 SKPaymentQueue.default().remove(self)复制代码
点击购买
//是否允许付款(通过权限限制购买的人群) if SKPaymentQueue.canMakePayments() { pid:这里指的是选择套餐对应的id,从苹果后台的套餐配置生成,App服务端获取 let set = NSSet(array: [pid]) //检索本地化商品信息 let request = SKProductsRequest(productIdentifiers: set as! Set<String>) request.delegate = self request.start() }else { print("禁止购买") }复制代码
恢复购买,这里的作用是持久化我们的订单信息,下次重新监听支付队列的时候会重新调用
恢复之前的购买 SKPaymentQueue.default().restoreCompletedTransactions()//非续订订阅型和消耗型无法恢复 购买历史记录的事务,添加回队列出错回调 func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) { print("错误恢复: \(error)") } 恢复购买,成功添加队列回调 func paymentQueueRestoreCompletedTransactionsFinished(_ queue:SKPaymentQueue){ }复制代码
产品要求代理<SKProductsRequestDelegate>
收到产品信息的响应 func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { } 请求失败 func request(_ request: SKRequest, didFailWithError error: Error) { } 请求完成 func requestDidFinish(_ request: SKRequest) { }复制代码
付款交易观察代理<SKPaymentTransactionObserver>
监听交易状态 func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { for tran in transactions { switch tran.transactionState { case .purchased: //交易完成,调起验证购买 //1.从沙盒获取持久化订单信息 //2.将收据上传到App服务器,成功后结束交易 //3.删除保存的订单信息 case .purchasing: //交易中 case .restored: //已经购买过 case .failed: //交易失败 break default: break } } } 交易结束 private func payFinish(transaction:SKPaymentTransaction) { }复制代码
代码
import UIKit import StoreKit // MARK: - swift title: IAP应用内购买 // MARK: - 点击购买 class UserIAPBuy: NSObject,SKProductsRequestDelegate,SKPaymentTransactionObserver { func startBuyInnerProduct(_ type: String) -> () { SKPaymentQueue.default().add(self as SKPaymentTransactionObserver) localRequest(type) } func localRequest(_ type: String) -> () { if SKPaymentQueue.canMakePayments() { let set = NSSet(array: [type]) //检索本地化商品信息 let request = SKProductsRequest(productIdentifiers: set as! Set<String>) request.delegate = self request.start() }else { print("禁止购买") } } } // MARK: - 恢复购买 extension UserIAPBuy { func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) { print("错误恢复 code: (error)") } func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) { //恢复购买获取成功回调 var array = String print("received restored transactions: (queue.transactions.count)") for pay:SKPaymentTransaction in queue.transactions { let productID = pay.payment.productIdentifier array.append(productID) print("message: (array)") } } //恢复之前购买 @objc func replyToBuy() { SKPaymentQueue.default().restoreCompletedTransactions() } } // MARK: - 代理:商品 SKProductsRequestDelegate extension UserIAPBuy { func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { // 收到App Store商品信息的响应 let pro = response.products if pro.count > 0 { var p: SKProduct? for pid in pro { print("描述信息: (pid.description)") print("产品标题: (pid.localizedTitle), 产品描述信息: (pid.localizedDescription)") print("价格: (pid.price)") p = pid } guard let pro = p else { return } SKPaymentQueue.default().add(SKPayment(product: pro)) }else { // 处理无法获得商品信息的操作 print("无法取得商品信息") } } func requestDidFinish(_ request: SKRequest) { // 处理请求完成 } func request(_ request: SKRequest, didFailWithError error: Error) { // 处理请求失败 } } // MARK: - 代理:付款交易观察 SKPaymentTransactionObserver extension UserIAPBuy { func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { //监听交易状态 for tran in transactions { switch tran.transactionState { case .purchased: //交易完成,调起验证购买 //1.从沙盒获取持久化订单信息 //2.将收据上传到App服务器,成功后结束交易 //3.删除保存的订单信息 paymentTransactionPurchased() SKPaymentQueue.default().finishTransaction(tran) case .purchasing: //交易中 paymentTransactionPurchasing() case .restored: //已经购买过 paymentTransactionRestored() SKPaymentQueue.default().finishTransaction(tran) case .failed: //交易失败 paymentTransactionFailed(tran) default: break } } } func paymentTransactionPurchased() { // 验证购买,避免越狱软件模拟苹果请求达到非法购买问题 guard let receiptUrl = Bundle.main.appStoreReceiptURL,let receiptData = try? Data(contentsOf: receiptUrl) else { // 从沙盒中获取交易凭证并且b拼接成请求提数据0 return } let receiptStr = receiptData.base64EncodedString(options: Data.Base64EncodingOptions.endLineWithLineFeed) //处理订单信息 print("订单信息: (receiptStr)") //删除保存的订单 } func paymentTransactionPurchasing() { print("交易中") } func paymentTransactionRestored() { print("已经购买过") } func paymentTransactionFailed(_ transaction: SKPaymentTransaction) { guard let err = transaction.error else { SKPaymentQueue.default().finishTransaction(transaction) return } if (err as NSError).code != SKError.paymentCancelled.rawValue { print("交易失败") }else{ print("交易取消") } } }复制代码
沙箱测试
沙箱账号是测试用途的Apple ID,由于内购涉及实际金钱交易,在测试阶段我们可以通过注册苹果的沙箱账号来完成内购付款。
电子邮箱可以自定义。
应用IAP权限打开
最后
技术总结:
1.在App Store后台配置内购买项目,需要先完成协议,税务银行项目。这部分可参考上一篇
2.配置具备In-App Purchase功能的App ID,并开启IAP权限。
3.通过StoreKit框架,在对应的地方实现并调整你的内购代码。
需要注意的地方:
1.有关于服务端验证收据,服务端也是有沙盒和正式两个环境,具体实现也有很多成熟的开源框架可用,这里也需要把应用套餐的信息给服务端配置。
2.苹果自带的内购买体验确实不是很好,由于本身服务器在美区,连接会比较慢,添加沙盒App ID的时候,介意不要在App内绑定,可以选择从设置绑定账号测试。
3.应用套餐也是需要审核的,把改填的地方填写清楚,问题不大,另外应用内套餐审核是伴随主App一起审核的,如果主App没有过,那么原先套餐审核通过的状态就会改变,在下一次重新提交主App的时候需要重置套餐的状态,否则,无法查找对应套餐信息。
纯属个人分享,希望对iOS社区能有更多贡献。
以上所述就是小编给大家介绍的《iOS内购集成》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 持续集成:数据库集成及快速构建
- ShareSDK集成及集成后遇到的一些问题【原创】
- 持续集成与持续部署宝典Part 3:创建集成环境
- 持续集成与持续部署宝典Part 2:创建持续集成流水线
- 禅道 12.3.stable 版本发布,全面集成八种单元测试框架,打通持续集成闭环
- 持续集成将死
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Discrete Mathematics and Its Applications
Kenneth H Rosen / McGraw-Hill Science/Engineering/Math / 2003-04-22 / USD 132.81
Discrete Mathematics and its Applications is a focused introduction to the primary themes in a discrete mathematics course, as introduced through extensive applications, expansive discussion, and deta......一起来看看 《Discrete Mathematics and Its Applications》 这本书的介绍吧!