zoukankan      html  css  js  c++  java
  • iOS- 给App添加内购& 验证购买iOS7新特性

    http://blog.csdn.net/tspangle/article/details/39315355

    1.内购——应用内购买                      

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

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

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

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

    3.添加内购功能                             

    3.1在iTunes 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. 越狱用户无法测试内购,但是可以购买

    1. @interface ITViewController () <SKProductsRequestDelegate, SKPaymentTransactionObserver>  
    2. {  
    3.     // 产品字典  
    4.     NSMutableDictionary *_productDict;  
    5. }  

    1. - (void)viewDidLoad  
    2. {  
    3.     [super viewDidLoad];  
    4.       
    5.     [self requestProducts];  
    6.       
    7.     // 设置购买队列的监听器  
    8.     [[SKPaymentQueue defaultQueue] addTransactionObserver:self];  
    9. }  

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

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

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

    1. - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response  
    2. {  
    3.     if (_productDict == nil) {  
    4.         _productDict = [NSMutableDictionary dictionaryWithCapacity:response.products.count];  
    5.     }  
    6.       
    7.     for (SKProduct *product in response.products) {  
    8.         // 激活了对应的销售操作按钮,相当于商店的商品上架允许销售  
    9.         NSLog(@"%@", product.productIdentifier);  
    10.           
    11.         if ([product.productIdentifier isEqualToString:kIAPBullet]) {  
    12.             _bulletButton.enabled = YES;  
    13.         }  
    14.           
    15.         if ([product.productIdentifier isEqualToString:kIAPBomb]) {  
    16.             _bombButton.enabled = YES;  
    17.         }  
    18.           
    19.         // 填充商品字典  
    20.         [_productDict setObject:product forKey:product.productIdentifier];  
    21.     }  
    22. }  

    3.6.用户决定购买商品                                      

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

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

    1. #pragma mark - SKPaymentTransaction Observer  
    2. #pragma mark 购买队列状态变化  
    3. - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions  
    4. {  
    5.     // 调试  
    6.     for (SKPaymentTransaction *transaction in transactions) {  
    7.         NSLog(@"队列状态变化 %@", transaction);  
    8.         // 如果小票状态是购买完成  
    9.         if (SKPaymentTransactionStatePurchased == transaction.transactionState) {  
    10.             NSLog(@"购买完成 %@", transaction.payment.productIdentifier);  
    11.               
    12.             // 更新界面或者数据,把用户购买得商品交给用户  
    13.             // ...  
    14.             // 验证购买凭据  
    15.             [self verifyPruchase];  
    16.               
    17.             // 将交易从交易队列中删除  
    18.             [[SKPaymentQueue defaultQueue] finishTransaction:transaction];  
    19.         } else if (SKPaymentTransactionStateRestored == transaction.transactionState) {  
    20.             NSLog(@"恢复成功 %@", transaction.payment.productIdentifier);  
    21.   
    22.             // 更新界面或者数据,把用户购买得商品交给用户  
    23.             // ...  
    24.   
    25.             // 将交易从交易队列中删除  
    26.             [[SKPaymentQueue defaultQueue] finishTransaction:transaction];  
    27.         }  
    28.     }  
    29. }  

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

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

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

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

    1. #pragma mark 验证购买凭据  
    2. - (void)verifyPruchase  
    3. {  
    4.     // 验证凭据,获取到苹果返回的交易凭据  
    5.     // appStoreReceiptURL iOS7.0增加的,购买交易完成后,会将凭据存放在该地址  
    6.     NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];  
    7.     // 从沙盒中获取到购买凭据  
    8.     NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];  
    9.       
    10.     // 发送网络POST请求,对购买凭据进行验证  
    11.     NSURL *url = [NSURL URLWithString:ITMS_SANDBOX_VERIFY_RECEIPT_URL];  
    12.     // 国内访问苹果服务器比较慢,timeoutInterval需要长一点  
    13.     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];  
    14.       
    15.     request.HTTPMethod = @"POST";  
    16.       
    17.     // 在网络中传输数据,大多情况下是传输的字符串而不是二进制数据  
    18.     // 传输的是BASE64编码的字符串  
    19.     /** 
    20.      BASE64 常用的编码方案,通常用于数据传输,以及加密算法的基础算法,传输过程中能够保证数据传输的稳定性 
    21.      BASE64是可以编码和解码的 
    22.      */  
    23.     NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];  
    24.       
    25.     NSString *payload = [NSString stringWithFormat:@"{"receipt-data" : "%@"}", encodeStr];  
    26.     NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];  
    27.   
    28.     request.HTTPBody = payloadData;  
    29.       
    30.     // 提交验证请求,并获得官方的验证JSON结果  
    31.     NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];  
    32.   
    33.     // 官方验证结果为空  
    34.     if (result == nil) {  
    35.         NSLog(@"验证失败");  
    36.     }  
    37.       
    38.     NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingAllowFragments error:nil];  
    39.       
    40.     NSLog(@"%@", dict);  
    41.       
    42.     if (dict != nil) {  
    43.         // 比对字典中以下信息基本上可以保证数据安全  
    44.         // bundle_id&application_version&product_id&transaction_id  
    45.         NSLog(@"验证成功");  
    46.     }  
    47. }  

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

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

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

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

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


    转自:http://www.cnblogs.com/qingche/p/3561424.html
  • 相关阅读:
    进制
    流程控制
    运算符
    格式化输出
    数据结构-树的遍历
    A1004 Counting Leaves (30分)
    A1106 Lowest Price in Supply Chain (25分)
    A1094 The Largest Generation (25分)
    A1090 Highest Price in Supply Chain (25分)
    A1079 Total Sales of Supply Chain (25分)
  • 原文地址:https://www.cnblogs.com/itlover2013/p/4810603.html
Copyright © 2011-2022 走看看