您的位置:首页 > 移动开发 > Objective-C

lua语言完成游戏逻辑,移植到ios 接入支付宝 完成lua和object-c的交互(各个模块独立)

2016-01-26 11:43 951 查看
一直没有写博客的习惯,第一篇

lua语言完成游戏逻辑,移植到ios 接入支付宝 完成lua和object-c的交互(各个模块独立)

1.移植到iOS
     本游戏是用lua脚本开发的,是一种跨平台的语言,移植到iOS非常简单,打开  工程名/frameworks/runtime-src/proj.ios_mac下的xcodeproj文件即可,可能会出现缺少框架文件类似的问题,只需要按照错误提示添加相应的框架文件即可。

2.iOS接入支付宝 完成lua和object-c 的交互

     (1)问题

          因为我们游戏的逻辑主要是用Lua实现的(前面已经做过假设),而SDK是用Objective-C实现,所以这里我们需要解决Lua与Objective-C的交互问题,即最终希望达到的目标是,在Lua层面“调用”Objective-C的代码(注意这里的调用是加引号的,间接的调用),而当Objective-C层面收到SDK的回调,再通知Lua。我们知道,Lua并没有简单的方法直接和Objective-C交流,但是Lua可以通过Lua
Binding和C/C++交流,而我们又知道,C++和Objective-C可以混编,即C++可以直接调用(这里调用没引号,是真的直接调用)Objective-C的代码。

     

     
根据上面的分析,我们可以用如下图表达我们的思路,我们这里将语言交互的过程分成了4个小部分:

整个语言交互的过程可以总结为:Lua调用Lua Binding的C++接口,C++接口调用混编的Objective-C接口,而Objective-C通过block形式的回调,将结果通知给C++,C++通过Lua的C
API将最终结果返回给Lua。这样一趟下来,就完成了Lua与Objective-C的整个交互过程。

     基本做法:

          可以分为几块:1⃣️ object-c接入支付宝(独立模块  与iOS项目接入支付宝完全一样)      

                                2⃣️lua层接收到游戏中传来的参数(独立模块     lua层的操作)     

                                 3⃣️lua层将接受到的参数传递到oc层(将lua层和oc层链接)

          总的来说就是  lua层接收到游戏中的与支付相关的参数  将参数通过luaoc传递到oc层  再发送给支付宝  支付成功后支付宝给后台服务器发送一个支付成功的消息  ,于此同时客户端也给服务器发送了一个支付的消息,在服务器端根据两个消息验证,验证成功 …
   完成.

(2)接入支付宝

     1⃣️下载sdk 与demo

          下载地址     https://doc.open.alipay.com/doc2/detail?treeId=54&articleId=103419&docType=1

     2⃣️按照支付宝官方文档的步骤导入sdk   添加框架  添加路径

               文档地址https://doc.open.alipay.com/doc2/detail.htm?spm=0.0.0.0.KXemyF&treeId=59&articleId=103676&docType=1

          1.导入adk和框架依赖库

          

     

     

     此配置适配ios9中对http访问的限制

     代替的简单做法:

          在info.plist文件中加入

<key>NSAppTransportSecurity</key>


    
<dict>   


        
<key>NSAllowsArbitraryLoads</key><
true
/>


    
</dict>


          

2.将demo中下面的文件复制到项目中

注意:建议先将下面几个文件先放到一个文件夹内再一起添加到项目(否则后面可能出现路径找不到的问题)

我的项目文件位置 (所有文件放到了一个文件aliPaySDK中)

3.编译项目,会出现以下问题:

  1)"Unknown type name ‘NSString‘ "或者"Unknown type name ‘NSData‘ "等不识别常见类的问题。

  

  这是因为缺少Foundation类库和UIKit类库,支付宝Demo中之所以没有出现此错误,是因为在.pch文件中导入过这些类库

  解决办法:只需要在出现错误的文件中导入这些类库即可

  

  2)‘openssl/asn1.h‘ file not found

  
