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教程的更多相关文章

  1. [[iso教程]] 《4个月ios实体教程》全网最新、最全ios视频教程

    全网最新.最全ios视频教程 内容简介 <ios实体教程>主要介绍如何使用iOS提供的强大工具集创建iOS应用.全视频对iOS操作系统做了全面的介绍,首先讲解如何构建应用程序的用户界面,涵 ...

  2. fir.im Weekly - 给女朋友的 iOS 开发教程

    俗话说:技多不压身,功到自然成.本期 fir.im Weekly 收集的热度资源,大部分关于Android.iOS 开发工具和源码,还有一些有关设计的 Tips ,希望对你有帮助. 给女朋友的 iOS ...

  3. IOS 学习教程

    IOS 学习教程http://www.gaixue.com/course/236#### 讲课http://wenku.baidu.com/view/6786064fe518964bcf847c63. ...

  4. IOS编程教程(八):在你的应用程序添加启动画面

    IOS编程教程(八):在你的应用程序添加启动画面   虽然你可能认为你需要编写闪屏的代码,苹果已经可以非常轻松地把它做在Xcode中.不需要任何编码.你只需要做的是设置一些配置. 什么是闪屏 对于那些 ...

  5. 新手必看,史上最全的iOS开发教程集锦,没有之一!

    最近大火的iPhone XS Max和iPhone XS,不知道有没有同学已经下手了呢?一万三的价位确实让很多人望而却步啊.据说为了赢得中国的用户,专门出了双卡双待的,可想而知中国市场这块“肥肉”人人 ...

  6. Unity3D for iOS初级教程:Part 2/3

    转自Unity3D for iOS 这篇文章还可以在这里找到 英语 Learn how to use Unity to make a simple 3D iOS game! 这篇教材是来自教程团队成员 ...

  7. IOS IAP APP内支付 Java服务端代码

    IOS IAP APP内支付 Java服务端代码   场景:作为后台需要为app提供服务,在ios中,app内进行支付购买时需要进行二次验证. 基础:可以参考上一篇转载的博文In-App Purcha ...

  8. ios外包公司——技术分享:IOS开发教程

        iOS入门培训,适合已经有C/C++/Java/C#基础的人学习.   本大仙主讲,总共4讲(第4讲尚在制作中),这仅仅是iOS开发的入门而已.学完本教程,应该已经足够你自学并开发app了. ...

  9. iOS CoreBluetooth 教程

    去App Store搜索并下载“LightBlue”这个App,对调试你的app和理解Core Bluetooth会很有帮助. ================================ Cor ...

随机推荐

  1. javascript删除目标标签

    <script> window.onload=function(){ var odiv=document.getElementById("content");  // ...

  2. Administration Commands

    Commands useful for administrators of a hadoop cluster. balancer Runs a cluster balancing utility. A ...

  3. 【C语言】重定向和文件

    重定向和文件 一.相关基础知识 重定向:在计算机领域,重定向是大多数命令行解释器所具有的功能,包括各种可以将标准流重定向用户规定地点的Unix shells. 输入重定向:可以使程序能够使用文件代替键 ...

  4. 简谈HashMap、HashTable的区别

    简单的说HashMap是HashTable的轻量级实现,即非线程安全的实现,他们的主要区别概述为: HashMap HashTable (1)允许键和值为null  不允许键或值为null (2)不是 ...

  5. C#事件(Event)学习日记

    event 关键字的来由,为了简化自定义方法的构建来为委托调用列表增加和删除方法. 在编译器处理 event 关键字的时候,它会自动提供注册和注销方法以及任何必要的委托类型成员变量. 这些委托成员变量 ...

  6. nutch getOutLinks 外链的处理

    转载自: http://blog.csdn.net/witsmakemen/article/details/8067530 通过跟踪发现,Fetcher获得网页解析链接没有问题,获得了网页中所有的链接 ...

  7. attr

    今天用attr的时候忽然不知道html中没有的attribute可以不可以用该方法新增了, 查了appframework的文档,居然木有看出解答. 百度之,js原生的setAttribute当然是可以 ...

  8. Python安装及开发环境配置

    Python的语法简洁,功能强大,有大量的第三方开发包(模块).同时Python不像java一样对内存要求非常高,适合做一些经常性的任务方面的编程.根据codeeval网站数据统计显示,连续三年,Py ...

  9. keil多文件组织方法

    方法一 首先新建一个main.c的文件,加入到项目中,该文件中主要写main函数,然后,新建文件,如delay.c,编写内容之后,不要加入到项目,而是在main.c文件的开始写上#include“de ...

  10. Android开源项目发现--- 工具类图片缓存篇(持续更新)

    1. Android-Universal-Image-Loader 图片缓存 目前使用最广泛的图片缓存,支持主流图片缓存的绝大多数特性. 项目地址:https://github.com/nostra1 ...