关于FlashBuilder4.7关于IOS打包上架AppStore

Posted 黑塞矩阵

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于FlashBuilder4.7关于IOS打包上架AppStore相关的知识,希望对你有一定的参考价值。

          网上有不少的关于ios打包的文章,不过都比较散和凌乱,有的有不少就是简单的记载。以自己的经验总结FlashBuilder4.7打包IOS并上交到AppStore。本文总共分为4大部分:(1)证书(2)FlashBuilder4.7项目针对IOS的修改部分(3)AppStore中的上架信息部分(4)FlashBuilder中的特殊内购。

                                                                                       第一部分:证书 

1.首先要一台苹果电脑和IPhone5和IPhone4手机和一个个人开发者账https://developer.apple.com/account/ios/certificate/development。

2.首先创建一个证书请求文件

2.1首先打开应用程序--->钥匙串访问,证书助理中,选择“从证书颁发机构求证书”。如下图:

2.2按要求操作之后,就出现下面界面:如图:填写你申请的用户电子邮件地址,常用名称,CA电子邮件地址,请求是:选择存储到磁盘,点击“继续”:

2.3.出现下面的保存位置,如图:(名字默认就好):

  

2.4.这样一个CSR(证书请求文件Cerificate Signing Request)就创建好了。如图:

3.开发者账号方面的证书

登录到个人开发者账号到AppleDeveloper上,操作到如下的界面

 

 

3.1授权设备(Devices)

授权设备其实就会苹果产品,从上面可以看出苹果设备有比较多,最常用的iPad和iPhone。每个苹果设备都有一个唯一的UDUD。本文以iPhone5(非越狱)进行示例。

3.1.1手机连接到苹果电脑中,打开iTunes,则如下图:拷贝UDID。

3.1.2 按下图注册设备(Devices)

 

这样你测试时的真机设备就注册号了。

3.2注册App IDs

3.2.1注册一个AppID,是唯一性的,这个就像相当于给App注册了一个身份证。

3.2.2关于AppID Suffix中Explicit App ID中的BundleID中一般是唯一性的(唯一性会为我们省好多的麻烦)。其一般组成为com.公司名字.项目名字.有意义的字母。

3.2.3.如果BundleID中带有*,那么它会对很多App有效,当然前提你授权证书和证书时会用到它。

3.2.4.如果你的app用到了push等功能,那你的appID就需要唯一了,就是不用*。这样的话,你的app只有一个Bundle Identifier(下图注释就是基于这样的原理)。

3.2.5.按下图注册一个AppID

 

3.3证书有不少的分类,作为一个以把打包App送到AppStore上加为目的话,我个人以使用的目的分为两大类:

(1)调试和开发证书:这类证书以开发和调试为目的的证书,说白了就是用真机进行测试时用的证书。它们是:

(I)Certificates->Development(开发和调试证书文件.cer):安装在电脑上提供权限:开发人员通过设备进行真机测试。可以生成副本供多台电脑安装。

(II)Provisioning Profiles->Development(开发授权文件.mobileprovision):在装有开发证书或副本的电脑上使用,开发人员选择授权文件通过将程序安装到授权记录的设备中,即可进行真机测试。

注意:确保电脑有权限真机调试,即安装了开发证书或副本;在开发工具中程序的Bundle identifier和选中使用的授权文件的App Id要一致;连接调试的设备的UDID在选中的授权文件中有记录。

(2)发布证书:在类证书就是以打包IOS成App发布到AppStore时用的证书,它们是:

(I)Certificates->Production(分发应用证书,发布应用证书.cer):安装在电脑上提供发布IOS程序的权限:开发人员可以制做测试版和发布版程序(打包IOS时用的证书)。不可生成副本,仅有配置该证书的电脑才可以使用。

(II)Provisioning Profiles->Distribution(发布授权文件.mobileprovision): 在装有发布证书的电脑上(即配置证书的电脑,只有一台)制作测试版和发布版的程序。