解决方法如下:在你的Xcode里的header search paths 里添加支付宝SDK(openssl的路径);格式如下  $(PROJECT_DIR)/文件夹名        
(这里说一下,直接点击openssl,然后showinfinder,然后command + i  查看路径,把得到路径的工程名字以后的部分加在文件夹名这OK了)

  这是openssl文件夹头文件链接问题,如果openssl文件夹随意拉进项目中,
18c93
即使添加头文件链接,也可能解决不了此问题,

  这也是问什么一开始就将所需要的文件放到一个新建文件夹中再添加到项目中的原因。

  解决办法:Targets->Build Settings->Header Search Path中添加1中建立的aliPaySDK文件夹的路径()



  

     

          路径这样写 :      $(PROJECT_DIR)/testDemo/aliPaySDK

                      $(PROJECT_DIR)表示跟路径 

                    testDemo是工程文件名  后面跟导入文件的实际路径

                         我的实际路径

3)根据项目需求添加demo中ViewController中的代码 编译后可能会出下面错误:

  "_OBJC_CLASS_$_Product", referenced from: objc-class-ref
in ViewController.o

  

  AlipaySDK的demo中将Product类的定义写在了ViewControler.h中所致

 

  解决办法:新建Product类,将viewController中Product类定义的代码复制过去即可。

  

4 添加支付代码  完成支付过程

(下面是实际项目中的过程)

     新建一个类用来完成支付 (供其他模块调用)

         

在.m文件中 添加字符代码(完全复制demo中的支付部分)

//
//  Pay.m
//  zygame
//
//  Created by apple on 16/1/24.
//
//

#import “Pay.h" 

#import"Order.h"

#import “Product.h” //新建的product文件

#import<AlipaySDK/AlipaySDK.h>

#import “DataSigner.h”
//签名用 util和opensll文件中可以找到

@implementationPay

{

   
Product *product;

}

+ (void)PayMoney:(NSDictionary *)dict{   //注意这里是+方法  以便于在其他的模块中可以直接调用
 需要在.h中声明

    

     //获得其他模块调用时传过来的参数(以字典的形式)发送给支付宝

   NSString*orderId
= [dict
valueForKey:@"orderId"];

   
NSString *subject = [dictvalueForKey:@"subject"];

   
NSString *body = [dictvalueForKey:@"body"];

   
NSString *price = [dictvalueForKey:@"price"];

    if(orderId) {

       
NSLog(@"orderId------%@",orderId);

    }

    if(subject) {

       
NSLog(@"orderId------%@",subject);

    }

    if(body) {

       
NSLog(@"orderId------%@",body);

    }

    if(price) {

       
NSLog(@"orderId------%@",price);

    }

    /*

     *商户的唯一的parnter和seller。

     *签约后,支付宝会为每个商户分配一个唯一的parnter和seller。

     */

   

    /*============================================================================*/

    /*=======================需要填写商户app申请的===================================*/

    /*============================================================================*/

   NSString *partner =@"";

   NSString*seller
= @“";

   NSString*privateKey
= @“”;  //商家私钥

   /*============================================================================*/

    /*============================================================================*/

    /*============================================================================*/

   

    //partner和seller获取失败,提示

    if([partnerlength]
== 0 ||

        [seller
length] == 0 ||

        [privateKey
length] == 0)

    {

       
UIAlertView *alert = [[UIAlertViewalloc]initWithTitle:@"提示"

                                                       
message:@"缺少partner或者seller或者私钥。"

                                                      
delegate:self

                                             
cancelButtonTitle:@"确定"

                                             
otherButtonTitles:nil];

        [alert
show];

       
return;

    }

   

    /*

     *生成订单信息及签名

     */

    //将商品信息赋予AlixPayOrder的成员变量

   
Order *order = [[Orderalloc]init];

    order.partner= partner;

    order.seller= seller;

    order.tradeNO= [selfgenerateTradeNO];//订单ID(由商家自行制定)

    order.productName= subject;//商品标题

    order.productDescription= body;//商品描述

    order.amount = [NSStringstringWithFormat:@"%.2f",[pricedoubleValue]];//商品价格

    order.notifyURL = @"http://www.xxx.com";//回调URL
 支付结果发送给谁(服务器地址)

   

    order.service=@"mobile.securitypay.pay";

    order.paymentType=@"1";

    order.inputCharset=@"utf-8";

    order.itBPay=@"30m";

    order.showUrl=@"m.alipay.com";

   

    //应用注册scheme,在AlixPayDemo-Info.plist定义URL
types

   
NSString *appScheme =@"alisdkdemo";

   

    //将商品信息拼接成字符串

   
NSString *orderSpec = [orderdescription];

   
NSLog(@"orderSpec = %@",orderSpec);

   

    //获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode

    id<DataSigner>
signer =
CreateRSADataSigner(privateKey);

   
NSString *signedString = [signersignString:orderSpec];

   

    //将签名成功字符串格式化为订单字符串,请严格按照该格式

   
NSString *orderString =nil;

    if(signedString !=nil)
{

        orderString = [NSStringstringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",

                       orderSpec, signedString,
@"RSA"];

       

        [[AlipaySDKdefaultService]payOrder:orderStringfromScheme:appSchemecallback:^(NSDictionary*resultDic)
{

           
NSLog(@"reslut = %@",resultDic);

        }];

    }

   

   

}

