StoreKit
- 用于iOS内购
内购流程
配置一个明确的APPID
配置内购相关的内容
- 配置内购项 配置测试账号 配置银行 信息
内购的流程
内购代码的实现
- 获取想卖的商品的ProductID(服务器)—>NSSet
- 请求可买的商品(SKProductRequest)
- 代理方法:SKProductResponse—>products—>SKProduct
- SKPayment paymentWithProduct:product
- [SKPaymentQueue defaultQueue] addPayment:payment
- [添加观察者]
- SKPaymentTransaction—>transactionState
- [SKPaymentQueue defaultQueue] retoreTransactions
#import "ViewController.h"
#import <StoreKit/StoreKit.h>
@interface ViewController ()<SKProductsRequestDelegate, SKPaymentTransactionObserver>
/** 产品数组*/
@property (nonatomic, strong) NSArray *productArray;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//1. 请求可售商品列表 --> 需要手动传入商品的标示符 --> 有可能传错, 或者失效
//2. 获取可售商品后给用户呈现
//3. 用户点击购买, 开具凭证
//4. 交易队列排队付款
//5. 付款成功, 享受增值服务
//6. 观察者会检测交易过程
NSSet *set = [NSSet setWithObjects:@"XXXX1",
@"XXXX2", nil];
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
request.delegate = self;
[request start];
}
#pragma mark 此方法在请求苹果可售商品列表后, 会调用此方法
- (void)productsRequest:(SKProductsRequest *)request
didReceiveResponse:(SKProductsResponse *)response {
//invalidProductIdentifiers: 无效的商品ID, 这个属性对用于无用, 只是方便开发者进行调试的
NSLog(@"id: %@", response.invalidProductIdentifiers);
self.productArray = response.products;
[self.tableView reloadData];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.productArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *ID = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
//1. 获取Product对象
SKProduct *product = self.productArray[indexPath.row];
//2. 根据需求获取对应的数据
cell.textLabel.text = product.localizedTitle;
cell.detailTextLabel.text = product.localizedDescription;
return cell;
}
#pragma mark cell选中方法, 实现点击购买
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//1. 获取Product对象
SKProduct *product = self.productArray[indexPath.row];
//2. 用户点击购买, 开具凭证
//Payment: 凭证
SKPayment * payment = [SKPayment paymentWithProduct:product];
//3. 交易队列排队付款
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
#pragma mark 观察者的添加(通知的添加)在视图出现的时候添加
//通知和代理的相关设置, 其实都可以放在这里, 也建议放在这里
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//观察者会检测交易过程
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
#pragma mark 观察者的移除(通知的移除)在视图消失的时候移除
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
#pragma mark 监听交易过程的代理方法
- (void)paymentQueue:(SKPaymentQueue *)queue
updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions {
/**
SKPaymentTransactionStatePurchasing, 购买中
SKPaymentTransactionStatePurchased, 购买完成, 需要关闭交易.
SKPaymentTransactionStateFailed, 购买失败
SKPaymentTransactionStateRestored, 恢复购买, 需要关闭交易
SKPaymentTransactionStateDeferred 未决定
*/
// 获取单个的交易对象
for (SKPaymentTransaction *transacation in transactions) {
switch (transacation.transactionState) {
case SKPaymentTransactionStatePurchasing:
NSLog(@"购买中");
break;
case SKPaymentTransactionStatePurchased:
NSLog(@"购买完成, 需要关闭交易");
//关闭交易
[[SKPaymentQueue defaultQueue] finishTransaction:transacation];
break;
case SKPaymentTransactionStateFailed:
NSLog(@"购买失败");
break;
case SKPaymentTransactionStateRestored:
NSLog(@"恢复购买, 需要关闭交易");
//关闭交易
[[SKPaymentQueue defaultQueue] finishTransaction:transacation];
break;
case SKPaymentTransactionStateDeferred:
NSLog(@"未决定");
break;
default:
break;
}
}
}
#pragma mark 重新购买
- (IBAction)restoreClick:(id)sender {
//这里还应该给用户弹出一些提示
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
@end