注:

(I)发布版就是发布到AppStore上的程序文件,开发者账号创建爱你授权文件时store选项,选择App Id,无需选择UDID。

(II)测试版就是在发布之前交给测试人员可同步到设备上的程序文件,开发者账号创建授权文件时选择AdHoc,选择AppID和UDID;只有选中的UDID对应的设备才可能安装上通过该授权文件制作的程序(App)。

3.4按下图注册开发者和发布证书,它们十分相似:

这样开发者证书和发布证书就注册好了

3.5:按下图进行注册授权证书

注:

(1)授权证书基本上的步骤基本上差不多,唯一不同的就是上AppStore的授权证书不用选择测试设备(测试真机)。

4.制作P12信息交换证书

4.1你需要什么证书只需下载相应的证书就可以了。当然,授权证书可以直接用,但开发者证书和分发者证书(.cer)项目还不能直接用,还需要通过钥匙串转成P12的信息交换文件,项目才可以用。

4.2按照下面示例制作P12证书:

第一步:需要制作哪个证书(.cer)双击它,导入到要钥匙串访问。一定要查看密码中的专用秘钥与你需要的.cer一致.

 这样,我们所需要的.cer证书就转换成P12个人信息交换证书就制作好了。

到此,我们项目中的所需要的证书就制作好了。 

                       

                                                                                              第二步:FlashBuilder4.7项目针对IOS上AppStore的修改部分

1配置相关的AppIcon图标问题和xiangmu.xml一些配置

1.1由于上AppStore需要配置相关的AppIcon图标,下面的图标是示例,如果你的App通过ApplicationLoader上传到AppStore时有下面类似的错误,你只需要进行修改就可以了。

ERROR ITMS-90022: "Missing required icon file. The bundle does not contain an app icon for iPhone / iPod Touch of exactly \'57x57\' pixels, in .png format for iOS versions < 7.0."
WARNING ITMS-90025: "Missing recommended icon file. The bundle does not contain an app icon for iPhone / iPod Touch of exactly \'120x120\' pixels, in .png format for iOS versions >= 7.0."

1.2如下图示例:

这几张Icon是设备启动的图标

2.关于真机调试。

2.1关于真机调试设置问题

3.关于打包成上AppStore的App

3.1项目->导出发行版

好了,关于项目中关于IOS的一些修改就介绍这些了,当然,关于内购的一些修改放到最后最后介绍。

                                                                                                            第三部分:关于AppStore中的上架信息部分

三部分关于AppStore中的上架信息部分,非常简单,没有什么介绍的,只要按照图片介绍进行填写即可。

 

 

 

                                                                                                                第四部分:FlashBuilder中的特殊内购

4.1插件:productStore.ane 下载地址:Adobe账号中的Adobe Gaming SDK中的productStore.ane以及案例

4.2  项目.xml中插入productStore.ane的引用

    
<extensions>     
    <extensionID>com.adobe.ane.productStore</extensionID>
   </extensions>
View Code

4.3项目中添加productStore.ane

项目->属性->ActionScript构建路径->本机扩展->添加ane

 

4.4打包时注意导入productStore.ane

4.5应用支付原理

(1)App请求订单号->苹果服务器处理->App收到苹果服务器处理结果(交易取消,交易成功,交易失败)。<1>成功,收到票据,票据发送到苹果服务器验证->苹果反馈验证成功->App发送商品给玩家。

(2)一般App收到票据发送给道具服务器(App自己的服务器)->道具服务器发送给苹果进行验证->道具服务器验证成功之后->道具服务器通知App发送商品给玩家。

(3)本案例进行本地验证

(4)记住苹果验证成功具有理想性和欺骗性,还要继续进行验证(如App id,交易的账单号,交易的时间戳等)防止玩家进行插件刷单。

4.6iTunes Connect中的设置

(1)协议、税务和银行业务中的相关信息设置,如果缺少这一步,内购功能是不会成功的。这是苹果给你钱啊!

(2)弄一个测试账号:用户和职能->沙箱技术测试员。

 4.7内购商品的分类以及设置

 

注意:一定要选对你的商品类型。

4.8关于productStore.ane的理解

4.8.1 ProductStore的API

写程序的第一行代码,一定要到iTunesConnect中上创建应用内支付商品,否则,程序请求商品ID无效,应用就无法测试。

ProductStore中的API只有这几个类:

ProductStore

ProductEvent

Product

Transaction

TransactionEvent

4.8.2ProductStore中的9个事件侦听

(1)ProductEvent.PRODUCT_DETAILS_SUCCESS商品列表获取成功

(2)ProductEvent.PRODUCT_DETAILS_FAIL商品列表获取失败

(3)TransactionEvent.PURCHASE_TRANSACTION_SUCCESS交易成功

(4)TransactionEvent.PURCHASE_TRANSACTION_CANCEL交易取消

(5)TransactionEvent.PURCHASE_TRANSACTION_FAIL交易失败

(6)TransactionEvent.FINISH_TRANSACTION_SUCCESS交易完成成功

(7)TransactionEvent.RESTORE_TRANSACTION_SUCCESS恢复交易成功

(8)TransactionEvent.RESTORE_TRANSACTION_FAIL恢复交易失败

(9)TransactionEvent.RESTORE_TRANSACTION_COMPLETE恢复交易完成

4.8.3在应用程序运行后,尽早创建一个ProductStore的Singleton(单利)示例,并保持它存在于整个应用的生命周期内

  productStore=new ProductStore()

4.8.4三个请求事件

(1)productStore.requestProductsDetails(ProductListId)使用商品ID来请求商品的详细信息  (商品列表数组)

(2)productStore.makePurchaseTransaction(buyProductId,1);//触发购买的交易请求  ("商品ID",数量);

(3)productStore.restoreTransactions();//恢复请求

4.8.5进行一些支持判断

               //检测苹果设备是否支持Productsore
        protected function check_isSupported():void{
            var t1:Boolean=ProductStore.isSupported;  
        }
        //检测用户是否通过应用直接购买
        protected function is_Available():void
        {
            var t2:Boolean=productStore.available;
        }
View Code

4.8.6尽早的进行请求商品信息,并保持在内存中

public function get_Product():void
        {
            trace("----------get_Product-------start---------");
            
            
            productStore.addEventListener(ProductEvent.PRODUCT_DETAILS_SUCCESS,productDetailsSucceeded)//商品列表获取成功
            
            
            productStore.addEventListener(ProductEvent.PRODUCT_DETAILS_FAIL,productDetailsFailed)//商品列表获取失败
            
            ProductListId=new Vector.<String>(5);
            var AppBundleId:String="com.gamevil.Kungfu.defug.";
            ProductListId[0]=AppBundleId+"MonthCardThirtyRMB4";//月卡充值30元
        
            ProductListId[1]=AppBundleId+"ThirtyRMB4";//充值30元
            ProductListId[2]=AppBundleId+"OneHuandedAndEightRMB4";//充值108元
            ProductListId[3]=AppBundleId+"OneHundredAndNinietyEightRMB4";//充值198元
            ProductListId[4]=AppBundleId+"FourHundredAndEightyEIghtRMB4";//充值488元
        
        
            
            productStore.requestProductsDetails(ProductListId);//可以使用商品ID来请求商品的详细信息
            trace("----------get_Product-------end---------");
            
        }
        //商品列表请求成功
        public function productDetailsSucceeded(e:ProductEvent):void
        {
            //            trace("in productDetailsSucceeded "+e);
            
            var i:uint=0;
            trace("商品列表请求成功 ");
            while(e.products&&i<e.products.length)
            {
                
                //                //获取每一个商品的详细信息<itunesconnect.apple.com成功设置每一个商品ID>
                var p:Product=e.products[i];
        
                trace("999999  "+p.identifier);
                //                trace("title: "+p.title);//商品名称
                //                trace("description:"+p.description);//商品描述
                //                trace("indetitier:"+p.identifier);//商品ID
                //                trace("priceLocale:"+p.priceLocale);//商品价格本地化信息
                //                trace("price:"+p.price);//商品价格
                i++;
            }
    
            
            
        }
        //商品列表请求失败
        public function productDetailsFailed(e:ProductEvent):void
        {
        
            
        
            var i:uint=0;
            while(e.invalidIdentifiers&&i<e.invalidIdentifiers.length)
            {
             
                trace("888888"+e.invalidIdentifiers[i]);
                i++;
            }
        }
