在App中都会有一些增值产品,比如说游戏的装备,道具之类的,是应用程序本身的增值产品。我们可以在登录了开发者账号之后,我们要去配置下证书和一些应用信息,然后之后我们再去点击一个iTunes Connect的东西,会有这么个网址https://itunesconnect.apple.com/login 在这里面中可以进行一些增值产品的配置。
像淘宝,天猫,京东那些产品不属于应用内购买的产品,只是一个第三方支付。
具体的代码实现如下所示
#import "ViewController.h"
#include <StoreKit/StoreKit.h>
@interface ViewController ()<SKProductsRequestDelegate,SKPaymentTransactionObserver>
//记录产品信息的数组
@property (nonatomic ,strong)NSArray *products;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//1、请求可销售商品的列表,
//1.1里面传入你增值产品的ID,这里就是创建产品ID的无序的集合
NSSet * set = [NSSet setWithObjects:@"kkkk",@"1111ww",nil];
//1.2创建商品请求对象
SKProductsRequest * request = [[SKProductsRequest alloc]initWithProductIdentifiers:set];
//1.3设置代理 获取请求到的商品的列表
request.delegate = self;
//1.4开始请求
[request start];
}
#pragma mark 此代理方法会返回请求后的结果的信息
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
//2、苹果在这个方法中会返回商品的列表
//如果代理方法不正确的话,就会返回一个错误的invalidProductIdentifiers的数组,所以我们可以去判断下是否有错误
//2.1判断是否有无效的产品的ID存在
if(response.invalidProductIdentifiers.count > 0)
{
NSLog(@"invalidProductIdentifiers: %@",response.invalidProductIdentifiers);
}
//2.2获取产品的列表,数组里面是SKProduct对象
self.products = response.products;
//2.3 刷新表格
[self.tableView reloadData];
}
//返回产品的数量
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.products.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * ID = @"cell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:ID];
if(cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
//获取产品模型
SKProduct * product = self.products[indexPath.row];
cell.textLabel.text = product.localizedTitle;
return cell;
}
#pragma mark 此处我们模拟点击cell,开始购买
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//3、选择相应的商品,然后去开票据的凭证
//3.1首先我们先去获取选中的产品
SKProduct * product = self.products[indexPath.row];
//3.2开票据的凭证
SKPayment * payment = [SKPayment paymentWithProduct:product];
//4、进入交易队列
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
//我们一般是在视图将要出现去添加观察者对象因为万一多个控制器都是监听了,那会产生混乱
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//5、添加观察者对象去监听付款的流程,这个方法就是一旦监听到了购买的方法就会通过带来方法来返回相关的信息
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
//视图即将消失的时候移除通知
-(void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[[SKPaymentQueue defaultQueue]removeTransactionObserver:self];
}
//通过这个代理方法来监听支付
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions
{
// SKPaymentTransactionStatePurchasing, 购买中的状态
// SKPaymentTransactionStatePurchased, 购买完成 后面有提示我们要去结束交易 Client should complete the transaction.
// SKPaymentTransactionStateFailed, 购买失败
// SKPaymentTransactionStateRestored, 恢复购买,我们也要去结束交易,就是说用户已购买的一些非消耗品产品可以进行恢复
//Transaction was restored from user's purchase history. Client should complete the transaction.
// SKPaymentTransactionStateDeferred 不能判断,一般是用户还没有进行设置一些相关的信息
//The transaction is in the queue, but its final status is pending external action.
for(SKPaymentTransaction * transaction in transactions)
{
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchasing:
NSLog(@"购买中");
break;
case SKPaymentTransactionStatePurchased:
NSLog(@"购买完成");
//要去结束交易不然订单就一直处在队列中
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
NSLog(@"购买失败");
break;
case SKPaymentTransactionStateRestored:
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
NSLog(@"恢复购买");
break;
case SKPaymentTransactionStateDeferred:
NSLog(@"没进行一些相关设置");
break;
default:
break;
}
}
}
//恢复购买
-(void)restore
{
//恢复购买调用下面的函数
[[SKPaymentQueue defaultQueue]restoreCompletedTransactions];
}
有一点需要注意的是[SKPaymentQueue defaultQueue]这个队列里面存着所有的已支付和未支付的订单,而且我们需要去手动移除,App每次启动的时候都会去判断这个队列里面是否为空,如果不为空的话会调用<SKPaymentTransactionObserver>代理的方法- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions。