IOS客户端内购(IAP)简单总结

来源:互联网 发布:金十数据原油点评 编辑:程序博客网 时间:2024/05/17 04:48
本文由 http://blog.csdn.net/dalehui/ 原创
需要注意的几点: 
1.导入StoreKit框架 
2.确保product ID惟一且与IITUNNES CONNECT中的一致
3.请确保plist文件中的Bundle identifier与ITunes Connet中的Bundle ID一致
4.虚拟机好像跑不起来
5.iTunes Connect 中product ID 的分配上限为10W个
6.内购不分区域,可以在任何地方购买,即使应用在不分区域没上架
7.越狱设备可能无法使用(我的机子就没通过,囧)
8.沙盒测试的话,请使用iTunes Connect Test User的账号

下面是个流程图



以下涉及到的分别有
(1)框架
       <StoreKit/StoreKit.h>
(2)1个类和3个Delegate
         Class:SKProductsRequest
      Delegate:<SKPaymentTransactionObserver,SKProductsRequestDelegate,SKRequestDelegate]]]]>

下面上几段核心代码

.h中
[cpp] view plaincopy
  1. #import <StoreKit/StoreKit.h>  
  2. @interface IAPUnity : NSObject<SKPaymentTransactionObserver,SKProductsRequestDelegate,SKRequestDelegate>  
  3.   
  4. @property(retain,nonatomic)NSArray* products;       //产品列表  
  5. @property(retain,nonatomic)NSSet* productIdf;       //产品标记符  
  6. @property(retain,nonatomic)SKProductsRequest* request;  //用于请求相关信息  
  7.   
  8. ///获取商店信息  
  9. -(void)requestStart;  
  10.   
  11. ///初始化  
  12. - (id)initProductIdf:(NSSet*)productIdf;  
  13.   
  14. ///购买  
  15. -(void)buyProduct;  
  16.   
  17. ///恢复交易  
  18. -(void)restorer;  
  19.   
  20. @end  