View Code

(1)这里的商品ID都要在iTunesconnect中的内购成功设置,否则就监听不成功

(2)监听成功的商品信息被ANE封装在一个Product类中,属性如下:

identifier:商品ID

title:商品名称

description:描述文字

price:商品价格(已经折合为用户商品的本地货币单位)

priceLocal:商品价格本地化信息(用来获取货币单位的显示)。

4.8.7有关交易触发和维护 

public function buyTheApp (buyProductId:String):void
        {
            trace("8888888   BUYTime"+BUYTime);
            if(BUYTime==true){
                BUYTime=false;
                productStore.addEventListener(TransactionEvent.PURCHASE_TRANSACTION_SUCCESS,purchaseTransactionSucceeded);//交易成功
                productStore.addEventListener(TransactionEvent.PURCHASE_TRANSACTION_CANCEL,purchaseTransactionCanceled);//交易取消
                productStore.addEventListener(TransactionEvent.PURCHASE_TRANSACTION_FAIL,purchaseTransactionFailed);//交易失败
                
    
                
                productStore.makePurchaseTransaction(buyProductId,1);//触发购买的交易请求  ("商品ID",1);
            
            }
        }
        //交易成功
        protected function purchaseTransactionSucceeded(e:TransactionEvent):void
        {
            
        
            productStore.removeEventListener(TransactionEvent.PURCHASE_TRANSACTION_SUCCESS,purchaseTransactionSucceeded);//交易成功
            productStore.removeEventListener(TransactionEvent.PURCHASE_TRANSACTION_CANCEL,purchaseTransactionCanceled);//交易取消
            productStore.removeEventListener(TransactionEvent.PURCHASE_TRANSACTION_FAIL,purchaseTransactionFailed);//交易失败
        
            BUYTime=true;
            trace("hongqianjin         //交易成功 ");
        
            var i:uint=0;
            var t:Transaction;

            
            while(e.transactions&&i<e.transactions.length)
            {
          
                t=e.transactions[i];
                purchaseIdentifier=t.identifier;//保存交易的id
                i++;
        
                
                productStore.addEventListener(TransactionEvent.FINISH_TRANSACTION_SUCCESS,finishTransactionSucceeded);
                productStore.finishTransaction(t.identifier);
                // 验证收据
                var encodedReceipt:String=Base64.encode(t.receipt);
  
                var req:URLRequest=new URLRequest("https://buy.itunes.apple.com/verifyReceipt");//沙盒测试,如上线则sandbox改成为buy
                req.method=URLRequestMethod.POST;
                req.data="{\\"receipt-data\\":\\""+encodedReceipt+"\\"}";
                var ldr:URLLoader=new URLLoader(req);
                ldr.load(req);
                ldr.addEventListener(Event.COMPLETE,function(e:Event):void{
            
                      
                   var People:*=JSON.parse(ldr.data);
       
                    if(People["status"]==21007)//如果是环境测试,则放到环境验证服务器验证
                    {
                        var req1:URLRequest=new URLRequest("https://sandbox.itunes.apple.com/verifyReceipt");//沙盒测试,如上线则sandbox改成为buy
                        req1.method=URLRequestMethod.POST;
                        req1.data="{\\"receipt-data\\":\\""+encodedReceipt+"\\"}";
                        var ldr1:URLLoader=new URLLoader(req1);
                        ldr1.load(req1);
                        
                        ldr1.addEventListener(Event.COMPLETE,function(e:Event):void{
                            var People1:*=JSON.parse(ldr1.data);
                            if(!People1["status"])
                            {
                                
                                    if(People1["receipt"].bid!="com.gamevil.Kungfu.defug")//如果不是次Kungf游戏,则保持
                                    {
                                    //    trace("游戏不是Kungfu");
                                    }else if(People1["receipt"].transaction_id!=purchaseIdentifier)
                                    {
                                        //trace("不是此次交易");
                                    }else
                                    {
                                        //trace("返回成功");
                                      //这地方发放玩家商品
                                    }
                                }else
                                {
                                //    trace("  票剧违法");
                                }
                        });
                        
                    }
                    else if(!People["status"])//返回0,则成功
                    {
                        if(People["receipt"].bid!="com.gamevil.Kungfu.defug")//如果不是次Kungf游戏,则保持
                        {
                            trace("游戏不是Kungfu");
                        }else if(People["receipt"].transaction_id!=purchaseIdentifier)
                        {
                            trace("不是此次交易");
                        }else
                        {
                                  trace("返回成功");
                                  //这地方发放给玩家商品
                        }
                    }else
                    {
                        trace("  票剧违法");
                    }
                });
                
            }
            getPendingTransaction(productStore);
        }
        //交易取消
        protected function purchaseTransactionCanceled(e:TransactionEvent):void{
            logn.off();
            productStore.removeEventListener(TransactionEvent.PURCHASE_TRANSACTION_SUCCESS,purchaseTransactionSucceeded);//交易成功
            productStore.removeEventListener(TransactionEvent.PURCHASE_TRANSACTION_CANCEL,purchaseTransactionCanceled);//交易取消
            productStore.removeEventListener(TransactionEvent.PURCHASE_TRANSACTION_FAIL,purchaseTransactionFailed);//交易失败
            BUYTime=true;
            trace("hongqinajin +//交易取消");
        
            var i:uint=0;
            while(e.transactions&&i<e.transactions.length)
            {
                var t:Transaction=e.transactions[i];
                //printTransaction(t);
                i++;
                trace("FinishTransactions"+t.identifier);
                productStore.addEventListener(TransactionEvent.FINISH_TRANSACTION_SUCCESS,finishTransactionSucceeded);
                productStore.finishTransaction(t.identifier);//结束这个交易。调用这个API会将该交易从系统维护的交易队列中移除
            }
            getPendingTransaction(productStore);
        }
        //交易失败
        protected function purchaseTransactionFailed(e:TransactionEvent):void
        {
          
            productStore.removeEventListener(TransactionEvent.PURCHASE_TRANSACTION_SUCCESS,purchaseTransactionSucceeded);//交易成功
            productStore.removeEventListener(TransactionEvent.PURCHASE_TRANSACTION_CANCEL,purchaseTransactionCanceled);//交易取消
            productStore.removeEventListener(TransactionEvent.PURCHASE_TRANSACTION_FAIL,purchaseTransactionFailed);//交易失败
            BUYTime=true;
            trace("ii交易失败");
            var i:uint=0;
        
            while(e.transactions&&i<e.transactions.length)
            {
                var t:Transaction=e.transactions[i];
                //printTransaction(t);
                i++;
                trace("FinishTransactions"+t.identifier);
                productStore.addEventListener(TransactionEvent.FINISH_TRANSACTION_SUCCESS,finishTransactionSucceeded);
                productStore.finishTransaction(t.identifier);
            }
            getPendingTransaction(productStore);
        }
        //完成交易成功完成
        protected function finishTransactionSucceeded(e:TransactionEvent):void
        {
            trace("i交易完成   "+e);
            BUYTime=true;
            var i:uint=0;
              
            while(e.transactions&&i<e.transactions.length)
            {
                var t:Transaction=e.transactions[i];
                //printTransaction(t);
                
                
                productStore.removeEventListener(TransactionEvent.FINISH_TRANSACTION_SUCCESS,finishTransactionSucceeded);
           
                
                i++;
            
                trace("FinishTrinsactions"+t.productIdentifier);
                trace("FinishTrinsactions"+t.identifier);
                
            }

            
        }