//获得一个随机的订单号  

+(NSString*)getOrderInfo{

   
NSString *orderSpec = [NSStringstring];

    orderSpec = [selfgenerateTradeNO];

    returnorderSpec;

   

}

#pragma mark -

#pragma mark   ==============产生随机订单号==============

+ (NSString*)generateTradeNO{

    staticintkNumber = 15;

   

   
NSString *sourceStr =@"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

   
NSMutableString *resultStr = [[NSMutableStringalloc]init];

   
srand((unsigned)time(0));

    for(inti
= 0; i < kNumber; i++)

    {

       
unsigned index =
rand() % [sourceStrlength];

       
NSString *oneStr = [sourceStrsubstringWithRange:NSMakeRange(index,
1)];

        [resultStr
appendString:oneStr];

    }

    returnresultStr;

}

@end

到此iOS与支付宝代码完成

(3) lua 层接受参数 并通过luaoc调用oc方法 (cocos 已封装好,只需要传递参数   设置调用的类名  方法名)

     

     lua文件:

--

--支付宝移动支付

--@function [parent=#src.app.tools.util]

m.AliPay = function (userid, subject, body, price, account)

    --Android平台

    if targetPlatform == cc.PLATFORM_OS_ANDROID then

     ...

     ...

   else               —iOS 平台

         price=0.02

        local luaoc = require("cocos.cocos2d.luaoc”)  —调用lua绑定中的luaoc

        local className = “Pay”  —调用oc中的类名

        local methodName = “getOrderInfo” —oc中的 方法名

        local args = { }   —参数  (这里是空 )

        local ok, orderinfo = luaoc.callStaticMethod(className,methodName,arg)  —返回的是一个订单号  用来传递给服务器做验证

        local xhr = cc.XMLHttpRequest:new()

        xhr.responseType = cc.XMLHTTPREQUEST_RESPONSE_STRING

        local out_trade_no = orderinfo

        print(out_trade_no)

        local req = string.format(

            'http://www.xxx.com?orderid=%s&...', —按照服务器要求的字段传递数据

            out_trade_no,

            userid,

            price,

            account,

            0

        )

        xhr:open("GET", req)

        xhr:send()  —向服务器发送数据

          —和上面一样调用oc的方法与支付宝对接

        local luaoc = require("cocos.cocos2d.luaoc")

        local className = "Pay"

        local methodName = "PayMoney"

        local args = { orderId = out_trade_no,subject = subject, body =  body, price = price, }  —按照oc中方法定义的参数传递(字典的形式)

        local ok = luaoc.callStaticMethod(className, methodName, args)  

    end

end

到此所有的工作完成!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息