【详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程!】【二】

简介:

 第二步:申请测试账号,利用沙盒测试模拟AppStore购买道具流程!

  回到itunesconnect主页中,选择“Manage Users”然后选择“Test User”,然后出现的界面如下图: 

 

 这里Himi已经创建了两个测试账号了,点击界面中的 “Add New User”进行创建即可;记住账号和密码哈,记不住就删掉重新建 娃哈哈~(切记:不能用于真正的AppStore中使用此账号,不仅不能用,而且一旦AppStore发现后果你懂得~) 


   第三步:在项目中申请购买产品代码以及监听;

         这里关于购买的代码部分呢,我都有备注的,Himi这里就不详细讲解了,Himi只是在代码后介绍几点值得注意的地方:

 

 这里Himi是新建的一个Cocos2d的项目,然后给出HelloWorldLayer.h以及HelloWorldLayer.m的全部代码,所有购买代码也全在里面也对应有Himi的注释!

          HelloWorldLayer.h

 

 
 
  1. //   
  2. //  HelloWorldLayer.h   
  3. //  buytest   
  4. //   
  5. //  Created by 华明 李 on 11-10-29.   
  6. //  Copyright Himi 2011年. All rights reserved.   
  7. //   
  8.    
  9.    
  10. // When you import this file, you import all the cocos2d classes   
  11. #import "cocos2d.h"   
  12. #import <UIKit/UIKit.h>   
  13.    
  14. #import <StoreKit/StoreKit.h>   
  15. enum{   
  16.      IAP0p99=10,   
  17.      IAP1p99,   
  18.      IAP4p99,   
  19.      IAP9p99,    
  20.      IAP24p99,   
  21. }buyCoinsTag;    
  22.    
  23. @interface HelloWorldLayer : CCLayer<SKProductsRequestDelegate,SKPaymentTransactionObserver>   
  24. {   
  25.     int buyType;   
  26. }   
  27.    
  28. +(CCScene *) scene;     
  29. - (void) requestProUpgradeProductData;   
  30. -(void)RequestProductData;   
  31. -(bool)CanMakePay;                                
  32. -(void)buy:(int)type;    
  33. - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions;   
  34. -(void) PurchasedTransaction: (SKPaymentTransaction *)transaction;   
  35. - (void) completeTransaction: (SKPaymentTransaction *)transaction;   
  36. - (void) failedTransaction: (SKPaymentTransaction *)transaction;   
  37. -(void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentTransaction *)transaction;   
  38. -(void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error;   
  39. - (void) restoreTransaction: (SKPaymentTransaction *)transaction;   
  40. -(void)provideContent:(NSString *)product;   
  41. -(void)recordTransaction:(NSString *)product;   
  42. @end   

 

 HelloWorldLayer.m

 

 
 
  1. //   
  2. //  IapLayer.m   
  3. //   
  4. //  Created by Himi on 11-5-25.   
  5. //  Copyright 2011年 李华明 . All rights reserved.   
  6. //   
  7.    
  8. #import "HelloWorldLayer.h"    
  9. #define ProductID_IAP0p99 @"com.buytest.one"//$0.99     
  10. #define ProductID_IAP1p99 @"com.buytest.two" //$1.99    
  11. #define ProductID_IAP4p99 @"com.buytest.three" //$4.99     
  12. #define ProductID_IAP9p99 @"com.buytest.four" //$19.99     
  13. #define ProductID_IAP24p99 @"com.buytest.five" //$24.99     
  14.    
  15. @implementation HelloWorldLayer   
  16. +(CCScene *) scene   
  17. {   
  18.     CCScene *scene = [CCScene node];   
  19.     HelloWorldLayer *layer = [HelloWorldLayer node];   
  20.     [scene addChild: layer];   
  21.     return scene;   
  22. }   
  23. -(id)init   
  24. {   
  25.     if ((self = [super init])) {   
  26.         CGSize size = [[CCDirector sharedDirector] winSize];   
  27.         CCSprite *iap_bg  = [CCSprite spriteWithFile:@"Icon.png"];     
  28.         [iap_bg setPosition:ccp(size.width/2,size.height/2)];   
  29.         [self addChild:iap_bg z:0];   
  30.         //---------------------   
  31.         //----监听购买结果   
  32.         [[SKPaymentQueue defaultQueue] addTransactionObserver:self];   
  33.         //申请购买   
  34.         /*  
  35.          enum{  
  36.          IAP0p99=10,  
  37.          IAP1p99,  
  38.          IAP4p99,  
  39.          IAP9p99,  
  40.          IAP24p99,  
  41.          }buyCoinsTag;  
  42.          */   
  43.         [self buy:IAP24p99];   
  44.     }   
  45.     return self;   
  46. }   
  47.    
  48. -(void)buy:(int)type   
  49. {    
  50.     buyType = type;     
  51.     if ([SKPaymentQueue canMakePayments]) {   
  52.         //[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];   
  53.         [self RequestProductData];     
  54.         CCLOG(@"允许程序内付费购买");   
  55.     }   
  56.     else   
  57.     {   
  58.         CCLOG(@"不允许程序内付费购买");    
  59.         UIAlertView *alerView =  [[UIAlertView alloc] initWithTitle:@"Alert"    
  60.                                                             message:@"You can‘t purchase in app store(Himi说你没允许应用程序内购买)"                                                           
  61.                                                            delegate:nil cancelButtonTitle:NSLocalizedString(@"Close(关闭)",nil) otherButtonTitles:nil];   
  62.            
  63.         [alerView show];   
  64.         [alerView release];   
  65.            
  66.     }    
  67. }   
  68.     
  69. -(bool)CanMakePay   
  70. {   
  71.     return [SKPaymentQueue canMakePayments];   
  72. }   
  73.    
  74. -(void)RequestProductData   
  75. {   
  76.     CCLOG(@"---------请求对应的产品信息------------");   
  77.     NSArray *product = nil;   
  78.     switch (buyType) {   
  79.         case IAP0p99:   
  80.             product=[[NSArray alloc] initWithObjects:ProductID_IAP0p99,nil];   
  81.             break;   
  82.         case IAP1p99:   
  83.             product=[[NSArray alloc] initWithObjects:ProductID_IAP1p99,nil];   
  84.             break;   
  85.         case IAP4p99:   
  86.             product=[[NSArray alloc] initWithObjects:ProductID_IAP4p99,nil];   
  87.             break;   
  88.         case IAP9p99:   
  89.             product=[[NSArray alloc] initWithObjects:ProductID_IAP9p99,nil];   
  90.             break;   
  91.         case IAP24p99:   
  92.             product=[[NSArray alloc] initWithObjects:ProductID_IAP24p99,nil];   
  93.             break;   
  94.                
  95.         default:   
  96.             break;   
  97.     }   
  98.     NSSet *nsset = [NSSet setWithArray:product];   
  99.     SKProductsRequest *request=[[SKProductsRequest alloc] initWithProductIdentifiers: nsset];   
  100.     request.delegate=self;   
  101.     [request start];   
  102.     [product release];   
  103. }   
  104. //<SKProductsRequestDelegate> 请求协议   
  105. //收到的产品信息   
  106. - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{   
  107.        
  108.     NSLog(@"-----------收到产品反馈信息--------------");   
  109.     NSArray *myProduct = response.products;   
  110.     NSLog(@"产品Product ID:%@",response.invalidProductIdentifiers);   
  111.     NSLog(@"产品付费数量: %d", [myProduct count]);   
  112.     // populate UI    
  113.     for(SKProduct *product in myProduct){   
  114.         NSLog(@"product info");   
  115.         NSLog(@"SKProduct 描述信息%@", [product description]);      
  116.         NSLog(@"产品标题 %@" , product.localizedTitle);   
  117.         NSLog(@"产品描述信息: %@" , product.localizedDescription);   
  118.         NSLog(@"价格: %@" , product.price);   
  119.         NSLog(@"Product id: %@" , product.productIdentifier);    
  120.     }    
  121.     SKPayment *payment = nil;    
  122.     switch (buyType) {   
  123.         case IAP0p99:   
  124.             payment  = [SKPayment paymentWithProductIdentifier:ProductID_IAP0p99];    //支付$0.99   
  125.             break;   
  126.         case IAP1p99:   
  127.             payment  = [SKPayment paymentWithProductIdentifier:ProductID_IAP1p99];    //支付$1.99   
  128.             break;   
  129.         case IAP4p99:   
  130.             payment  = [SKPayment paymentWithProductIdentifier:ProductID_IAP4p99];    //支付$9.99   
  131.             break;   
  132.         case IAP9p99:   
  133.             payment  = [SKPayment paymentWithProductIdentifier:ProductID_IAP9p99];    //支付$19.99   
  134.             break;   
  135.         case IAP24p99:   
  136.             payment  = [SKPayment paymentWithProductIdentifier:ProductID_IAP24p99];    //支付$29.99   
  137.             break;   
  138.         default:   
  139.             break;   
  140.     }   
  141.     CCLOG(@"---------发送购买请求------------");   
  142.     [[SKPaymentQueue defaultQueue] addPayment:payment];     
  143.     [request autorelease];    
  144.        
  145. }   
  146. - (void)requestProUpgradeProductData   
  147. {   
  148.     CCLOG(@"------请求升级数据---------");   
  149.     NSSet *productIdentifiers = [NSSet setWithObject:@"com.productid"];   
  150.     SKProductsRequest* productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];   
  151.     productsRequest.delegate = self;   
  152.     [productsRequest start];    
  153.        
  154. }   
  155. //弹出错误信息   
  156. - (void)request:(SKRequest *)request didFailWithError:(NSError *)error{   
  157.     CCLOG(@"-------弹出错误信息----------");   
  158.     UIAlertView *alerView =  [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Alert",NULL) message:[error localizedDescription]   
  159.                                                        delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil];   
  160.     [alerView show];   
  161.     [alerView release];   
  162. }   
  163.    
  164. -(void) requestDidFinish:(SKRequest *)request    
  165. {   
  166.     NSLog(@"----------反馈信息结束--------------");   
  167.        
  168. }   
  169.     
  170. -(void) PurchasedTransaction: (SKPaymentTransaction *)transaction{   
  171.     CCLOG(@"-----PurchasedTransaction----");   
  172.     NSArray *transactions =[[NSArray alloc] initWithObjects:transaction, nil];   
  173.     [self paymentQueue:[SKPaymentQueue defaultQueue] updatedTransactions:transactions];   
  174.     [transactions release];   
  175. }    
  176.    
  177. //<SKPaymentTransactionObserver> 千万不要忘记绑定,代码如下:   
  178. //----监听购买结果   
  179. //[[SKPaymentQueue defaultQueue] addTransactionObserver:self];   
  180.    
  181. - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions//交易结果   
  182. {   
  183.     CCLOG(@"-----paymentQueue--------");   
  184.     for (SKPaymentTransaction *transaction in transactions)   
  185.     {   
  186.         switch (transaction.transactionState)   
  187.         {    
  188.             case SKPaymentTransactionStatePurchased://交易完成    
  189.                 [self completeTransaction:transaction];   
  190.                 CCLOG(@"-----交易完成 --------");   
  191.                 CCLOG(@"不允许程序内付费购买");    
  192.                 UIAlertView *alerView =  [[UIAlertView alloc] initWithTitle:@"Alert"    
  193.                                                                     message:@"Himi说你购买成功啦~娃哈哈"                                                         
  194.                                                                    delegate:nil cancelButtonTitle:NSLocalizedString(@"Close(关闭)",nil) otherButtonTitles:nil];   
  195.                    
  196.                 [alerView show];   
  197.                 [alerView release];    
  198.                 break;    
  199.             case SKPaymentTransactionStateFailed://交易失败    
  200.                 [self failedTransaction:transaction];   
  201.                  CCLOG(@"-----交易失败 --------");   
  202.                 UIAlertView *alerView2 =  [[UIAlertView alloc] initWithTitle:@"Alert"    
  203.                                                                     message:@"Himi说你购买失败,请重新尝试购买~"                                                         
  204.                                                                    delegate:nil cancelButtonTitle:NSLocalizedString(@"Close(关闭)",nil) otherButtonTitles:nil];   
  205.                    
  206.                 [alerView2 show];   
  207.                 [alerView2 release];   
  208.                 break;    
  209.             case SKPaymentTransactionStateRestored://已经购买过该商品    
  210.                 [self restoreTransaction:transaction];   
  211.                  CCLOG(@"-----已经购买过该商品 --------");   
  212.             case SKPaymentTransactionStatePurchasing:      //商品添加进列表   
  213.                  CCLOG(@"-----商品添加进列表 --------");   
  214.                 break;   
  215.             default:   
  216.                 break;   
  217.         }   
  218.     }   
  219. }   
  220. - (void) completeTransaction: (SKPaymentTransaction *)transaction   
  221.    
  222. {   
  223.     CCLOG(@"-----completeTransaction--------");   
  224.     // Your application should implement these two methods.   
  225.     NSString *product = transaction.payment.productIdentifier;   
  226.     if ([product length] > 0) {   
  227.            
  228.         NSArray *tt = [product componentsSeparatedByString:@"."];   
  229.         NSString *bookid = [tt lastObject];   
  230.         if ([bookid length] > 0) {   
  231.             [self recordTransaction:bookid];   
  232.             [self provideContent:bookid];   
  233.         }   
  234.     }   
  235.        
  236.     // Remove the transaction from the payment queue.   
  237.        
  238.     [[SKPaymentQueue defaultQueue] finishTransaction: transaction];   
  239.        
  240. }   
  241.    
  242. //记录交易   
  243. -(void)recordTransaction:(NSString *)product{   
  244.     CCLOG(@"-----记录交易--------");   
  245. }   
  246.    
  247. //处理下载内容   
  248. -(void)provideContent:(NSString *)product{   
  249.     CCLOG(@"-----下载--------");    
  250. }   
  251.    
  252. - (void) failedTransaction: (SKPaymentTransaction *)transaction{   
  253.     NSLog(@"失败");   
  254.     if (transaction.error.code != SKErrorPaymentCancelled)   
  255.     {   
  256.     }   
  257.     [[SKPaymentQueue defaultQueue] finishTransaction: transaction];   
  258.        
  259.        
  260. }   
  261. -(void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentTransaction *)transaction{   
  262.        
  263. }   
  264.    
  265. - (void) restoreTransaction: (SKPaymentTransaction *)transaction   
  266.    
  267. {   
  268.     NSLog(@" 交易恢复处理");   
  269.        
  270. }   
  271.    
  272. -(void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error{   
  273.     CCLOG(@"-------paymentQueue----");   
  274. }   
  275.    
  276.    
  277. #pragma mark connection delegate   
  278. - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data   
  279. {   
  280.     NSLog(@"%@",  [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]);    
  281. }   
  282. - (void)connectionDidFinishLoading:(NSURLConnection *)connection{   
  283.        
  284. }   
  285.    
  286. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{   
  287.     switch([(NSHTTPURLResponse *)response statusCode]) {   
  288.         case 200:   
  289.         case 206:   
  290.             break;   
  291.         case 304:    
  292.             break;   
  293.         case 400:    
  294.             break;     
  295.         case 404:   
  296.             break;   
  297.         case 416:   
  298.             break;   
  299.         case 403:   
  300.             break;   
  301.         case 401:   
  302.         case 500:   
  303.             break;   
  304.         default:   
  305.             break;   
  306.     }           
  307. }   
  308.    
  309. - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {   
  310.     NSLog(@"test");   
  311. }   
  312.    
  313. -(void)dealloc   
  314. {   
  315.     [super dealloc];   
  316. }    
  317. @end   

 

代码注释的相当清楚了,没有什么可解释的,这里说几点值得注意的地方:

1.添加对应对应代码时不要忘记,添加框架 StoreKit.framework,如何添加框架请看我的博文【iOS-Cocos2d游戏开发之十四】音频/音效/视频播放(利用Cocos2D-iPhone-Extensions嵌入Cocos2d进行视频播放!)

2. 越狱机器无法沙盒测试!模拟器的话,Himi用4.3模拟器不可以,因为提示没有开启程序内付费- -(我都没看到模拟器有store的选项,so~);但是使用iOS5的模拟器可以测试沙盒,但是执行的顺序会有些问题,但是还没真机的童鞋可以使用,建议一切以真机实测为准

3. 千万不要忘记在iTunesConnect中创建App Bundle ID一定要跟你的项目中的info.plist中的Bundle ID保证一致!!!!

4. 以上代码中你需要修改的就是我在HelloWorldLayer.m类中的宏定义的Product ID(产品ID),例如Himi刚才新建了一个产品ID是“com.himi.wahaha"


然后我运行项目截图如下以及运行控制台打印的信息如下:

 

 

点击Buy之后运行截图以及打印信息:

 

输入测试账号密码后以及打印信息:

 

 

      害羞这里Himi最后一张截图是没有购买成功,这里Himi是故意截图出来的,原因就是想告诉童鞋们:

 如果你的产品信息能够正常得到,但是始终无法成功的话,不要着急,因为你的产品要进入iTunes Connect,并且Apple准备好沙箱环境需要一些时间。Himi之前遇到过,然后在一天后我没有修改任何一行代码,但产品ID变为有效并能成功购买。=。 =郁闷ing~~  起始要使产品发布到Apple的网络系统是需要一段时间的!

 

    好了,写了这么多了,咳咳、Himi继续忙了,做iOS的童鞋们我想此篇将成为你必须收藏的一篇哦~嘿嘿!





本文转自 xiaominghimi 51CTO博客,原文链接:http://blog.51cto.com/xiaominghimi/706419,如需转载请自行联系原作者
目录
相关文章
|
27天前
|
SQL 安全 测试技术
【软件设计师备考 专题 】测试要求说明书的编写和应用
【软件设计师备考 专题 】测试要求说明书的编写和应用
55 0
|
1月前
|
弹性计算 监控 测试技术
弹性计算的测试流程
弹性计算的测试流程
18 0
|
1月前
|
安全 测试技术
现代软件测试中的自动化技术应用及挑战
在当今数字化时代,软件测试的重要性日益凸显。本文探讨了现代软件测试中自动化技术的应用现状和挑战,分析了自动化测试在提高效率、降低成本、增强可靠性等方面的优势,同时也提出了自动化测试所面临的挑战和解决方案。
|
1月前
|
机器学习/深度学习 数据采集 人工智能
探索AI在软件测试中的应用与挑战
【2月更文挑战第25天】 随着人工智能(AI)技术的迅猛发展,其在软件测试领域的应用逐渐深入。AI不仅改变了传统测试流程,提高了测试效率和质量,也引入了新的挑战。本文将详细探讨AI在软件测试中的具体应用,包括智能化测试用例生成、缺陷预测、自动化测试执行等,并分析当前面临的主要挑战,如数据质量、模型泛化能力和工具集成等问题。通过实例分析和研究展望,本文旨在为软件测试专业人士提供一个关于AI技术融合的全面视角。
|
1月前
|
机器学习/深度学习 数据采集 人工智能
探索AI在软件测试中的应用和优势
【2月更文挑战第22天】 随着科技的不断发展,人工智能(AI)在各个领域的应用越来越广泛。本文主要探讨了AI在软件测试领域的应用及其带来的优势。文章首先介绍了AI技术的基本概念,然后详细分析了AI在软件测试中的具体应用,包括自动化测试、智能缺陷检测和预测等方面。最后,文章总结了AI在软件测试领域的优势,如提高测试效率、降低人力成本、提高测试质量等,并展望了AI在软件测试领域的未来发展趋势。
|
22天前
|
Web App开发 Java 测试技术
深入理解与应用软件自动化测试工具Selenium
随着软件开发的快速发展,软件测试在保证产品质量方面发挥着越来越重要的作用。其中,自动化测试以其效率高、成本低的特点受到了广大开发者的欢迎。本文主要介绍了自动化测试工具Selenium的基本概念、原理以及在实际开发中的应用,旨在帮助读者更好地理解和使用Selenium进行高效的自动化测试。
22 4
|
28天前
|
设计模式 敏捷开发 监控
深入理解与应用软件自动化测试框架
在快速迭代的软件开发过程中,自动化测试已成为确保产品质量和加快交付速度的关键因素。本文将详细探讨自动化测试框架的核心原理、设计模式及其在实际项目中的应用。我们将分析几种流行的自动化测试工具,如Selenium、Appium和JUnit,并讨论它们如何集成以形成强大的测试解决方案。文章还将展示通过自定义框架来满足特定测试需求的实例,以及如何通过持续集成和持续部署(CI/CD)流程优化测试实践。
|
29天前
|
安全 数据安全/隐私保护 虚拟化
iOS应用加固方案解析:ipa加固安全技术全面评测
iOS应用加固方案解析:ipa加固安全技术全面评测
36 3
|
1月前
|
缓存 运维 Serverless
应用研发平台EMAS产品常见问题之测试检查更新没有反应如何解决
应用研发平台EMAS(Enterprise Mobile Application Service)是阿里云提供的一个全栈移动应用开发平台,集成了应用开发、测试、部署、监控和运营服务;本合集旨在总结EMAS产品在应用开发和运维过程中的常见问题及解决方案,助力开发者和企业高效解决技术难题,加速移动应用的上线和稳定运行。
|
1月前
|
敏捷开发 供应链 测试技术
深入理解与应用软件测试中的Mock技术
【2月更文挑战第30天】 在现代软件开发过程中,单元测试是保证代码质量的重要手段。然而,对于高度依赖外部系统或服务的应用来说,传统的单元测试方法往往难以实施。Mock技术应运而生,它通过模拟外部依赖的响应,使开发者可以在隔离的环境中测试目标代码。本文将探讨Mock技术的概念、应用场景以及如何在软件测试中有效地使用Mock对象,以增强测试的灵活性和可靠性。