View Code

(1)进入买卖的时候,就开始进行了交易的结果的三大监听

productStore.addEventListener(TransactionEvent.PURCHASE_TRANSACTION_SUCCESS,purchaseTransactionSucceeded);//交易成功

productStore.addEventListener(TransactionEvent.PURCHASE_TRANSACTION_CANCEL,purchaseTransactionCanceled);//交易取消

productStore.addEventListener(TransactionEvent.PURCHASE_TRANSACTION_FAIL,purchaseTransactionFailed);//交易失败

(2)触发购买

productStore.makePurchaseTransaction(buyProductId,1);//触发购买的交易请求  ("商品ID",1);

这句代码是想Store发送了一个购买请求,商品号是ProductId,数量为1。同时ane负责与AppStore之间的交易,会有三种结果(交易成功,交易取消交易失败)。设备系统会弹出一个原生对话框,取消or购买。点击取消会触发productStore.addEventListener(TransactionEvent.PURCHASE_TRANSACTION_CANCEL,purchaseTransactionCanceled);//交易取消

这个事件。

点击购买,会触发

productStore.addEventListener(TransactionEvent.PURCHASE_TRANSACTION_SUCCESS,purchaseTransactionSucceeded);//交易成功

 这个事件

(3)从程序角度来说,每一个交易是Transcation。它包含了下面的属性:

