苹果商店的赚钱方式
- 直接收费:下载应用时收费
- 广告:苹果提供的广告控件,广告内容不是自己提供的
- 内购:应用程序本身的增值产品
苹果与开发者的比例分成是37开,开发者占7成收益
内购的代码实现
- 请求可售商品列表
- 创建商品的无序集
- 创建商品请求对象
- 设置代理,接收请求到的数据
- 开始请求
- 苹果会返回商品列表,在代理方法中返回
- 判断是否存在无效的标示符商品
- 获取并保存产品列表
- 刷新表格
- 在tableView的选中方法中,选中产品,开票据凭证
- 获取选中的商品
- 开票据凭证
- 进入交易队列 –> 单例不需要alloc创建
- 获取选中的商品
- 开票据凭证
- 进入交易队列
- 观察者对象监听支付流程(一旦监听到购买行为时,就会通知代理方法返回相关信息)
- 视图将要出现时,添加通知
- 视图即将消失时,移除通知
- 代理方法中监听交易的状态
- 购买中
- 购买完成
- 购买失败
- 恢复购买
- 无法判断
代码实现
//
// ViewController.m
// 02-内购代码实现
//
// Created by styshy on 16/1/3.
// Copyright © 2016年 styshy. All rights reserved.
//
#import "ViewController.h"
#import <StoreKit/StoreKit.h>
@interface ViewController ()<SKProductsRequestDelegate,UITableViewDataSource,UITableViewDelegate,SKPaymentTransactionObserver>
@property (nonatomic, strong) NSArray *products;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 请求可售商品列表
// 1.1 创建商品标识符的无序集
NSSet *set = [NSSet setWithObjects:@"com.itheima.heima4in.yaoshui", @"com.itheima.heima4in.dabaojian",nil];
// 1.2 创建商品请求对象
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
// 1.3 设置代理 --> 获取请求到的商品列表
request.delegate = self;
// 1.4 开始请求
[request start];
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
#pragma mark - SKProductRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
/**
* 2.苹果会返回商品列表 --> 在代理方法中返回
* 如果标识符不正确,会返回一个错误的array集合,这个东西供用户开发调试使用
* invalidProductIdentifier:无效标识符
*/
// 2.1 判断是否存在无效的标识符
if (response.invalidProductIdentifiers.count > 0) {
NSLog(@"invalidProductIdentifiers:%@",response.invalidProductIdentifiers);
}
// 2.2 获取并保存产品列表
self.products = response.products;
// 2.3 刷新表格
[self.tableView reloadData];
}
#pragma mark - 数据源方法
- (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];
}
return cell;
}
#pragma mark - 代理方法
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
// 1.获取商品列表
SKProduct *product = self.products[indexPath.row];
// 2.显示商品信息
cell.textLabel.text = product.localizedTitle;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
// 选择之后,开票据凭证
// 1.获取选中商品
SKProduct *product = self.products[indexPath.row];
// 2.开票据凭证
SKPayment *payment = [SKPayment paymentWithProduct:product];
// 3.进入交易队列
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
#pragma mark - 代理方法静听支付状态
/**
SKPaymentTransactionStatePurchasing
SKPaymentTransactionStatePurchased
SKPaymentTransactionStateFailed
SKPaymentTransactionStateRestored
SKPaymentTransactionStateDeferred
*/
//
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions{
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchasing:
NSLog(@"正在购买当中");
break;
case SKPaymentTransactionStatePurchased:
NSLog(@"购买完成");
// 结束交易
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
NSLog(@"交易失败");
// 结束交易
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
NSLog(@"恢复购买");
// 结束交易
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateDeferred:
NSLog(@"无法判断");
break;
default:
break;
}
}
}
@end