.m
[cpp] view plaincopy
  1. #import "IAPUnity.h"  
  2.   
  3. @interface IAPUnity ()  
  4.   
  5. @property(retain,nonatomic)SKProduct* product;  
  6.   
  7. @end  
  8.   
  9.   
  10. @implementation IAPUnity  
  11.   
  12. - (id)initProductIdf:(NSSet*)productIdf  
  13. {  
  14.     self = [super init];  
  15.     if (self) {  
  16.         self.productIdf=productIdf;  
  17.         [self getProducts];  
  18.     }  
  19.     return self;  
  20. }  
  21. -(void)getProducts  
  22. {  
  23.     _request=[[SKProductsRequest alloc]initWithProductIdentifiers:_productIdf];  
  24. }  
  25. -(void)requestStart  
  26. {  
  27.     [_request setDelegate:self];  
  28.     ///请求数据  
  29.     [_request start];  
  30. }  
  31.   
  32. #pragma SKProductsRequestDelegate   
  33. - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response  
  34. {  
  35.     ///判断用户是否禁用内购功能  
  36.     if ([SKPaymentQueue canMakePayments]) {  
  37.         NSLog(@"%@",response.products);  
  38.         //得到产品列表  
  39.         self.products=response.products;  
  40.       
  41.     }  
  42.       
  43.     ///获取成功列表成功,并且取到第0个的相关信息  
  44.     if ([response.products count]>0) {  
  45.         self.product=[response.products objectAtIndex:0];  
  46.         NSLog(@"产品本地标题:%@",[self.product localizedTitle]);  
  47.         NSLog(@"产品描述:%@",self.product.localizedDescription);  
  48.         NSLog(@"产品价格:%@",self.product.price);  
  49.         NSLog(@"产品标识:%@",self.product.productIdentifier);  
  50.     }  
  51.       
  52.       
  53.     ///发生错误的时候输出错误信息  
  54.     for (NSString *invalidProductId in response.invalidProductIdentifiers)  
  55.     {  
  56.         NSLog(@"Invalid product id: %@" , invalidProductId);  
  57.     }  
  58. }  
  59. -(void)buyProduct  
  60. {  
  61.     if (self.product) {  
  62.           
  63.         if ([SKPaymentQueue canMakePayments]) {  
  64.             SKPayment* payment=[SKPayment paymentWithProduct:self.product];  
  65.             ///为支付队列增加一个观察者  
  66.             [[SKPaymentQueue defaultQueue]addTransactionObserver:self];  
  67.             ///增加了一个观察者到付款队列中  
  68.             [[SKPaymentQueue defaultQueue]addPayment:payment];  
  69.         }  
  70.     }  
  71. }  
  72.   
  73. -(void)restorer  
  74. {  
  75.       
  76.     [[SKPaymentQueue defaultQueue]restoreCompletedTransactions];  
  77. }  
  78.   
  79.   
  80. // Sent when the transaction array has changed (additions or state changes).  Client should check state of transactions and finish as appropriate.  
  81. - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions  
  82. {  
  83.     for (SKPaymentTransaction* transaction in transactions) {  
  84.         switch (transaction.transactionState) {  
  85.             case SKPaymentTransactionStatePurchasing:  
  86.             {  
  87.                 NSLog(@"购买中");  
  88.             }  
  89.                 break;  
  90.             case SKPaymentTransactionStatePurchased:  
  91.             {  
  92.                 NSLog(@"SKPaymentTransactionStatePurchased");  
  93.                 NSLog(@"%@",[[NSString alloc]initWithData:transaction.transactionReceipt encoding:NSUTF8StringEncoding]);  
  94.                 NSString* temp=[[NSString alloc]initWithData:transaction.transactionReceipt encoding:NSUTF8StringEncoding];  
  95.                 UIAlertView* alertView=[[UIAlertView alloc]initWithTitle:@"提示" message:@"内购成功" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];  
  96.                 [alertView show];  
  97.                 NSLog(@"BASE64:%@",[self encode:temp.UTF8String length:temp.length]);  
  98.                 [[SKPaymentQueue defaultQueue]finishTransaction:transaction];  
  99.             }  
  100.                 break;  
  101.             case SKPaymentTransactionStateFailed:  
  102.             {  
  103.                 if (transaction.error.code!=SKErrorPaymentCancelled) {  
  104.                     NSLog(@"Failed....%d",transaction.error.code);  
  105.                     NSLog(@"%@",transaction.error.localizedDescription);  
  106.                 }  
  107.                 [[SKPaymentQueue defaultQueue]finishTransaction:transaction];  
  108.               
  109.             }  
  110.                 break;  
  111.             case SKPaymentTransactionStateRestored:  
  112.             {  
  113.                 [[SKPaymentQueue defaultQueue]finishTransaction:transaction];  
  114.             }  
  115.                 break;  
  116.             default:  
  117.                 break;  
  118.         }  
  119.     }  
  120.   
  121. }  
  122.   
  123.   
  124. @end  
[cpp] view plaincopy
  1.   

之前的BASE64函数有点问题,所以删掉了,换了一个
下面是 transaction.transactionState的几种状态
[cpp] view plaincopy
  1. SKPaymentTransactionStatePurchasing,    // 这一个是应用商店是正在处理交易的状态  
  2. SKPaymentTransactionStatePurchased,     // 这一个是应用商店成功处理付款的状态  
  3. SKPaymentTransactionStateFailed,        // 这儿是应用商店处理失败的状态  
  4. SKPaymentTransactionStateRestored       // 这个是应用商店恢复之前的状态  





中间遇到的问题

(1)问题:使用SKPaymentpaymentWithProductIdentifier无法连接上APP STORE导致无法进行购买(网络不好也可能出现连接不上的情况)
     解决方法:改用SKPayment的paymentWithProduct方法

(2)问题:购买时,登陆成功后提示 [environment:sandbox] ,导致无法成功购买
     解决方案:我在这,就是回到ITUNESCONNETION中重新Add了1个账号(美国地区的,中国的试了几个都不行),回到设备上注销掉之前的账号和关掉APP STORE,重新登陆即可

(3)问题:-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response 中 response.invalidProductIdentifiers count>0的情况。
     解决方案:我换了一台非越狱设备,就正常了


苹果IAP文档:https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/13_ManagingIn-AppPurchases/ManagingIn-AppPurchases.html#//apple_ref/doc/uid/TP40011225-CH4-SW1

苹果视频(Using Store Kit for In-App Purchases):https://developer.apple.com/wwdc/videos/?id=305
0 0
原创粉丝点击