identifier:交易ID,每次交易都有一个unique的ID,由应用商店生成。

date:交易时间

error:交易错误信息

originalTransaction:原始交易(针对恢复非消费型商品的交易)

productIdentifier:交易所涉及的商品ID

productQuantity:交易所涉及的商品数量

receipt:交易成功后的数据(由ANE封装的Product和Transaction类,保存了IOS SDK中的StoreKit的原生类属性,连命名都一样)。

4.8.8Transaction队列

    //交易队列中
        public function getPendingTransaction(prdStore:ProductStore):void
        {
            var transactions:Vector.<Transaction>=prdStore.pendingTransactions;
            var i:uint=0;
            //    trace("hongqianjin:transactions="+transactions);
            
            while(transactions&&i<transactions.length)
            {
                
                var t:Transaction=transactions[i];    
                
                //    printTransaction(t);
                i++;
            }        
        }
View Code

 设备应用商品中,维护者一个Transaction队列。每个交易的生命周期不受应用程序的生命周期限制,即使在交易过程中退出,交易依然存在。下次登录应用并初始化ProductStore时,应用商品在第一个时间派发时间告知交易结果。这就是为什么尽早初始化ProductStore。

4.8.9打印交易的信息

//打印交易的信息
        public function printTransaction(t:Transaction):void
        {
            trace("------------in Print Transaction-----------------");
            trace("identifier:"+t.identifier);//交易ID,每次交易都有一个uniqueID,由应用商店生成
            trace("productIdentifier:"+t.productIdentifier);//交易所涉及的商品ID
            trace("productQuantity:"+t.productQuantity);//交易所涉及的商品数量
            trace("data:"+t.date);//交易时间
            trace("receipt:"+t.receipt);//交易成功后的收据
            trace("error:"+t.error);//交易错误信息
            trace("originalTransaction:"+t.originalTransaction);//原始交易(针对恢复非消费型商品的交易)
            if(t.originalTransaction)
                printTransaction(t.originalTransaction);
            trace("------end of print transaction--------------------");
        }
View Code

4.8.10  结束交易

productStore.finishTransaction(t.identifier);//结束这个交易。调用这个API会将该交易从系统维护的交易队列中移除

