【详解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,如需转载请自行联系原作者
目录
相关文章
|
1月前
|
安全 数据安全/隐私保护 Android开发
【05】2025年1月首发完整版-篇幅较长-苹果app如何上架到app store完整流程·不借助第三方上架工具的情况下无需花钱但需仔细学习-优雅草央千澈详解关于APP签名以及分发-们最关心的一篇来了-IOS上架app
【05】2025年1月首发完整版-篇幅较长-苹果app如何上架到app store完整流程·不借助第三方上架工具的情况下无需花钱但需仔细学习-优雅草央千澈详解关于APP签名以及分发-们最关心的一篇来了-IOS上架app
222 75
|
4月前
|
移动开发 前端开发 Swift
iOS 最好的应用程序开发编程语言竟然是这7种
iOS 最好的应用程序开发编程语言竟然是这7种
158 8
|
6月前
|
测试技术 开发工具 iOS开发
iOS自动化测试方案(三):WDA+iOS自动化测试解决方案
这篇文章是iOS自动化测试方案的第三部分,介绍了在没有MacOS系统条件下,如何使用WDA(WebDriverAgent)结合Python客户端库facebook-wda和tidevice工具,在Windows系统上实现iOS应用的自动化测试,包括环境准备、问题解决和扩展应用的详细步骤。
583 1
iOS自动化测试方案(三):WDA+iOS自动化测试解决方案
|
6月前
|
测试技术 数据安全/隐私保护 iOS开发
iOS自动化测试方案(四):保姆级搭建iOS自动化开发环境
iOS自动化测试方案的第四部分,涵盖了基础环境准备、iPhone虚拟机设置、MacOS虚拟机与iPhone真机的连接,以及扩展问题和代码示例,确保读者能够顺利完成环境搭建并进行iOS自动化测试。
664 0
iOS自动化测试方案(四):保姆级搭建iOS自动化开发环境
|
6月前
|
测试技术 虚拟化 iOS开发
iOS自动化测试方案(二):Xcode开发者工具构建WDA应用到iphone
这篇文章是iOS自动化测试方案的第二部分,详细介绍了在Xcode开发者工具中构建WebDriverAgent(WDA)应用到iPhone的全过程,包括环境准备、解决构建过程中可能遇到的错误,以及最终成功安装WDA到设备的方法。
358 0
iOS自动化测试方案(二):Xcode开发者工具构建WDA应用到iphone
|
6月前
|
测试技术 开发工具 虚拟化
iOS自动化测试方案(一):MacOS虚拟机保姆级安装Xcode教程
这篇文章提供了一份保姆级的教程,指导如何在MacOS虚拟机上安装Xcode,包括环境准备、基础软件安装以及USB扩展插件的使用,以实现iOS自动化测试方案的第一步。
352 0
iOS自动化测试方案(一):MacOS虚拟机保姆级安装Xcode教程
|
6月前
|
Swift iOS开发 开发者
探索iOS开发:使用SwiftUI构建现代应用程序
【8月更文挑战第3天】在本文中,我们将一起潜入SwiftUI的世界,这是一个创新的框架,它让iOS应用的开发变得更加简单快捷。我们将通过一个实际的项目示例来展示如何利用SwiftUI的强大功能,快速搭建起一个既美观又实用的应用界面。无论你是刚入门的新手还是寻求提升的开发者,这篇文章都将为你提供宝贵的知识和技能。
79 10
|
5月前
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
199 0
|
6月前
|
测试技术 Swift iOS开发
探索iOS自动化测试:使用Swift编写UI测试
【8月更文挑战第31天】在软件开发的海洋中,自动化测试是保证船只不偏离航线的灯塔。本文将带领读者启航,深入探索iOS应用的自动化UI测试。我们将通过Swift语言,点亮代码的灯塔,照亮测试的道路。文章不仅会展示如何搭建测试环境,还会提供实用的代码示例,让理论知识在实践中生根发芽。无论你是新手还是有经验的开发者,这篇文章都将是你技能提升之旅的宝贵指南。
|
7月前
|
iOS开发 开发者 UED
探索iOS开发中的SwiftUI框架:构建现代应用程序的桥梁
本文深入探讨了SwiftUI框架在iOS开发中的应用,揭示了其对提升开发效率和改善用户体验的重要性。通过分析SwiftUI的设计哲学、核心组件以及与旧有开发模式的比较,文章旨在为读者提供关于如何利用SwiftUI构建现代化应用程序的实用指南。

热门文章

最新文章

  • 1
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    23
  • 2
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    21
  • 3
    uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
    141
  • 4
    【05】2025年1月首发完整版-篇幅较长-苹果app如何上架到app store完整流程·不借助第三方上架工具的情况下无需花钱但需仔细学习-优雅草央千澈详解关于APP签名以及分发-们最关心的一篇来了-IOS上架app
    222
  • 5
    app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
    87
  • 6
    深入探索iOS开发中的SwiftUI框架
    143
  • 7
    ios样式开关按钮jQuery插件
    58
  • 8
    Android与iOS生态差异深度剖析:技术架构、开发体验与市场影响####
    74
  • 9
    深入探索iOS与Android操作系统的安全性差异
    102
  • 10
    安卓与iOS开发中的跨平台策略:一次编码,多平台部署
    173