ECPurchase实现IAP的例子

下面我会以一个简单的例子演示程序端如何使用ECPurchase完成IAP功能,该例子实现了以下功能:从App Store上获取In App Purchase产品列表,并显示在一个表格(UITableView)上,点击表格上某一个产品名右边的“buy”按钮能购买对应的产品。这个例子主要包含两个类:ProductsViewController 和IAPHandler。

ProductsViewController为UI类,用于显示Iap产品列表和弹出购买结果;

IAPHandler实现ECPurchase与的两个代理接口:ECPurchaseTransactionDelegate和ECPurchaseProductDelegate,ECPurchase的执行结果会被IAPHandler接收处理。 IAPHandler被设计为单例类,目的是防止在iap请求过程中IAPHandler的实例被销毁,导致iap购买结果返回后找不到处理的实例对象。

我们可以在IAPHandler里加入自己的业务逻辑,如购买某个金币产品成功后给玩家帐号增加对应的金币数、购买解锁道具后给游戏解锁等逻辑等。IAPHandler处理了玩家的购买请求后会使用消息中心(NSNotificationCenter)对外发送一条消息,我们可以在相关的视图里接收该消息,更新视图。

首先我们需要创建一个项目,主要项目里设置的Bundle identifier要与itunes connect里指定的一样;

 

导入以下库:
  • StoreKit.framework
  • CFNetwork.framework
  • SystemConfiguration.framework
  • libz.1.2.5.dylib
把ECPurchase库拷贝到项目里(可从下载的例子里获得)

编写下面的代码:
ProductsViewController.h
  1. //   
  2. //  ProductsViewController.h   
  3. //  IAPDemo   
  4. //   
  5. //  Created by luoyl on 12-3-24.   
  6. //  Copyright (c) 2012年 http://luoyl.info. All rights reserved.   
  7. //   
  8.   
  9. #import <UIKit/UIKit.h>   
  10. #import "ECPurchase.h"   
  11.   
  12. @interface ProductsViewController : UITableViewController   
  13. {   
  14.     NSArray *products_;   
  15. }   
  16.   
  17. @end  

 