这一个代码非常的重要,在三大交易结果中都需要调用这个API会将它中该交易从系统维护的交易队列中移除。不然会很容易造成“该商品已经购买,将免费帮你恢复”从而造成该交易购买不成功。

4.8.10  三大交易结果的解释

(1)productStore.addEventListener(TransactionEvent.PURCHASE_TRANSACTION_SUCCESS,purchaseTransactionSucceeded);//交易成功

purchaseTransactionSucceeded这个函数中处理交易成功的事情,交易成功之后不要立即给玩家发送商品,应该拿票据到AppStore商店里进行验证该此交易,是为了保证该次交易的合法性,而不是第三方软件的造假行为。交易成功也需要结束交易。

(2)

productStore.addEventListener(TransactionEvent.PURCHASE_TRANSACTION_CANCEL,purchaseTransactionCanceled);//交易取消

productStore.addEventListener(TransactionEvent.PURCHASE_TRANSACTION_FAIL,purchaseTransactionFailed);//交易失败

当用户取消交易或者交易失败的时候,或者一个新的交易请求属于重复购买行为。应用商品会派发Cancel或者Fail这两个事件。但都需要结束交易。

4.8.11验证收据

(1)交易收据以字符串的形式保存在Transaction类的receipt属性里,开发者可以选择在客户端提交验证,也可以让自己的服务器来发送。

(2)验证的目前就是为了判断该交易的合法性。现在大量的插件很容易进行刷单,所以需要进行判断该交易的合法性。验证的方式是将收据以JSON对象的方式发送到苹果地址,然后判断返回的结果。

(3)返回的结果即使正确在本地也需要进一步判断,例如以 AppId,时间戳,交易单号等。现在的刷单插件实在是比较强大。

(4)先用Base64把数据编码然后在发送给AppStore服务器验证

(6)记住我们自己的验证和苹果的审核都是在苹果的沙盒环境下进行的,而玩家却是在正式的服务器下进行购买。这就是所谓的二次验证。苹果的玩家购买环境服务器:

https://buy.itunes.apple.com/verifyReceipt   苹果的沙盒环境:https://sandbox.itunes.apple.com/verifyReceipt

(7) 票据发送给苹果服务器的代码示例:

    var encodedReceipt:String=Base64.encode(t.receipt);

                var req:URLRequest=new URLRequest("https://buy.itunes.apple.com/verifyReceipt");//沙盒测试,如上线则sandbox改成为buy
                req.method=URLRequestMethod.POST;
                req.data="{\\"receipt-data\\":\\""+encodedReceipt+"\\"}";
                var ldr:URLLoader=new URLLoader(req);
                ldr.load(req);
loader.addEventListener(Event.COMPLETE,onReceiptComplete);
loader.addEventListener(Event.IO_ERROR,onReceiptError);
View Code

(8)响应的结果也是JOSN对象:

{

  "receipt":{(receipt here)},"status":0

}

(I)status :0是说明该交易是有效的,否则是无效的,2007是测试用的sandbox,却被发送到玩家购买的服务器中去了。还有很多,这里就不介绍了。

(II)receipt here :这里记录了关于本次交易的很多信息,例如时间戳,交易ID,交易数量,交易商品,交易AppID等等,这些信息都是可以进行本地化验证的依据。

4.8.12 这里恢复商品,只贴出代码。

                //恢复内购
                protected function restore_Transactions():void
                {
                    trace("in restore_Transactions"以上是关于关于FlashBuilder4.7关于IOS打包上架AppStore的主要内容,如果未能解决你的问题,请参考以下文章

关于flutter打包无法上传的问题

关于uniapp地图真机运行正常,打包后无法使用

关于 Flutter IOS混合开发打包Framework集成到原生IOS工程 和 flutter_boost使用

关于uniapp在ios审核时会出现的问题1

iOS使用HBuilder进行云端打包步骤

关于打包之后崩溃日志的查看