context
今天接到一个给公司RN小伙伴集成VPN SDK的任务.原生代码三下五除二的就写完了.
坑
在下面的代码中,由于初始化校验是异步操作,所以加了回调block.
if (VPN_STATUS_OK == [self.helper vpnQueryStatus]) {
NSLog(@"vpn当前是已经登录状态,注销后才能再登录");
return;
}
SdkMode mode = EasyApp;
[self.helper init:mode host:ipAddress port:[port integerValue] delegate:self];
self.initCallBack = callback;
然后为了测试,我在RN代码中进行调用:
VPNManager.initWithIPAddress('114.255.251.193','443',(status,description)=>{
AlertIOS.alert(status,description);
if (status=='RESULT_VPN_INIT_SUCCESS'){
VPNManager.startAuthWithUserName('your name','your password',(stausD,descriptionD)=>{
AlertIOS.alert(stausD,descriptionD);
})
}
});
return;
顺理成章没有难度.
然后发生的事情让我沉默了. 原生代码中helper对象的代理方法死活不走_.
容易被忽略的线程
原生代码里面加上断点, 左边一扫,发现thread
赫然是34
.难道这就是元凶?
于是改写代码:
dispatch_async(dispatch_get_main_queue(), ^{
if (VPN_STATUS_OK == [self.helper vpnQueryStatus]) {
NSLog(@"vpn当前是已经登录状态,注销后才能再登录");
return;
}
SdkMode mode = EasyApp;
[self.helper init:mode host:ipAddress port:[port integerValue] delegate:self];
self.initCallBack = callback;
});
重新运行.
终于实现了自己的想法.
可能经常做RN的小伙伴觉得这不是什么.可是我这扔下快一年的,而且当时也没做RN OC交互的弱鸡,真的是好难为.特地记录一下,希望能帮到人.
附录
顺带附上今天查资料,关于RN调用OC方法的几个点:
相关配置
1.头文件和协议
#import <React/RCTBridgeModule.h>//导入头文件
@interface DEVPNManager : NSObject<RCTBridgeModule>//遵守协议
//.m文件
@implementation DEVPNManager
RCT_EXPORT_MODULE();//导出的模块名,如果()内不写,则为类名.
- 方法定义.
- 方法的返回值只能是void
- 异步方法,还是用回调用
- 我怕生命周期有问题,将对象设置成了单例
/**
使用IP地址和端口号初始化VPN
@param ipAddress IP地址 (字符串类型) 例如:114.255.251.193
@param port 端口号 (字符串类型) 例如 443
@param callback 结果回调
*/
RCT_EXPORT_METHOD(initWithIPAddress:(NSString *)ipAddress port:(NSString*)port callback:(RCTResponseSenderBlock)callback){
/*
your code
*/
self.callBack = callback;
}
//somewhere 参数是数组
self.callBack(@[@"RESULT_VPN_INIT_SUCCESS",@"初始化VPN成功"]);
RN 端使用.
var VPNManager = NativeModules.DEVPNManager; //导入模块
//某个触发事件
VPNManager.initWithIPAddress('114.255.251.193','443',(status,description)=>{
AlertIOS.alert(status,description);
if (status=='RESULT_VPN_INIT_SUCCESS'){
}
});
参数依次传递, Block类型参数只能是数组.