iOS IAP教程
1. 创建应用

首先进入iTunes Connect然后按下 Manage Your Applications

接下来按下Add New Applicationbutton创建应用
2. 在应用中创建IAP

创建应用之后,在Manage Your Applications中点应用的图示,进入应用
就会看到上图画面点击Manage In App Purchases就能够进入IAP的管理画面
在这边要注意左边的Bundle ID,在Xcode项目中,info.plist中的设定需与此Bundle同样
(此Bundle ID会在创建应用时填入)

此为IAP的管理画面,仅仅要按下Create Newbutton就可创建IAP
在本图中我已经创建好三个IAP
而当中要注意的是Product ID,仅仅要用Product ID就能够请求IAP的相关讯息及交易
Consumable
消耗品,每次下载都需付费
Non-Consumable
一次性付费,通经常使用在升级pro版或是移除广告等
Auto-Renewable Subscriptions
自己主动更新订阅
Free Subscription
免费订阅
Non-Renewing Subscription
非自己主动更新订阅
3. 怎样创建沙盒測试用户

进入iTunes Connect,点击Manage Users

在这个画面中点下Test User

按下Add New User就能够了,Email Address就是登入沙盒測试的username
password的部份在Add New User时可自行创建
4.代码
/*
* CBiOSStoreManager.h
* CloudBox Cross-Platform Framework Project
*
* Created by Cloud on 2012/10/30.
* Copyright 2011 Cloud Hsu. All rights reserved.
*
*/ #import <UIKit/UIKit.h>
#import <StoreKit/StoreKit.h> @interface CBiOSStoreManager : NSObject<SKProductsRequestDelegate,SKPaymentTransactionObserver>
{
NSString* _buyProductIDTag;
} + (CBiOSStoreManager*) sharedInstance; - (void) buy:(NSString*)buyProductIDTag;
- (bool) CanMakePay;
- (void) initialStore;
- (void) releaseStore;
- (void) requestProductData:(NSString*)buyProductIDTag;
- (void) provideContent:(NSString *)product;
- (void) recordTransaction:(NSString *)product; - (void) requestProUpgradeProductData:(NSString*)buyProductIDTag;
- (void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions;
- (void) purchasedTransaction: (SKPaymentTransaction *)transaction;
- (void) completeTransaction: (SKPaymentTransaction *)transaction;
- (void) failedTransaction: (SKPaymentTransaction *)transaction;
- (void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentTransaction *)transaction;
- (void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error;
- (void) restoreTransaction: (SKPaymentTransaction *)transaction; @end
/*
* CBiOSStoreManager.mm
* CloudBox Cross-Platform Framework Project
*
* Created by Cloud on 2012/10/30.
* Copyright 2011 Cloud Hsu. All rights reserved.
*
*/ #import "CBiOSStoreManager.h" @implementation CBiOSStoreManager static CBiOSStoreManager* _sharedInstance = nil; +(CBiOSStoreManager*)sharedInstance
{
@synchronized([CBiOSStoreManager class])
{
if (!_sharedInstance)
[[self alloc] init]; return _sharedInstance;
}
return nil;
} +(id)alloc
{
@synchronized([CBiOSStoreManager class])
{
NSAssert(_sharedInstance == nil, @"Attempted to allocate a second instance of a singleton.\n");
_sharedInstance = [super alloc];
return _sharedInstance;
}
return nil;
} -(id)init {
self = [super init];
if (self != nil) {
// initialize stuff here
}
return self;
} -(void)initialStore
{
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
-(void)releaseStore
{
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
} -(void)buy:(NSString*)buyProductIDTag
{
[self requestProductData:buyProductIDTag];
} -(bool)CanMakePay
{
return [SKPaymentQueue canMakePayments];
} -(void)requestProductData:(NSString*)buyProductIDTag
{
NSLog(@"---------Request product information------------\n");
_buyProductIDTag = [buyProductIDTag retain];
NSArray *product = [[NSArray alloc] initWithObjects:buyProductIDTag,nil];
NSSet *nsset = [NSSet setWithArray:product];
SKProductsRequest *request=[[SKProductsRequest alloc] initWithProductIdentifiers: nsset];
request.delegate=self;
[request start];
[product release];
} - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{ NSLog(@"-----------Getting product information--------------\n");
NSArray *myProduct = response.products;
NSLog(@"Product ID:%@\n",response.invalidProductIdentifiers);
NSLog(@"Product count: %d\n", [myProduct count]);
// populate UI
for(SKProduct *product in myProduct){
NSLog(@"Detail product info\n");
NSLog(@"SKProduct description: %@\n", [product description]);
NSLog(@"Product localized title: %@\n" , product.localizedTitle);
NSLog(@"Product localized descitption: %@\n" , product.localizedDescription);
NSLog(@"Product price: %@\n" , product.price);
NSLog(@"Product identifier: %@\n" , product.productIdentifier);
}
SKPayment *payment = nil;
payment = [SKPayment paymentWithProduct:[response.products objectAtIndex:0]];
NSLog(@"---------Request payment------------\n");
[[SKPaymentQueue defaultQueue] addPayment:payment];
[request autorelease]; }
- (void)requestProUpgradeProductData:(NSString*)buyProductIDTag
{
NSLog(@"------Request to upgrade product data---------\n");
NSSet *productIdentifiers = [NSSet setWithObject:buyProductIDTag];
SKProductsRequest* productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
productsRequest.delegate = self;
[productsRequest start]; } - (void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
NSLog(@"-------Show fail message----------\n");
UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Alert",NULL) message:[error localizedDescription]
delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil];
[alerView show];
[alerView release];
} -(void) requestDidFinish:(SKRequest *)request
{
NSLog(@"----------Request finished--------------\n"); } -(void) purchasedTransaction: (SKPaymentTransaction *)transaction
{
NSLog(@"-----Purchased Transaction----\n");
NSArray *transactions =[[NSArray alloc] initWithObjects:transaction, nil];
[self paymentQueue:[SKPaymentQueue defaultQueue] updatedTransactions:transactions];
[transactions release];
} - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
NSLog(@"-----Payment result--------\n");
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
NSLog(@"-----Transaction purchased--------\n");
UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:@"Congratulation"
message:@"Transaction suceed!"
delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil]; [alerView show];
[alerView release];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
NSLog(@"-----Transaction Failed--------\n");
UIAlertView *alerView2 = [[UIAlertView alloc] initWithTitle:@"Failed"
message:@"Sorry, your transcation failed, try again."
delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil]; [alerView2 show];
[alerView2 release];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
NSLog(@"----- Already buy this product--------\n");
case SKPaymentTransactionStatePurchasing:
NSLog(@"-----Transcation puchasing--------\n");
break;
default:
break;
}
}
} - (void) completeTransaction: (SKPaymentTransaction *)transaction
{
NSLog(@"-----completeTransaction--------\n");
// Your application should implement these two methods.
NSString *product = transaction.payment.productIdentifier;
if ([product length] > 0) { NSArray *tt = [product componentsSeparatedByString:@"."];
NSString *bookid = [tt lastObject];
if ([bookid length] > 0) {
[self recordTransaction:bookid];
[self provideContent:bookid];
}
} // Remove the transaction from the payment queue.
[[SKPaymentQueue defaultQueue] finishTransaction: transaction]; } -(void)recordTransaction:(NSString *)product
{
NSLog(@"-----Record transcation--------\n");
// Todo: Maybe you want to save transaction result into plist.
} -(void)provideContent:(NSString *)product
{
NSLog(@"-----Download product content--------\n");
} - (void) failedTransaction: (SKPaymentTransaction *)transaction
{
NSLog(@"Failed\n");
if (transaction.error.code != SKErrorPaymentCancelled)
{
}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
-(void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentTransaction *)transaction
{ } - (void) restoreTransaction: (SKPaymentTransaction *)transaction
{
NSLog(@"-----Restore transaction--------\n");
} -(void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error
{
NSLog(@"-------Payment Queue----\n");
} #pragma mark connection delegate
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"%@\n", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{ } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
switch([(NSHTTPURLResponse *)response statusCode]) {
case 200:
case 206:
break;
case 304:
break;
case 400:
break;
case 404:
break;
case 416:
break;
case 403:
break;
case 401:
case 500:
break;
default:
break;
}
} - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"test\n");
} -(void)dealloc
{
[super dealloc];
} @end
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
因为交易是永久有效的,建议addTransactionObserver这个于应用启动后即可监听,而不要在用户想买东西时才监听
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
交易结果会于此处显示

