iOS内购步骤总结
### 什么是内购?
– 内购就是指,在APP内购买某些产品
:: 如果你在App中销售的商品,跟App有关(例如植物大战僵尸中的道具,需要开启关卡,拥有某种技能等等).那么,苹果规定,必须通过内购方式购买.
:: 内购分成: 3:7分 ::
– 为什么做内购?
:: 1. 开发者创收的一种模式:free+内购 2.某些场景下不得不用::
– 内购的产品类型
> 非消耗品(Nonconsumable)
:: 买了就一直有,不会消耗,例如开启关卡
:: 指的是在游戏中一次性购买并拥有永久访问权的物品或服务。非消耗品物品可以被用户再次下载,并且能够在用户的所有设备上使用
> 消耗品(Consumable)
:: 买了就用,用了就没
:: 专为支持可消耗的物品或服务设计的,消耗品购买不可被再次下载,根据其特点,消耗品不能在用户的设备之间跨设备使用,除非自定义服务在用户的账号之间共享这些信息
> 以下三种类别在iBooks中使用,目前iBooks不支持大陆市场
:: 免费订阅(Free subscriptions)
:: 自动续费订阅(Auto-renewing subscriptions)
:: 非自动续费订阅(Nonrenewing subscriptions)
### 内购流程
– 类似于商场购物流程,参照PPT图解
– 内购演练
1. 在App管理中心,创建一个App,并填写App信息
:: ** 注意: 此处创建的App时,填写套装ID,时,必须选择可以内购的套装ID **::
2. 创建内购商品,并添加到App,指定此App,可以销售哪些商品
:: ** 注意: 创建内购商品的前提,是你已经填写了税务/银行信息,否则的话,无法创建**::
3. 添加用于测试内购的测试账号
4. 创建App项目,开始开发
5. 代码实现内购流程
### 广告
> 广告作用?
:: 属于创收的一种方式, 你在App内展示广告,苹果会付费给你,分成从原来的4:6 到 3:7 ::
> 如何展示广告?
– 导入框架: iAd.framework
– 添加控件: ADBannerView
– 实现代理 ADBannerViewDelegate,优化用户体验
0:做内购需要添加系统框架storeKit.frameWork
1:登陆苹果开发者账号中去创建商品,即告诉苹果商场自己都卖哪些东西如图:
@interface ProductModel : NSObject
/**产品名称*/
@property (nonatomic, copy) NSString *name;
/**产品id*/
@property (nonatomic, copy) NSString *productID;
2:从服务器中取出商品,(封装:数据模型和请求模型)
@implementation AWDataTool
+(void)getProduct:(ResultBlock)resultBlock
{
ProductModel *model = [[ProductModel alloc] init];
model.name = @”大神跑鞋”;
model.productID = @”dashenpaoxie”;
resultBlock(@[model]);
}
3:将商品发送到苹果服务器,请求可以销售的商品;
//服务器中取出商品
[AWDataTool getProduct:^(NSArray<ProductModel *> *goods) {
//取出商品ID
NSArray *product = [goods valueForKey:@”productID”];
//将商品发送到苹果服务器,请求可以销售的商品
NSSet *set = [NSSet setWithArray:product];
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
//设置代理从代理中获取哪些商品可以销售
request.delegate = self;
[request start];
}];
#pragma mark – SKProductsRequestDelegate
/**
* 当请求到结果时会调用该方法
*
* @param request 请求
* @param response 响应
*/
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
self.productList = response.products;
}
———————————–uitableViewController所有代码如下—————————————–
//
// ViewController.m
// 大神一期内购测试
//
// Created by apple on 16/4/5.
// Copyright © 2016年 apple. All rights reserved.
//
#import “ViewController.h”
#import <StoreKit/StoreKit.h>
#import “XMGDataTool.h”
#import “XMGProduct.h”
@interface ViewController () <SKProductsRequestDelegate>
/** 能销售的商品列表 */
@property (strong, nonatomic) NSArray <SKProduct *> *products;
@end
@implementation ViewController
– (void)setProducts:(NSArray<SKProduct *> *)products {
_products = products;
[self.tableView reloadData];
}
– (void)viewDidLoad {
[super viewDidLoad];
// 1.从服务器获取商品
[XMGDataTool getProducts:^(NSArray<XMGProduct *> *goods) {
// 取出商品标示
NSArray *identifiers = [goods valueForKeyPath:@”proId”];
// 将商品标示发送到苹果服务器,请求可以销售的商品
NSSet *set = [[NSSet alloc] initWithArray:identifiers];
// 请求对象
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
// 设置代理,从代理中获取哪些商品可以销售
request.delegate = self;
// 开始请求
[request start];
}];
}
#pragma mark – SKProductsRequestDelegate
/**
* 当请求到结果时会调用该方法
*
* @param request 请求
* @param response 响应
*/
– (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
NSLog(@”%@”,response.products);
self.products = response.products;
}
#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:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
// 1.取出模型
SKProduct *product = self.products[indexPath.row];
// 2.设置数据
cell.textLabel.text = product.localizedTitle;
cell.detailTextLabel.text = product.localizedDescription;
return cell;
}
**
* 当交易状态发生改变时会调用该方法
*
* @param queue 交易队列
* @param transactions 交易商品数组
*/
– (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions NS_AVAILABLE_IOS(3_0) {
//SKPaymentTransactionStatePurchasing, 正在支付
//SKPaymentTransactionStatePurchased, 支付成功
//SKPaymentTransactionStateFailed, 支付失败
//SKPaymentTransactionStateRestored, 恢复购买
//SKPaymentTransactionStateDeferred 延迟购买
[transactions enumerateObjectsUsingBlock:^(SKPaymentTransaction * _Nonnull transaction, NSUInteger idx, BOOL * _Nonnull stop) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchasing:
NSLog(@”正在支付”);
break;
case SKPaymentTransactionStatePurchased:
// 当支付完成时,一定要将该订单,从支付队列中移除
[queue finishTransaction:transaction];
NSLog(@”支付成功”);
break;
case SKPaymentTransactionStateFailed:
// 当支付失败时,一定要将该订单,从支付队列中移除
[queue finishTransaction:transaction];
NSLog(@”支付失败”);
break;
case SKPaymentTransactionStateRestored:
NSLog(@”恢复购买”);
// 当恢复时,一定要将该订单,从支付队列中移除
[queue finishTransaction:transaction];
break;
case SKPaymentTransactionStateDeferred:
NSLog(@”延迟购买”);
break;
default:
break;
}
}];
}
#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:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
// 1.取出模型
SKProduct *product = self.products[indexPath.row];
// 2.设置数据
cell.textLabel.text = product.localizedTitle;
cell.detailTextLabel.text = product.localizedDescription;
return cell;
}
#pragma mark – 代理
– (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// 1.取出选中的商品
SKProduct *product = self.products[indexPath.row];
// 2.根据商品开一个小票
SKPayment *payment = [SKPayment paymentWithProduct:product];
// 3.将小票添加到队列中
SKPaymentQueue *queue = [SKPaymentQueue defaultQueue];
[queue addPayment:payment];
// 4.监听交易状态
[queue addTransactionObserver:self];
}
@end