iOS- 给App添加内购 验证购买iOS7新特性

2024-04-24 10:38

本文主要是介绍iOS- 给App添加内购 验证购买iOS7新特性,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.内购——应用内购买                      

我所说的内购——也可以说是应用内购买

大家都知道通过苹果应用程序商店有三种主要赚钱的方式:
1.直接收费(与国内大部分用户的消费习惯相悖,如果要收费,直接收高的,别收6块钱)
2.广告(降低用户体验 应用程序名称带Lite可以添加广告)
3.内购
至于设计哪些卖钱?产品经理需要认真考虑和调研的。记录用户行为是可以帮助产品经理确认哪些收费!
所以要做好游戏,一定要研究心理,要研究哲学,哈哈。

2.内购的类别有哪几种呢?                    

在游戏中我们经常用到的主要由分两种:
非消耗品(Nonconsumable)买了就有,头衔,功能
指的是在游戏中一次性购买并拥有永久访问权的物品或服务。非消耗品物品可以被用户再次下载,并且能够在用户的所有设备上使用
消耗品(Consumable),买了就用,用了就没
专为支持可消耗的物品或服务设计的,消耗品购买不可被再次下载,根据其特点,消耗品不能在用户的设备之间跨设备使用,除非自定义服务在用户的账号之间共享这些信息

3.添加内购功能                             

3.1iTunes Connect中给自己的应用添加消耗品定义                      


3.2在iTunes Connect中给自己的应用添加定义的商品              


3.3要使用内购,需要导入StoreKit框架                            

 定义好的商品

#define kIAPBomb @"airplay.10bombs"

#define kIAPBullet @"airplay.laserBullet"

1. 实例化请求时,必须指定有效的identifiers集合,之所以如此处理,主要是为了确保提交的内购商品真的通过了苹果的审批,处于可用状态!

2. 要想获取到准确的可用产品集合,需要通过代理方法实现

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response

3. 越狱用户无法测试内购,但是可以购买

@interface ITViewController () <SKProductsRequestDelegate, SKPaymentTransactionObserver>
{// 产品字典NSMutableDictionary *_productDict;
}

