IOS,苹果内购和添加广告
内购——应用内购买
准备工作:
在Itunes 添加应用 设置 apppurese 内购的 道具
并且制定每一个道具的名称跟 产品 ID
bundleID: 唯一的
必须是真机: 要求 不能越狱
添加测试账号: (不花钱 苹果提供一个 沙盒 专门用来测试内购
注意点: 不能是苹果真的 账号
1> 内购程序的APP ID需要单独指定,因为在开发时,需要独立测试,通过苹果的网站进行交互
2> 在iTunes Connect中添加可以销售的商品
3> 中间有一个审批的过程,之后就可以在应用程序中添加
4> 注册Sandbox(使用测试服务器的)用户,同样具备苹果ID的能力
苹果官方有限定,不能用测试账号在苹果真正市场消费,一旦有消费行为,就会被禁用
5> 在应用程序信息中,填写测试账号和密码,方便审核人员测试!
开发前的注意事项:
1> 要开发内购,必须用真机
2> 真机一定不能越狱
3> BundlID 和服务器上的 App ID要一致,靠AppID来识别具体的消费
对于非消耗品,需要增加一个恢复购买的功能,提示:会一次性恢复所有的购买的非消耗品
要使用内购,需要导入StoreKit框架
内购的常用方法
// 1) 实例化产品请求
SKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:identifiers];
// 2) 设置代理
[request setDelegate:self];
// 3) 启动请求
[request start];
提示:
1. 实例化请求时,必须指定有效的identifiers集合,之所以如此处理,主要是为了确保提交的内购商品真的通过了苹果的审批,处于可用状态!
2. 要想获取到准确的可用产品集合,需要通过代理方法实现
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
3. 越狱用户无法测试内购,但是可以购买
购买产品
1. 内购的交易过程是通过SKPaymentTransactionObserver监控的,因此需要为IAPHelper添加交易观察者:
// 添加交易观察者对象
[[SKPaymentQueue defaultQueue]addTransactionObserver:sharedInstance];
2. 由于发起交易需要使用SKProduct对象,因此需要使用字典记录所有可用的商品
NSMutableDictionary*_productsDict;
交易队列回调方法
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction *transaction in transactions) {
// 购买完成
if (transaction.transactionState == SKPaymentTransactionStatePurchased) {
NSLog(@"购买完成 %@", transaction.payment.productIdentifier);
[queue finishTransaction:transaction];
} else if (transaction.transactionState == SKPaymentTransactionStateFailed) {
if (transaction.error.code != SKErrorPaymentCancelled) {
NSLog(@"交易失败: %@", transaction.error.localizedDescription);
}
}
}
}
恢复购买
[[SKPaymentQueue defaultQueue]restoreCompletedTransactions];
验证购买
#if DEBUG
#define ITMS_VERIFY_RECEIPT_URL @"https://sandbox.itunes.apple.com/verifyReceipt"
#else
#define ITMS_VERIFY_RECEIPT_URL @"https://buy.itunes.apple.com/verifyReceipt"
#endif
--------------------------------------------------------------------------------------------------------------------
完整步骤代码:
#import "ViewController.h"
#import <StoreKit/StoreKit.h>
@interface ViewController ()<SKProductsRequestDelegate,SKPaymentTransactionObserver>
//产品
@property (nonatomic,strong)NSArray *allProducts;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//1.请求可销售的商品列表
//准备自己需要销售的商品列表
NSString *path = [[NSBundle mainBundle]pathForResource:@"products.json" ofType:nil];
NSData *data = [NSData dataWithContentsOfFile:path];
NSArray *arrayList = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
NSArray *arrayIdList = [arrayList valueForKeyPath:@"productId"];
NSLog(@"%@",arrayIdList);
NSSet *set = [NSSet setWithArray:arrayIdList];
//创建一个请求对象
SKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:set];
request.delegate = self;
[request start];
//6.创建监听对象 来监听交易队列中的交易对象的交易状态
[[SKPaymentQueue defaultQueue]addTransactionObserver:self];
}
- (void)dealloc
{
//移除监听对象
[[SKPaymentQueue defaultQueue]removeTransactionObserver:self];
}
#pragma mark - SKProductsRequestDelegate
/**
* 返回可销售的商品列表
*
* @param request 请求对象
* @param response 返回数据
*/
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
for (SKProduct *product in response.products) {
NSLog(@"%@ %@ %@ %@",product.localizedTitle,product.localizedDescription,product.price,product.productIdentifier);
}
self.allProducts = response.products;
//刷新表格
[self.tableView reloadData];
}
/**
* //2.展示可销售的商品
*
* @param tableView <#tableView description#>
* @param section <#section description#>
*
* @return <#return value description#>
*/
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.allProducts.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];
}
//取模型
SKProduct *product = self.allProducts[indexPath.row];
cell.textLabel.text = product.localizedTitle;
cell.detailTextLabel.text = [NSString stringWithFormat:@"%@元",product.price];
return cell;
}
//3.点击购买
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//4.开具小票
SKProduct *pro = self.allProducts[indexPath.row];
//小票 创建一个交易
SKPayment *payment = [SKPayment paymentWithProduct:pro];
//5.创建交易对象并添加到交易队列
[[SKPaymentQueue defaultQueue]addPayment:payment];
}
#pragma mark -SKPaymentTransactionObserver
/**
* 监听到交易队列中交易状态改变的时候就会调用
*
* @param queue 队列
* @param transactions 在队列交易
*/
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
//非消耗品 才能被恢复购买
/*
SKPaymentTransactionStatePurchasing, 交易正在被添加到交易队列
SKPaymentTransactionStatePurchased, //交易已经在队列,用户已经付钱,客户端需要完成交易
SKPaymentTransactionStateFailed, //还没添加到队列中就取消或者失败了
SKPaymentTransactionStateRestored, // 交易被恢复购买,客户端需要完成交易
SKPaymentTransactionStateDeferred NS_ENUM_AVAILABLE_IOS(8_0), 交易在队列中,交易状态不确定依赖别的参数参与
*/
//7.如果交易状态购买成功 提供特殊服务
for (SKPaymentTransaction *t in transactions) {
if (t.transactionState == SKPaymentTransactionStatePurchased) {
NSLog(@"购买成功提供增值");
//结束交易完成
[[SKPaymentQueue defaultQueue]finishTransaction:t];
}else if (t.transactionState == SKPaymentTransactionStateRestored) {
NSLog(@"恢复购买成功!");
//结束交易完成
[[SKPaymentQueue defaultQueue]finishTransaction:t];
}
}
//测试账户
//huijidazhan@126.com
//密码
//Yinuohanlei001
}
/**
* 恢复 非消耗品的购买 从用户的交易记录
*
* @param sender <#sender description#>
*/
- (IBAction)retoreProduct:(UIBarButtonItem *)sender {
[[SKPaymentQueue defaultQueue]restoreCompletedTransactions];
}
@end
-------------------------------------------------------------------------------------------------------------
广告:
- (void)bannerViewDidLoadAd:(ADBannerView *)banner {
self.bannerBottomConstraint.constant = 20.0;
[UIView animateWithDuration:0.5 animations:^{
[self.view layoutIfNeeded];
}];
NSLog(@"加载广告成功");
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
NSLog(@"加载广告失败 %@", error);
---------------------------------------------------------------------------------------------------
广告完整代码
#import "ViewController.h"
#import <iAd/iAd.h>
@interface ViewController ()<ADBannerViewDelegate>
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *cons;
@end
@implementation ViewController
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
self.cons.constant = 50;
//显示完整广告条
[UIView animateWithDuration:2.0 animations:^{
[self.view layoutIfNeeded];
}];
}
- (void)viewDidLoad {
[super viewDidLoad];
//1>3 7
//2>根据用户的应用的分类 //自动推送
//广告什么时候加载完毕
}
@end
IOS,苹果内购和添加广告的更多相关文章
- ios 苹果内购订单验证 --- php实现
验证函数: function appleVerify($receipt_data,$orderId = 0) { /* * 21000 App Store不能读取你提供的JSON对象 * 21002 ...
- ios 苹果内购订单验证 --- nodejs实现
实现代码 function IosPlayVerify(data,orderid,cb) { itunesPost(data,function (error,responseData) { if (e ...
- iOS:苹果内购实践
iOS 苹果的内购 一.介绍 苹果规定,凡是虚拟的物品(例如:QQ音乐的乐币)进行交易时,都必须走苹果的内购通道,苹果要收取大约30%的抽成,所以不允许接入第三方的支付方式(微信.支付宝等),当然开发 ...
- iOS开发苹果内购的介绍与实现
1.iOS开发苹果内购的介绍 1.1 介绍 苹果规定,凡是虚拟的物品(例如:QQ音乐的乐币)进行交易时,都必须走苹果的内购通道,苹果要收取大约30%的抽成,所以不允许接入第三方的支付方式(微信.支付宝 ...
- Cocos 2d-X Lua 游戏添加苹果内购(二) OC和Lua交互代码详解
这是第二篇 Cocos 2d-X Lua 游戏添加苹果内购(一) 图文详解准备流程 这是前面的第一篇,详细的说明了怎样添加内购项目以及填写银行信息提交以及沙盒测试员的添加使用以及需要我们注意的东西,结 ...
- 苹果内购服务器验证之receipt返回多组in_app思考
最近有部分用户反映,苹果内购充值失败,经过测试总结有几个关键点出现问题 1.app购买成功苹果没有返回票据,属于票据遗漏(取决于苹果服务器的响应状况),只能客户端进行监听刷新等处理 2.app连续购买 ...
- ios IAP 内购验证
参考我之前的笔记 苹果内购笔记,在客户端向苹果购买成功之后,我们需要进行二次验证. 二次验证 IOS在沙箱环境下购买成功之后,向苹果进行二次验证,确认用户是否购买成功. 当应用向Apple服务器请求购 ...
- 苹果内购和 Apple Pay
作者:CC老师_MissCC链接:http://www.jianshu.com/p/e3bc47e81785來源:简书 苹果内购 1.什么是内购? 如果你购买的商品,是在本app中使用和消耗的,就一定 ...
- apicloud含有微信支付。支付宝支付和苹果内购的代码
apicloud含有微信支付.支付宝支付和苹果内购的代码 <!DOCTYPE html> <html> <head> <meta charset=" ...
随机推荐
- 在Servlet中出现一个输出中文乱码的问题
添加:reqeust.setCharacterEncoding("utf-8");
- 【BZOJ1101】Zap [莫比乌斯反演]
Zap Time Limit: 10 Sec Memory Limit: 162 MB[Submit][Status][Discuss] Description 对于给定的整数a,b和d,有多少正整 ...
- COGS2642 / Bzoj4590 [Shoi2015]自动刷题机
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 906 Solved: 321 Description 曾经发明了信号增幅仪的发明家SHTSC又公开了 ...
- [POJ1637]混合图的欧拉回路判定|网络流
混合图的欧拉回路判定 上一篇正好分别讲了有向图和无向图的欧拉回路判定方法 如果遇上了混合图要怎么做呢? 首先我们思考有向图的判定方法:所有点的出度=入度 我们可以先为无向边任意定一个向,算出此时所有顶 ...
- POJ 1062 昂贵的聘礼 (最短路 迪杰斯特拉 )
题目链接 Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请 ...
- BZOJ1037 DP
2013-11-15 21:51 原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1037 拿到这道题想到了DP,后来发现三维无法确定的表示状 ...
- C++ 头文件保护符
头文件保护符有什么作用? 在C++中我们写头文件时经常需要#include来包含其他头文件.头文件定义的实体经常使用其他头文件的内容,有时候会出现一个头文件被多次包含进同一源文件. 例如:一个头文件中 ...
- Csharp 非安全代码
using System; using System.Collections.Generic; using System.Text; namespace ConsoleApplication1 { c ...
- 1、使用Xcode修改iOS项目工程名和路径名
http://blog.sina.com.cn/s/blog_a42013280101blxo.html 对,好:错,改正. ------ 前言 系统 10.7 狮子 开发平台 xcode 4.5.2 ...
- linux C 中的volatile使用【转】
转自:http://blog.csdn.net/sukhoi27smk/article/details/38020583 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器 ...