IOS客户端内购(IAP)简单总结
来源:互联网 发布:金十数据原油点评 编辑:程序博客网 时间:2024/05/17 04:48
本文由 http://blog.csdn.net/dalehui/ 原创
需要注意的几点:
1.导入StoreKit框架
2.确保product ID惟一且与IITUNNES CONNECT中的一致
3.请确保plist文件中的Bundle identifier与ITunes Connet中的Bundle ID一致
4.虚拟机好像跑不起来
5.iTunes Connect 中product ID 的分配上限为10W个
6.内购不分区域,可以在任何地方购买,即使应用在不分区域没上架
7.越狱设备可能无法使用(我的机子就没通过,囧)
8.沙盒测试的话,请使用iTunes Connect Test User的账号
下面是个流程图
以下涉及到的分别有
(1)框架
<StoreKit/StoreKit.h>
(2)1个类和3个Delegate
Class:SKProductsRequest
Delegate:<SKPaymentTransactionObserver,SKProductsRequestDelegate,SKRequestDelegate]]]]>
下面上几段核心代码
.h中
- #import <StoreKit/StoreKit.h>
- @interface IAPUnity : NSObject<SKPaymentTransactionObserver,SKProductsRequestDelegate,SKRequestDelegate>
- @property(retain,nonatomic)NSArray* products; //产品列表
- @property(retain,nonatomic)NSSet* productIdf; //产品标记符
- @property(retain,nonatomic)SKProductsRequest* request; //用于请求相关信息
- ///获取商店信息
- -(void)requestStart;
- ///初始化
- - (id)initProductIdf:(NSSet*)productIdf;
- ///购买
- -(void)buyProduct;
- ///恢复交易
- -(void)restorer;
- @end
.m
- #import "IAPUnity.h"
- @interface IAPUnity ()
- @property(retain,nonatomic)SKProduct* product;
- @end
- @implementation IAPUnity
- - (id)initProductIdf:(NSSet*)productIdf
- {
- self = [super init];
- if (self) {
- self.productIdf=productIdf;
- [self getProducts];
- }
- return self;
- }
- -(void)getProducts
- {
- _request=[[SKProductsRequest alloc]initWithProductIdentifiers:_productIdf];
- }
- -(void)requestStart
- {
- [_request setDelegate:self];
- ///请求数据
- [_request start];
- }
- #pragma SKProductsRequestDelegate
- - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
- {
- ///判断用户是否禁用内购功能
- if ([SKPaymentQueue canMakePayments]) {
- NSLog(@"%@",response.products);
- //得到产品列表
- self.products=response.products;
- }
- ///获取成功列表成功,并且取到第0个的相关信息
- if ([response.products count]>0) {
- self.product=[response.products objectAtIndex:0];
- NSLog(@"产品本地标题:%@",[self.product localizedTitle]);
- NSLog(@"产品描述:%@",self.product.localizedDescription);
- NSLog(@"产品价格:%@",self.product.price);
- NSLog(@"产品标识:%@",self.product.productIdentifier);
- }
- ///发生错误的时候输出错误信息
- for (NSString *invalidProductId in response.invalidProductIdentifiers)
- {
- NSLog(@"Invalid product id: %@" , invalidProductId);
- }
- }
- -(void)buyProduct
- {
- if (self.product) {
- if ([SKPaymentQueue canMakePayments]) {
- SKPayment* payment=[SKPayment paymentWithProduct:self.product];
- ///为支付队列增加一个观察者
- [[SKPaymentQueue defaultQueue]addTransactionObserver:self];
- ///增加了一个观察者到付款队列中
- [[SKPaymentQueue defaultQueue]addPayment:payment];
- }
- }
- }
- -(void)restorer
- {
- [[SKPaymentQueue defaultQueue]restoreCompletedTransactions];
- }
- // Sent when the transaction array has changed (additions or state changes). Client should check state of transactions and finish as appropriate.
- - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
- {
- for (SKPaymentTransaction* transaction in transactions) {
- switch (transaction.transactionState) {
- case SKPaymentTransactionStatePurchasing:
- {
- NSLog(@"购买中");
- }
- break;
- case SKPaymentTransactionStatePurchased:
- {
- NSLog(@"SKPaymentTransactionStatePurchased");
- NSLog(@"%@",[[NSString alloc]initWithData:transaction.transactionReceipt encoding:NSUTF8StringEncoding]);
- NSString* temp=[[NSString alloc]initWithData:transaction.transactionReceipt encoding:NSUTF8StringEncoding];
- UIAlertView* alertView=[[UIAlertView alloc]initWithTitle:@"提示" message:@"内购成功" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
- [alertView show];
- NSLog(@"BASE64:%@",[self encode:temp.UTF8String length:temp.length]);
- [[SKPaymentQueue defaultQueue]finishTransaction:transaction];
- }
- break;
- case SKPaymentTransactionStateFailed:
- {
- if (transaction.error.code!=SKErrorPaymentCancelled) {
- NSLog(@"Failed....%d",transaction.error.code);
- NSLog(@"%@",transaction.error.localizedDescription);
- }
- [[SKPaymentQueue defaultQueue]finishTransaction:transaction];
- }
- break;
- case SKPaymentTransactionStateRestored:
- {
- [[SKPaymentQueue defaultQueue]finishTransaction:transaction];
- }
- break;
- default:
- break;
- }
- }
- }
- @end
之前的BASE64函数有点问题,所以删掉了,换了一个
下面是 transaction.transactionState的几种状态
- SKPaymentTransactionStatePurchasing, // 这一个是应用商店是正在处理交易的状态
- SKPaymentTransactionStatePurchased, // 这一个是应用商店成功处理付款的状态
- SKPaymentTransactionStateFailed, // 这儿是应用商店处理失败的状态
- SKPaymentTransactionStateRestored // 这个是应用商店恢复之前的状态
中间遇到的问题
(1)问题:使用SKPayment的paymentWithProductIdentifier无法连接上APP STORE导致无法进行购买(网络不好也可能出现连接不上的情况)
解决方法:改用SKPayment的paymentWithProduct方法
(2)问题:购买时,登陆成功后提示 [environment:sandbox] ,导致无法成功购买
解决方案:我在这,就是回到ITUNESCONNETION中重新Add了1个账号(美国地区的,中国的试了几个都不行),回到设备上注销掉之前的账号和关掉APP STORE,重新登陆即可
(3)问题:-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response 中 response.invalidProductIdentifiers count>0的情况。
解决方案:我换了一台非越狱设备,就正常了
苹果IAP文档:https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/13_ManagingIn-AppPurchases/ManagingIn-AppPurchases.html#//apple_ref/doc/uid/TP40011225-CH4-SW1
苹果视频(Using Store Kit for In-App Purchases):https://developer.apple.com/wwdc/videos/?id=305
0 0
- IOS客户端内购(IAP)简单总结
- IOS客户端内购(IAP)简单总结
- ios iap 内购
- iOS 应用内购(iAP)
- iOS 应用内购(iAP)
- IOS 内购iap测试问题
- iOS 内购( IAP)处理流程
- iOS --iap内购的那些小事
- IOS IAP支付总结
- IOS IAP支付总结
- iOS 应用内支付(IAP)
- ios客户端本地校验iap
- IAP 程序内购
- IAP 程序内购
- IAP内购
- 关于IAP内购
- iOS_内购IAP
- IOS开发关于内购IAP/StoreKit详解
- 编译resipro时老是SSL出错
- SpringMVC表单标签简介
- 设置Dialog窗口的大小
- 2000条你应知的WPF小姿势 基础篇<69-73 WPF Freeze机制和Template>
- Linux内存管理——伙伴系统
- IOS客户端内购(IAP)简单总结
- Ant调用java类
- java复习
- Binder与AIDL服务
- 设计模式总结(《Head First设计模式》学习总结)
- 第七周项目三之求三个正整数中的差值
- Ffmpeg结构体——AVFormatContext
- 如何反编译android的apk文件得到资源文件
- Git系列之操作标签