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 ...
随机推荐
- 精通 Oracle+Python,第 2 部分:处理时间和日期
从 Python 2.4 版开始,cx_Oracle 自身可以处理 DATE 和 TIMESTAMP 数据类型,将这些列的值映射到 Python 的 datetime 模块的 datetime 对象中 ...
- Mvc Model 模板的获取【学习笔记】
MVC的Model模板有两种:一种编辑模式(@Html.EditorFor()).一种显示模式(Html.DisplayFor()). 模板的获取与执行(以下转自这里): 当我们调用HtmlHelpe ...
- 数据结构练习 00-自测4. Have Fun with Numbers (20)
Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, wit ...
- C++中Reference与指针(Pointer)的使用对比
整理日: 2015年3月18日 引用(reference)和指针(pointer)是学C++过程中最令人头疼的问题,常常不知道什么时候用哪个合适,又常常弄混.找到Dan Saks的这篇文章,讲的很清楚 ...
- DXP 技巧和龙芯3A装机
时间过得好快!来公司已经半个月多了!本想着每日一搏,可是一再被耽搁,到今天才写.好了,废话不说了.就把自己这些天做的事写一些.理一理吧.也希望大家监督,由于水平有限,有不正确的地方,还望指正! 刚来做 ...
- matplotlib 绘图
http://blog.csdn.net/jkhere/article/details/9324823 都打一遍 5 matplotlib-绘制精美的图表 matplotlib 是python最著名的 ...
- CTSC模拟题 树上的路径
Description 给定一棵\(N\)个结点的树,结点用正整数\(1 \dots N\)编号,每条边有一个正整数权值.用\(d(a, b)\)表示从结点\(a\)到结点\(b\)路径上经过边的权值 ...
- SQLite 中的各种限制
英文原文:Limits In SQLite 本文定义了 SQLite 的限制,如何针对这些限制定制特定的应用程序.默认的限制设置通常是适当的,几乎适合于每一个应用.有一些应用程序可能需要在 ...
- js图片预览插件,不涉及上传
小小的几十行代码,很牛逼,很实用. 支持多个图片的预览,只要new多个对象就行了. html如下 <!-- zhouxiang www.zhou-xiang.com --> <!DO ...
- 【Better Code】面向切面编程
用AOP改善JavaScript代码http://www.w3cfuns.com/thread-5597323-1-1.html