ProductsViewController.m
  1. //   
  2. //  ProductsViewController.m   
  3. //  IAPDemo   
  4. //   
  5. //  Created by luoyl on 12-3-24.   
  6. //  Copyright (c) 2012年 http://luoyl.info. All rights reserved.   
  7. //   
  8.   
  9. #import "ProductsViewController.h"   
  10. #import "IAPHandler.h"   
  11.   
  12. @interface ProductsViewController ()   
  13. - (void)registIapObservers;   
  14. @end   
  15.   
  16. @implementation ProductsViewController   
  17.   
  18. - (void)viewDidLoad   
  19. {   
  20.     [super viewDidLoad];     
  21.     self.title = @"IAP Demo";   
  22.     [self registIapObservers];   
  23.     [IAPHandler initECPurchaseWithHandler];   
  24.     //iap产品编号集合,这里你需要替换为你自己的iap列表   
  25.     NSArray *productIds = [NSArray arrayWithObjects:@"info.luoyl.iap.item1",   
  26.                                                     @"info.luoyl.iap.item2",   
  27.                                                     @"info.luoyl.iap.item3", nil];   
  28.     //从AppStore上获取产品信息   
  29.     [[ECPurchase shared]requestProductData:productIds];   
  30. }   
  31.   
  32. - (void)viewWillUnload   
  33. {   
  34.     [[NSNotificationCenter defaultCenter]removeObserver:self];   
  35. }   
  36.   
  37. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section   
  38. {   
  39.     return products_ ? [products_ count] : 0;   
  40. }   
  41.   
  42. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath   
  43. {   
  44.     static NSString *CellIdentifier = @"Cell";   
  45.        
  46.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];   
  47.     if (cell == nil) {   
  48.         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];   
  49.         cell.selectionStyle = UITableViewCellSelectionStyleNone;   
  50.         cell.accessoryType =  UITableViewCellAccessoryNone;   
  51.     } else {   
  52.         for (UIView *view in [cell.contentView subviews]) {   
  53.             [view removeFromSuperview];   
  54.         }   
  55.     }   
  56.     SKProduct *product = [products_ objectAtIndex:indexPath.row];   
  57.     //产品名称   
  58.     UILabel *localizedTitle = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 130, 20)];   
  59.     localizedTitle.text = product.localizedTitle;   
  60.     //产品价格   
  61.     UILabel *localizedPrice = [[UILabel alloc]initWithFrame:CGRectMake(150, 10, 100, 20)];   
  62.     localizedPrice.text = product.localizedPrice;   
  63.     //购买按钮   
  64.     UIButton *buyButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];   
  65.     buyButton.tag = indexPath.row;   
  66.     buyButton.frame = CGRectMake(250, 10, 50, 20);   
  67.     [buyButton setTitle:@"Buy" forState:UIControlStateNormal];   
  68.     [buyButton addTarget:self action:@selector(buy:) forControlEvents:UIControlEventTouchUpInside];   
  69.   
  70.     [cell.contentView addSubview:localizedTitle];   
  71.     [cell.contentView addSubview:localizedPrice];   
  72.     [cell.contentView addSubview:buyButton];   
  73.     return cell;   
  74. }   
  75.   
  76. - (void)getedProds:(NSNotification*)notification   
  77. {   
  78.     NSLog(@"通过NSNotificationCenter收到信息:%@,", [notification object]);   
  79. }   
  80.   
  81.   
  82. - (void)buy:(UIButton*)sender   
  83. {   
  84.     SKProduct *product = [products_ objectAtIndex:sender.tag];   
  85.     NSLog(@"购买商品:%@", product.productIdentifier);   
  86.     [[ECPurchase shared]addPaymentWithProduct:product];   
  87. }   
  88.   
  89.   
  90. - (void)viewDidUnload   
  91. {   
  92.     [super viewDidUnload];   
  93. }   
  94.   
  95. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation   
  96. {   
  97.     return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);   
  98. }   
  99.   
  100. //接收从app store抓取回来的产品,显示在表格上   
  101. -(void) receivedProducts:(NSNotification*)notification   
  102. {   
  103.     if (products_) {   
  104.         [products_ release];   
  105.         products_ = nil;   
  106.     }   
  107.     products_ = [[NSArray alloc]initWithArray:[notification object]];   
  108.     [self.tableView reloadData];    
  109. }   
  110.   
  111. // 注册IapHander的监听器,并不是所有监听器都需要注册,   
  112. // 这里可以根据业务需求和收据认证模式有选择的注册需要   
  113. - (void)registIapObservers   
  114. {   
  115.     [[NSNotificationCenter defaultCenter]addObserver:self    
  116.                                             selector:@selector(receivedProducts:)    
  117.                                                 name:IAPDidReceivedProducts    
  118.                                               object:nil];   
  119.       
  120.     [[NSNotificationCenter defaultCenter]addObserver:self   
  121.                                             selector:@selector(failedTransaction:)   
  122.                                                 name:IAPDidFailedTransaction    
  123.                                               object:nil];   
  124.        
  125.     [[NSNotificationCenter defaultCenter]addObserver:self   
  126.                                             selector:@selector(restoreTransaction:)    
  127.                                                 name:IAPDidRestoreTransaction    
  128.                                               object:nil];   
  129.       
  130.     [[NSNotificationCenter defaultCenter]addObserver:self    
  131.                                             selector:@selector(completeTransaction:)   
  132.                                                 name:IAPDidCompleteTransaction object:nil];   
  133.        
  134.     [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(completeTransactionAndVerifySucceed:)    
  135.                                                 name:IAPDidCompleteTransactionAndVerifySucceed    
  136.                                               object:nil];   
  137.       
  138.     [[NSNotificationCenter defaultCenter]addObserver:self    
  139.                                             selector:@selector(completeTransactionAndVerifyFailed:)    
  140.                                                 name:IAPDidCompleteTransactionAndVerifyFailed    
  141.                                               object:nil];   
  142. }   
  143.   
  144. -(void)showAlertWithMsg:(NSString*)message   
  145. {   
  146.     UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"IAP反馈"    
  147.                                                    message:message    
  148.                                                   delegate:nil    
  149.                                          cancelButtonTitle:@"OK"    
  150.                                          otherButtonTitles:nil, nil];   
  151.     [alert show];   
  152.     [alert release];   
  153. }   
  154.   
  155. -(void) failedTransaction:(NSNotification*)notification   
  156. {   
  157.     [self showAlertWithMsg:[NSString stringWithFormat:@"交易取消(%@)",[notification name]]];    
  158. }   
  159.   
  160. -(void) restoreTransaction:(NSNotification*)notification   
  161. {   
  162.     [self showAlertWithMsg:[NSString stringWithFormat:@"交易恢复(%@)",[notification name]]];    
  163. }   
  164.   
  165. -(void )completeTransaction:(NSNotification*)notification   
  166. {   
  167.     [self showAlertWithMsg:[NSString stringWithFormat:@"交易成功(%@)",[notification name]]];    
  168. }   
  169.   
  170. -(void) completeTransactionAndVerifySucceed:(NSNotification*)notification   
  171. {   
  172.     NSString *proIdentifier = [notification object];   
  173.     [self showAlertWithMsg:[NSString stringWithFormat:@"交易成功,产品编号:%@",proIdentifier]];   
  174. }   
  175.   
  176. -(void) completeTransactionAndVerifyFailed:(NSNotification*)notification   
  177. {   
  178.     NSString *proIdentifier = [notification object];   
  179.     [self showAlertWithMsg:[NSString stringWithFormat:@"产品%@交易失败",proIdentifier]];   
  180. }   
  181.   
  182. @end   
