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類型參數只能是數組.