下面我会以一个简单的例子演示程序端如何使用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
- #import <UIKit/UIKit.h>
- #import "ECPurchase.h"
- @interface ProductsViewController : UITableViewController
- {
- NSArray *products_;
- }
- @end
ProductsViewController.m
- #import "ProductsViewController.h"
- #import "IAPHandler.h"
- @interface ProductsViewController ()
- - (void)registIapObservers;
- @end
- @implementation ProductsViewController
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- self.title = @"IAP Demo";
- [self registIapObservers];
- [IAPHandler initECPurchaseWithHandler];
- NSArray *productIds = [NSArray arrayWithObjects:@"info.luoyl.iap.item1",
- @"info.luoyl.iap.item2",
- @"info.luoyl.iap.item3", nil];
- [[ECPurchase shared]requestProductData:productIds];
- }
- - (void)viewWillUnload
- {
- [[NSNotificationCenter defaultCenter]removeObserver:self];
- }
- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
- {
- return products_ ? [products_ count] : 0;
- }
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- static NSString *CellIdentifier = @"Cell";
- UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
- if (cell == nil) {
- cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
- cell.selectionStyle = UITableViewCellSelectionStyleNone;
- cell.accessoryType = UITableViewCellAccessoryNone;
- } else {
- for (UIView *view in [cell.contentView subviews]) {
- [view removeFromSuperview];
- }
- }
- SKProduct *product = [products_ objectAtIndex:indexPath.row];
- UILabel *localizedTitle = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 130, 20)];
- localizedTitle.text = product.localizedTitle;
- UILabel *localizedPrice = [[UILabel alloc]initWithFrame:CGRectMake(150, 10, 100, 20)];
- localizedPrice.text = product.localizedPrice;
- UIButton *buyButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
- buyButton.tag = indexPath.row;
- buyButton.frame = CGRectMake(250, 10, 50, 20);
- [buyButton setTitle:@"Buy" forState:UIControlStateNormal];
- [buyButton addTarget:self action:@selector(buy:) forControlEvents:UIControlEventTouchUpInside];
- [cell.contentView addSubview:localizedTitle];
- [cell.contentView addSubview:localizedPrice];
- [cell.contentView addSubview:buyButton];
- return cell;
- }
- - (void)getedProds:(NSNotification*)notification
- {
- NSLog(@"通过NSNotificationCenter收到信息:%@,", [notification object]);
- }
- - (void)buy:(UIButton*)sender
- {
- SKProduct *product = [products_ objectAtIndex:sender.tag];
- NSLog(@"购买商品:%@", product.productIdentifier);
- [[ECPurchase shared]addPaymentWithProduct:product];
- }
- - (void)viewDidUnload
- {
- [super viewDidUnload];
- }
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
- {
- return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
- }
- -(void) receivedProducts:(NSNotification*)notification
- {
- if (products_) {
- [products_ release];
- products_ = nil;
- }
- products_ = [[NSArray alloc]initWithArray:[notification object]];
- [self.tableView reloadData];
- }
- - (void)registIapObservers
- {
- [[NSNotificationCenter defaultCenter]addObserver:self
- selector:@selector(receivedProducts:)
- name:IAPDidReceivedProducts
- object:nil];
- [[NSNotificationCenter defaultCenter]addObserver:self
- selector:@selector(failedTransaction:)
- name:IAPDidFailedTransaction
- object:nil];
- [[NSNotificationCenter defaultCenter]addObserver:self
- selector:@selector(restoreTransaction:)
- name:IAPDidRestoreTransaction
- object:nil];
- [[NSNotificationCenter defaultCenter]addObserver:self
- selector:@selector(completeTransaction:)
- name:IAPDidCompleteTransaction object:nil];
- [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(completeTransactionAndVerifySucceed:)
- name:IAPDidCompleteTransactionAndVerifySucceed
- object:nil];
- [[NSNotificationCenter defaultCenter]addObserver:self
- selector:@selector(completeTransactionAndVerifyFailed:)
- name:IAPDidCompleteTransactionAndVerifyFailed
- object:nil];
- }
- -(void)showAlertWithMsg:(NSString*)message
- {
- UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"IAP反馈"
- message:message
- delegate:nil
- cancelButtonTitle:@"OK"
- otherButtonTitles:nil, nil];
- [alert show];
- [alert release];
- }
- -(void) failedTransaction:(NSNotification*)notification
- {
- [self showAlertWithMsg:[NSString stringWithFormat:@"交易取消(%@)",[notification name]]];
- }
- -(void) restoreTransaction:(NSNotification*)notification
- {
- [self showAlertWithMsg:[NSString stringWithFormat:@"交易恢复(%@)",[notification name]]];
- }
- -(void )completeTransaction:(NSNotification*)notification
- {
- [self showAlertWithMsg:[NSString stringWithFormat:@"交易成功(%@)",[notification name]]];
- }
- -(void) completeTransactionAndVerifySucceed:(NSNotification*)notification
- {
- NSString *proIdentifier = [notification object];
- [self showAlertWithMsg:[NSString stringWithFormat:@"交易成功,产品编号:%@",proIdentifier]];
- }
- -(void) completeTransactionAndVerifyFailed:(NSNotification*)notification
- {
- NSString *proIdentifier = [notification object];
- [self showAlertWithMsg:[NSString stringWithFormat:@"产品%@交易失败",proIdentifier]];
- }
- @end
IAPHandler.h
- #define IAPDidReceivedProducts @"IAPDidReceivedProducts"
- #define IAPDidFailedTransaction @"IAPDidFailedTransaction"
- #define IAPDidRestoreTransaction @"IAPDidRestoreTransaction"
- #define IAPDidCompleteTransaction @"IAPDidCompleteTransaction"
- #define IAPDidCompleteTransactionAndVerifySucceed @"IAPDidCompleteTransactionAndVerifySucceed"
- #define IAPDidCompleteTransactionAndVerifyFailed @"IAPDidCompleteTransactionAndVerifyFailed"
- #import <Foundation/Foundation.h>
- #import "ECPurchase.h"
- @interface IAPHandler : NSObject<ECPurchaseTransactionDelegate, ECPurchaseProductDelegate>
- + (void)initECPurchaseWithHandler;
- @end
IAPHandler.m
- #import "IAPHandler.h"
- @interface IAPHandler()
- -(void)afterProductBuyed:(NSString*)proIdentifier;
- @end
- @implementation IAPHandler
- static IAPHandler *DefaultHandle_ = nil;
- + (void)initECPurchaseWithHandler
- {
- @synchronized(self) {
- if (!DefaultHandle_) {
- DefaultHandle_ = [[IAPHandler alloc]init];
- }
- }
- }
- - (id)init
- {
- if (self = [super init]) {
- [[ECPurchase shared] addTransactionObserver];
- [[ECPurchase shared] setProductDelegate:self];
- [[ECPurchase shared] setTransactionDelegate:self];
- [[ECPurchase shared] setVerifyRecepitMode:ECVerifyRecepitModeiPhone];
- }
- return self;
- }
- #pragma mark - ECPurchaseProductDelegate
- - (void)didReceivedProducts:(NSArray *)products
- {
- [[NSNotificationCenter defaultCenter] postNotificationName:IAPDidReceivedProducts object:products];
- }
- #pragma mark - ECPurchaseTransactionDelegate
- -(void)didFailedTransaction:(NSString *)proIdentifier
- {
- [[NSNotificationCenter defaultCenter] postNotificationName:IAPDidFailedTransaction object:proIdentifier];
- }
- -(void)didRestoreTransaction:(NSString *)proIdentifier
- {
- [[NSNotificationCenter defaultCenter] postNotificationName:IAPDidRestoreTransaction object:proIdentifier];
- }
- -(void)didCompleteTransaction:(NSString *)proIdentifier
- {
- [self afterProductBuyed:proIdentifier];
- [[NSNotificationCenter defaultCenter] postNotificationName:IAPDidCompleteTransaction object:proIdentifier];
- }
- -(void)didCompleteTransactionAndVerifySucceed:(NSString *)proIdentifier
- {
- [self afterProductBuyed:proIdentifier];
- [[NSNotificationCenter defaultCenter] postNotificationName:IAPDidCompleteTransactionAndVerifySucceed object:proIdentifier];
- }
- -(void)didCompleteTransactionAndVerifyFailed:(NSString *)proIdentifier withError:(NSString *)error
- {
- [[NSNotificationCenter defaultCenter] postNotificationName:IAPDidCompleteTransactionAndVerifyFailed object:proIdentifier];
- }
- -(void)afterProductBuyed:(NSString*)proIdentifier
- {
- }
- @end