IAPHandler.h
  1. //   
  2. //  IAPHandler.h   
  3. //  IAPDemo   
  4. //   
  5. //  Created by luoyl on 12-3-24.   
  6. //  Copyright (c) 2012年 http://luoyl.info. All rights reserved.   
  7. //   
  8.   
  9. #define IAPDidReceivedProducts                      @"IAPDidReceivedProducts"   
  10. #define IAPDidFailedTransaction                     @"IAPDidFailedTransaction"   
  11. #define IAPDidRestoreTransaction                    @"IAPDidRestoreTransaction"   
  12. #define IAPDidCompleteTransaction                   @"IAPDidCompleteTransaction"   
  13. #define IAPDidCompleteTransactionAndVerifySucceed   @"IAPDidCompleteTransactionAndVerifySucceed"  
  14. #define IAPDidCompleteTransactionAndVerifyFailed    @"IAPDidCompleteTransactionAndVerifyFailed"  
  15. #import <Foundation/Foundation.h>   
  16. #import "ECPurchase.h"   
  17.   
  18. @interface IAPHandler : NSObject<ECPurchaseTransactionDelegate, ECPurchaseProductDelegate>   
  19.   
  20. + (void)initECPurchaseWithHandler;   
  21. @end  
IAPHandler.m
  1. //   
  2. //  IAPHandler.m   
  3. //  IAPDemo   
  4. //   
  5. //  Created by luoyl on 12-3-24.   
  6. //  Copyright (c) 2012年 http://luoyl.info. All rights reserved.   
  7. //   
  8.   
  9. #import "IAPHandler.h"   
  10.   
  11. @interface IAPHandler()   
  12. -(void)afterProductBuyed:(NSString*)proIdentifier;   
  13. @end   
  14. @implementation IAPHandler   
  15.   
  16. static IAPHandler *DefaultHandle_ = nil;   
  17.   
  18. + (void)initECPurchaseWithHandler   
  19. {   
  20.     @synchronized(self)     {   
  21.         if (!DefaultHandle_) {   
  22.             DefaultHandle_ = [[IAPHandler alloc]init];   
  23.         }   
  24.     }       
  25. }   
  26.   
  27. - (id)init   
  28. {   
  29.     if (self = [super init]) {   
  30.         [[ECPurchase shared] addTransactionObserver];   
  31.         [[ECPurchase shared] setProductDelegate:self];   
  32.         [[ECPurchase shared] setTransactionDelegate:self];   
  33.         [[ECPurchase shared] setVerifyRecepitMode:ECVerifyRecepitModeiPhone];   
  34.     }   
  35.     return self;   
  36. }   
  37.   
  38. #pragma mark - ECPurchaseProductDelegate   
  39. //从App Store请求产品列表后返回的产品列表   
  40. - (void)didReceivedProducts:(NSArray *)products   
  41. {   
  42.     [[NSNotificationCenter defaultCenter] postNotificationName:IAPDidReceivedProducts object:products];   
  43. }   
  44.   
  45. #pragma mark - ECPurchaseTransactionDelegate   
  46. // 如果不需要收据认证, 则实现以下3个代理函数   
  47. // 即 ECVerifyRecepitModeNone 模式下   
  48. -(void)didFailedTransaction:(NSString *)proIdentifier   
  49. {   
  50. //   NSLog(@"交易取消");   
  51.     [[NSNotificationCenter defaultCenter] postNotificationName:IAPDidFailedTransaction object:proIdentifier];   
  52. }   
  53.   
  54. -(void)didRestoreTransaction:(NSString *)proIdentifier   
  55. {   
  56.     //NSLog(@" 交易恢复 ");   
  57.     [[NSNotificationCenter defaultCenter] postNotificationName:IAPDidRestoreTransaction object:proIdentifier];   
  58. }   
  59.   
  60. -(void)didCompleteTransaction:(NSString *)proIdentifier   
  61. {   
  62. //  NSLog(@" 交易成功 ");   
  63.     [self afterProductBuyed:proIdentifier];   
  64.     [[NSNotificationCenter defaultCenter] postNotificationName:IAPDidCompleteTransaction object:proIdentifier];   
  65. }   
  66.   
  67. // 否则, 需要收据认证, 实现以下2个代理函数   
  68. // ECVerifyRecepitModeiPhone 和 ECVerifyRecepitModeServer模式下   
  69. -(void)didCompleteTransactionAndVerifySucceed:(NSString *)proIdentifier   
  70. {   
  71.     [self afterProductBuyed:proIdentifier];   
  72.     [[NSNotificationCenter defaultCenter] postNotificationName:IAPDidCompleteTransactionAndVerifySucceed object:proIdentifier];   
  73. }   
  74.   
  75. -(void)didCompleteTransactionAndVerifyFailed:(NSString *)proIdentifier withError:(NSString *)error   
  76. {   
  77.     [[NSNotificationCenter defaultCenter] postNotificationName:IAPDidCompleteTransactionAndVerifyFailed object:proIdentifier];   
  78.   
  79. }   
  80.   
  81. //用户购买某件商品成功后的处理逻辑   
  82. -(void)afterProductBuyed:(NSString*)proIdentifier   
  83. {   
  84.     //写下你的逻辑, 加金币 or 解锁 or ...   
  85. }   
  86. @end   
posted @ 2014-02-22 23:32  左左木  阅读(1036)  评论(1编辑  收藏  举报