- (void)viewDidLoad
{[super viewDidLoad];[self requestProducts];// 设置购买队列的监听器[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}

3.4.询问苹果的服务器能够销售哪些商品                        

#pragma mark 询问苹果的服务器能够销售哪些商品
- (void)requestProducts
{// 能够销售的商品NSSet *set = [[NSSet alloc] initWithObjects:kIAPBomb, kIAPBullet, nil];// "异步"询问苹果能否销售SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];request.delegate = self;// 启动请求[request start];
}

3.5.获取询问结果,成功采取操作把商品加入可售商品字典里                   

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{if (_productDict == nil) {_productDict = [NSMutableDictionary dictionaryWithCapacity:response.products.count];}for (SKProduct *product in response.products) {// 激活了对应的销售操作按钮,相当于商店的商品上架允许销售NSLog(@"%@", product.productIdentifier);if ([product.productIdentifier isEqualToString:kIAPBullet]) {_bulletButton.enabled = YES;}if ([product.productIdentifier isEqualToString:kIAPBomb]) {_bombButton.enabled = YES;}// 填充商品字典[_productDict setObject:product forKey:product.productIdentifier];}
}

3.6.用户决定购买商品                                      

#pragma mark - 用户决定购买商品
- (void)buyProduct:(SKProduct *)product
{// 要购买产品(店员给用户开了个小票)SKPayment *payment = [SKPayment paymentWithProduct:product];//    // 设置购买队列的监听器
//    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];// 去收银台排队,准备购买(异步网络)[[SKPaymentQueue defaultQueue] addPayment:payment];
}
- (IBAction)purchaseProducts
{[self buyProduct:_productDict[kIAPBullet]];
}- (IBAction)purchaseBomb:(id)sender
{[self buyProduct:_productDict[kIAPBomb]];
}

3.7.判断购买状态是否成功                                

#pragma mark - SKPaymentTransaction Observer
#pragma mark 购买队列状态变化
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{// 调试for (SKPaymentTransaction *transaction in transactions) {NSLog(@"队列状态变化 %@", transaction);// 如果小票状态是购买完成if (SKPaymentTransactionStatePurchased == transaction.transactionState) {NSLog(@"购买完成 %@", transaction.payment.productIdentifier);// 更新界面或者数据,把用户购买得商品交给用户// ...// 验证购买凭据[self verifyPruchase];// 将交易从交易队列中删除[[SKPaymentQueue defaultQueue] finishTransaction:transaction];} else if (SKPaymentTransactionStateRestored == transaction.transactionState) {NSLog(@"恢复成功 %@", transaction.payment.productIdentifier);// 更新界面或者数据,把用户购买得商品交给用户// ...// 将交易从交易队列中删除[[SKPaymentQueue defaultQueue] finishTransaction:transaction];}}
}

3.8.给用户提供恢复功能(因为在不同设备上永久性商品可能会出现需要恢复购买的情况)    

#pragma mark - 恢复商品
- (void)restorePurchase
{// 恢复已经完成的所有交易.(仅限永久有效商品)[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}

3.9.验证购买(防止第三方插件漏洞)iOS7新特性                      

提示:虽然苹果在iOS7提升了购买凭据的安全性,但是处于金钱考虑,购买完成后,一定要做凭据的验证工作

#pragma mark 验证购买凭据
- (void)verifyPruchase
{// 验证凭据,获取到苹果返回的交易凭据// appStoreReceiptURL iOS7.0增加的,购买交易完成后,会将凭据存放在该地址NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];// 从沙盒中获取到购买凭据NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];// 发送网络POST请求,对购买凭据进行验证NSURL *url = [NSURL URLWithString:ITMS_SANDBOX_VERIFY_RECEIPT_URL];// 国内访问苹果服务器比较慢,timeoutInterval需要长一点NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];request.HTTPMethod = @"POST";// 在网络中传输数据,大多情况下是传输的字符串而不是二进制数据// 传输的是BASE64编码的字符串/**BASE64 常用的编码方案,通常用于数据传输,以及加密算法的基础算法,传输过程中能够保证数据传输的稳定性BASE64是可以编码和解码的*/NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];NSString *payload = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", encodeStr];NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];request.HTTPBody = payloadData;// 提交验证请求,并获得官方的验证JSON结果NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];// 官方验证结果为空if (result == nil) {NSLog(@"验证失败");}NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingAllowFragments error:nil];NSLog(@"%@", dict);if (dict != nil) {// 比对字典中以下信息基本上可以保证数据安全// bundle_id&application_version&product_id&transaction_idNSLog(@"验证成功");}
}

3.10.说说整个购买流程结构                                    

1.苹果APP(商家)——— 2.告诉苹果Store服务器要卖的商品 ——— 3.苹果审核完(告诉你是否可以卖)

4.用户(买商品)——— 5.苹果APP(商家)——— 6.开发票给(用户)————

7.用户(拿着发票去苹果Store服务器付款)——8.付款成功(用户在APP里获得服务商品)

 

(注意:如果要模拟测试内购,需要用真机才可以测试)


转自:http://www.cnblogs.com/qingche/p/3561424.html

这篇关于iOS- 给App添加内购 验证购买iOS7新特性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/931526

相关文章

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

Spring Security中用户名和密码的验证完整流程

《SpringSecurity中用户名和密码的验证完整流程》本文给大家介绍SpringSecurity中用户名和密码的验证完整流程,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定... 首先创建了一个UsernamePasswordAuthenticationTChina编程oken对象,这是S

JDK9到JDK21中值得掌握的29个实用特性分享

《JDK9到JDK21中值得掌握的29个实用特性分享》Java的演进节奏从JDK9开始显著加快,每半年一个新版本的发布节奏为Java带来了大量的新特性,本文整理了29个JDK9到JDK21中值得掌握的... 目录JDK 9 模块化与API增强1. 集合工厂方法:一行代码创建不可变集合2. 私有接口方法:接口

C#特性(Attributes)和反射(Reflection)详解

《C#特性(Attributes)和反射(Reflection)详解》:本文主要介绍C#特性(Attributes)和反射(Reflection),具有很好的参考价值,希望对大家有所帮助,如有错误... 目录特性特性的定义概念目的反射定义概念目的反射的主要功能包括使用反射的基本步骤特性和反射的关系总结特性

PyTorch高级特性与性能优化方式

《PyTorch高级特性与性能优化方式》:本文主要介绍PyTorch高级特性与性能优化方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、自动化机制1.自动微分机制2.动态计算图二、性能优化1.内存管理2.GPU加速3.多GPU训练三、分布式训练1.分布式数据

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

SpringBoot3.4配置校验新特性的用法详解

《SpringBoot3.4配置校验新特性的用法详解》SpringBoot3.4对配置校验支持进行了全面升级,这篇文章为大家详细介绍了一下它们的具体使用,文中的示例代码讲解详细,感兴趣的小伙伴可以参考... 目录基本用法示例定义配置类配置 application.yml注入使用嵌套对象与集合元素深度校验开发

Linux内核参数配置与验证详细指南

《Linux内核参数配置与验证详细指南》在Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要,本文主要来聊聊如何配置与验证这些Linux内核参数,希望对大家有一定的帮助... 目录1. 引言2. 内核参数的作用3. 如何设置内核参数3.1 临时设置(重启失效)3.2 永久设置(重启仍生效

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n