苹果准备沙盒測试环境需一段时间,若是创建IAP后能够取得资讯,却无法交易成功,要稍待一下
另外若是模拟器能够购买,但真机购买却失败的话,做Hard Reset就能够了,一直按住Home键跟电源键就能够做Hard Reset
按住后会出现关机画面,不要理会它,继续等,直到等到白苹果出现后,就能够放开等它重开机完成后再測试
5. IAP运作流程图


6.范例下载
iOS IAP教程的更多相关文章
- [[iso教程]] 《4个月ios实体教程》全网最新、最全ios视频教程
全网最新.最全ios视频教程 内容简介 <ios实体教程>主要介绍如何使用iOS提供的强大工具集创建iOS应用.全视频对iOS操作系统做了全面的介绍,首先讲解如何构建应用程序的用户界面,涵 ...
- fir.im Weekly - 给女朋友的 iOS 开发教程
俗话说:技多不压身,功到自然成.本期 fir.im Weekly 收集的热度资源,大部分关于Android.iOS 开发工具和源码,还有一些有关设计的 Tips ,希望对你有帮助. 给女朋友的 iOS ...
- IOS 学习教程
IOS 学习教程http://www.gaixue.com/course/236#### 讲课http://wenku.baidu.com/view/6786064fe518964bcf847c63. ...
- IOS编程教程(八):在你的应用程序添加启动画面
IOS编程教程(八):在你的应用程序添加启动画面 虽然你可能认为你需要编写闪屏的代码,苹果已经可以非常轻松地把它做在Xcode中.不需要任何编码.你只需要做的是设置一些配置. 什么是闪屏 对于那些 ...
- 新手必看,史上最全的iOS开发教程集锦,没有之一!
最近大火的iPhone XS Max和iPhone XS,不知道有没有同学已经下手了呢?一万三的价位确实让很多人望而却步啊.据说为了赢得中国的用户,专门出了双卡双待的,可想而知中国市场这块“肥肉”人人 ...
- Unity3D for iOS初级教程:Part 2/3
转自Unity3D for iOS 这篇文章还可以在这里找到 英语 Learn how to use Unity to make a simple 3D iOS game! 这篇教材是来自教程团队成员 ...
- IOS IAP APP内支付 Java服务端代码
IOS IAP APP内支付 Java服务端代码 场景:作为后台需要为app提供服务,在ios中,app内进行支付购买时需要进行二次验证. 基础:可以参考上一篇转载的博文In-App Purcha ...
- ios外包公司——技术分享:IOS开发教程
iOS入门培训,适合已经有C/C++/Java/C#基础的人学习. 本大仙主讲,总共4讲(第4讲尚在制作中),这仅仅是iOS开发的入门而已.学完本教程,应该已经足够你自学并开发app了. ...
- iOS CoreBluetooth 教程
去App Store搜索并下载“LightBlue”这个App,对调试你的app和理解Core Bluetooth会很有帮助. ================================ Cor ...
随机推荐
- ASP.Net Web 点击链接直接下载 不在浏览器打开
目标是:用户点击链接直接弹出下载框,不在浏览器打开文件. 一般网站下载的功能,本以为直接把虚拟路径赋值给链接就行了,没想到测试的时候发现图片,文本和PDF格式的文件都自动在Firefox里面打开了,没 ...
- sourceInsight的技巧
在用sourceInsight看代码...在这里积累技巧,慢慢积累吧 1.如何高亮显示所有要搜的东西,例如 1.aaaaaa 2. bbbbbbbbaaaaaaa 3. ccccccc 4. aaaa ...
- NorFlash
一.NorFlash概述 1.NorFlash Intel于1988年首先开发出NOR Flash 技术,彻底改变了原先由EPROM(Erasable Programmable Read-Only-M ...
- 常见HTTP状态码大全
我们经常会遇到404.500.302等提示,它们究竟是什么意思呢?除了这几个常见的状态码外,还有哪些我们没有遇到过的但有可能出现的状态码呢?网站的http状态对于网站维护人员来说是相当重要的,当网站出 ...
- 从UI Automation看Windows平台自动化测试原理
前言 楼主在2013年初研究Android自动化测试的时候,就分享了几篇文章 Android ViewTree and DecorView Android自动化追本溯源系列(1): 获取页面元素 An ...
- Python处理XML
在Python(以及其他编程语言)内有两种常见的方法处理XML:SAX(Simple API for XML)和DOM(Document Object Model,文档对象模型).SAX语法分析器读取 ...
- Kernel Bypass & Offload 介绍
系统网络优化可以有两方面的工作可以做:1 绕开内核(bypass):2 用硬件替代软件(offload). 具体包括: 1. 绕开内核: 不使用内核内核子系统的功能,采用自己实现的相同功能的代码来处理 ...
- Test for open live write
this is test document. this is test document. this is test document. this is test document. this is ...
- js将数字转换成大写的人民币表达式
function changeNumMoneyToChinese(money) { var cnNums = new Array("零", "壹", " ...
- uva 10130 SuperSale
一个01背包问题: 刚刚开始把题目看错了,以为物品的数目是有限的,然后让你求一个家庭里最多能够拿多个价值的东西: 这样一来的话,这个题目就有点意思了: 但是后来发现竟然是个简单的01背包问题 = = ...