首页 > 代码库 > wax lua 脚本升级练习(1)

wax lua 脚本升级练习(1)

当发现线上app某一功能出现bug,即使在技术上很快的做出了这一bug的补丁,但是因为AppStore上线审核漫长,这将在一段时间里,用户用的都是这个款带有已知bug的产品。

这种情况的一个解决办法就是通过Lua给app打补丁,因为Lua是脚本语言,将脚本放在服务器上,在程序启动的某个时机动态的从服务器上下载Lua代码,并在本地执行,就实现了动态替换app代码,从而快速的给app打补丁。

现在就做一个小练习,模拟一下。


(1)功能就是点击“4 x 3 =”按钮,将4和3传到lua,然后在lua里面计算4和3的乘积,返回给objc,显示在旁边的TextField里。当然,在这里lua返回的得是一个错误得值,比如两数之和 “7”。

(2)然后点击“下载新脚本”,将命令传到lua,然后lua再到指定到服务器去下载新脚本,然后覆盖旧脚本,热加载新脚本,再次点击“4 x 3 =”按钮,将显示正确到值“12”。

这里先实现第一步,通过lua脚本计算乘积。

创建一个工程waxDemo,做一个如图到界面,将wax添加到工程里(可以参考xcode5中 wax 安装记录)。

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UITextField *text;

- (IBAction)click:(id)sender;//4 x 3 =
- (IBAction)downlodNewLua:(id)sender;
@end
- (IBAction)click:(id)sender {
    //,@"delegate":self
    NSDictionary * dic= [[luaMain shareInstance] ExecLua:@{@"cmd":LUA_EVENT_CLICK, @"param":@{@"Multiplicand":@4,@"Multiplier":@3}}];
    NSString *str = dic[@"param"][@"value"];
    self.text.text = str;
}

上面到函数就是将‘4’和‘3’传到lua,ExecLua 接收到参数是一个NSDictionary类型,也可以是其他任意类型,因为luaMain类是自己写得一个封装,ExecLua函数可以随意更改。

返回的也是一个NSDictionary,dic对象里的key是oc和lua约定的规则。我自己定义的,也是可以随意修改的。下面就是luaMain类

luaMain.h

#import <Foundation/Foundation.h>
#import "wax.h"


//约定好的命令
#define LUA_EVENT_CLICK         @"10000"
#define LUA_EVENT_DOWNLOAD_NEN_SCRIPT         @"10001"

@interface luaMain : NSObject

@property(nonatomic) lua_State* curState;

+ (luaMain*) shareInstance;

- (NSDictionary*) ExecLua:(NSDictionary*)param;

@end

luaMain.m

#import "luaMain.h"
#import "lualib.h"
#import "../wax/lib/extensions/HTTP/wax_http.h"
#import "../wax/lib/extensions/json/wax_json.h"
#import "JSONKit.h"
static luaMain* instance = nil;
@implementation luaMain

+(luaMain*)shareInstance {
    
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        
        instance = [[self alloc] init];
        
    });
    return instance;
    
}

- (id)init
{
    self= [super init];
    if (self) {
        self.curState = wax_currentLuaState();
        wax_start("main.lua", luaopen_wax_http, luaopen_wax_json, nil);
    }
    return  self;
}


- (NSDictionary* )ExecLua:(NSDictionary *)param{
    if (param){
        
        NSString* strJSON = [param JSONString];//将NSDictionary转成JSON格式,使用第三方库JSONKIT
        lua_getglobal(_curState, "exeLuaCode");////lua里调用的函数exeLuaCode
        lua_pushstring(_curState, [strJSON UTF8String]);//将参数推送到lua
        
        if (0 != wax_pcall(_curState, 1, 1)){
            
            const char *msg = lua_tostring(_curState, -1);
            NSString* value = http://www.mamicode.com/[NSString stringWithUTF8String:msg];>
main.lua

function printLog( log )
 	-- body
 	if 'table' == type(log) then
 		log = wax.json.generate(log);
 	end
   	print(log);
end 

function exeLuaCode( param )
	-- body
	print('exeLuaCode')

	if (not param) then
		return nil;
	end


	local dict_param = wax.json.parse(param);

	if dict_param then
		local cmd = dict_param['cmd'];
		if cmd == '10000' then
			return multiply(dict_param['param'])
		 elseif cmd == '10001' then
		-- 	updateScriptStatus()
		end
	end
end

function multiply( param)
	-- body
	printLog('multiply')
	if (not param) then
		return;
	end

	local delegate = param['delegate']
	local Multiplicand = param['Multiplicand']
	local Multiplier = param['Multiplier']
	printLog('Multiplicand = ' .. Multiplicand)
	printLog('Multiplier = ' .. Multiplier)
	local Product =  string.format("%d",Multiplicand*Multiplier)--这里将返回4*3的积  
	printLog(Product)
	return wax.json.generate({param={value=http://www.mamicode.com/Product}})>
正常情况下将打印日志

exeLuaCode
multiply
Multiplicand = 4
Multiplier = 3
12


参考链接

Wax Lua—使用lua编写原生ios程序的框架实现原理

用Lua给你的iOS程序打patch

用Lua给你的程序打patch(续)

Create-a-More-Flexible-App