iOS:Support debugging
This commit is contained in:
parent
5ca650c9cb
commit
9db60d94ba
@ -1,12 +1,15 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="pub.doric.devkit">
|
package="pub.doric.devkit">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.VIBRATE" />
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||||
|
|
||||||
<application>
|
<application>
|
||||||
<activity android:name=".ui.DoricDevActivity" />
|
<activity
|
||||||
|
android:name=".ui.DoricDevActivity"
|
||||||
|
android:exported="true" />
|
||||||
<activity android:name=".qrcode.activity.CaptureActivity" />
|
<activity android:name=".qrcode.activity.CaptureActivity" />
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@ -6,7 +6,7 @@ import org.json.JSONObject;
|
|||||||
public interface IDevKit {
|
public interface IDevKit {
|
||||||
|
|
||||||
enum Command {
|
enum Command {
|
||||||
HOT_RELOAD, EXCEPTION, LOG
|
HOT_RELOAD, EXCEPTION, LOG, DEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
void connectDevKit(String url);
|
void connectDevKit(String url);
|
||||||
|
@ -49,7 +49,7 @@ public class WSClient extends WebSocketListener {
|
|||||||
boolean intercept(String type, String command, JSONObject payload) throws JSONException;
|
boolean intercept(String type, String command, JSONObject payload) throws JSONException;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Interceptor> interceptors = new HashSet<>();
|
private final Set<Interceptor> interceptors = new HashSet<>();
|
||||||
|
|
||||||
public WSClient(String url) {
|
public WSClient(String url) {
|
||||||
OkHttpClient okHttpClient = new OkHttpClient
|
OkHttpClient okHttpClient = new OkHttpClient
|
||||||
|
@ -17,6 +17,8 @@ import androidx.appcompat.app.AppCompatActivity;
|
|||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
import com.github.pengfeizhou.jscore.JSONBuilder;
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
import org.greenrobot.eventbus.ThreadMode;
|
import org.greenrobot.eventbus.ThreadMode;
|
||||||
@ -25,6 +27,7 @@ import pub.doric.DoricContext;
|
|||||||
import pub.doric.DoricContextManager;
|
import pub.doric.DoricContextManager;
|
||||||
import pub.doric.devkit.DevKit;
|
import pub.doric.devkit.DevKit;
|
||||||
import pub.doric.devkit.DoricDev;
|
import pub.doric.devkit.DoricDev;
|
||||||
|
import pub.doric.devkit.IDevKit;
|
||||||
import pub.doric.devkit.R;
|
import pub.doric.devkit.R;
|
||||||
import pub.doric.devkit.event.ConnectExceptionEvent;
|
import pub.doric.devkit.event.ConnectExceptionEvent;
|
||||||
import pub.doric.devkit.event.EOFExceptionEvent;
|
import pub.doric.devkit.event.EOFExceptionEvent;
|
||||||
@ -150,7 +153,11 @@ public class DoricDevActivity extends AppCompatActivity {
|
|||||||
cell.findViewById(R.id.debug_text_view).setOnClickListener(new View.OnClickListener() {
|
cell.findViewById(R.id.debug_text_view).setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
DevKit.getInstance().sendDevCommand(
|
||||||
|
IDevKit.Command.DEBUG,
|
||||||
|
new JSONBuilder()
|
||||||
|
.put("source", doricContext.getSource())
|
||||||
|
.toJSONObject());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
import WebSocket from "ws"
|
import WebSocket from "ws"
|
||||||
import "colors";
|
import "colors";
|
||||||
|
import path from "path";
|
||||||
|
import { glob } from "./util";
|
||||||
|
import { Shell } from "./shell";
|
||||||
|
|
||||||
export type MSG = {
|
export type MSG = {
|
||||||
type: "D2C" | "C2D" | "C2S" | "D2S" | "S2C" | "S2D",
|
type: "D2C" | "C2D" | "C2S" | "D2S" | "S2C" | "S2D",
|
||||||
@ -45,6 +48,26 @@ export async function createServer() {
|
|||||||
debug?.send(result);
|
debug?.send(result);
|
||||||
} else if (resultObject.type === "C2S") {
|
} else if (resultObject.type === "C2S") {
|
||||||
switch (resultObject.cmd) {
|
switch (resultObject.cmd) {
|
||||||
|
case 'DEBUG':
|
||||||
|
let source = resultObject.payload.source as string;
|
||||||
|
if (source.endsWith(".js")) {
|
||||||
|
source = source.replace(".js", ".ts");
|
||||||
|
} else if (!source.endsWith(".ts")) {
|
||||||
|
source = source + ".ts"
|
||||||
|
}
|
||||||
|
const tsFiles = await glob(`**/${source}`, {
|
||||||
|
cwd: path.resolve(process.cwd(), "src")
|
||||||
|
})
|
||||||
|
if (!!!tsFiles || tsFiles.length === 0) {
|
||||||
|
console.error(`Cannot find ${source} in ${path.resolve(process.cwd(), "src")}`);
|
||||||
|
}
|
||||||
|
const sourceFile = tsFiles[0];
|
||||||
|
Shell.exec("node", [
|
||||||
|
"--inspect-brk",
|
||||||
|
path.resolve(process.cwd(), "src", sourceFile)
|
||||||
|
])
|
||||||
|
console.log(`Debugger on ${sourceFile}`);
|
||||||
|
break;
|
||||||
case 'EXCEPTION':
|
case 'EXCEPTION':
|
||||||
console.log(resultObject.payload.source.red);
|
console.log(resultObject.payload.source.red);
|
||||||
console.log(resultObject.payload.exception.red);
|
console.log(resultObject.payload.exception.red);
|
||||||
|
@ -22,10 +22,11 @@
|
|||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import <DoricCore/Doric.h>
|
#import <DoricCore/Doric.h>
|
||||||
|
#import "DoricWSClient.h"
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface DoricDebugDriver : NSObject <DoricDriverProtocol>
|
@interface DoricDebugDriver : NSObject <DoricDriverProtocol>
|
||||||
|
- (instancetype)initWithWSClient:(DoricWSClient *)wsClient;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -23,19 +23,21 @@
|
|||||||
#import "DoricDebugDriver.h"
|
#import "DoricDebugDriver.h"
|
||||||
#import "DoricDebugJSEngine.h"
|
#import "DoricDebugJSEngine.h"
|
||||||
#import "DoricConstant.h"
|
#import "DoricConstant.h"
|
||||||
#import "DoricContextManager.h"
|
#import "DoricDev.h"
|
||||||
|
|
||||||
@interface DoricDebugDriver ()
|
@interface DoricDebugDriver ()
|
||||||
@property(nonatomic, strong) DoricJSEngine *jsExecutor;
|
@property(nonatomic, strong) DoricJSEngine *jsExecutor;
|
||||||
|
@property(nonatomic, copy) NSString *theContextId;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation DoricDebugDriver
|
@implementation DoricDebugDriver
|
||||||
|
|
||||||
@dynamic registry;
|
@dynamic registry;
|
||||||
|
|
||||||
- (instancetype)init {
|
- (instancetype)initWithWSClient:(DoricWSClient *)wsClient {
|
||||||
if (self = [super init]) {
|
if (self = [super init]) {
|
||||||
_jsExecutor = [[DoricDebugJSEngine alloc] init];
|
_jsExecutor = [[DoricDebugJSEngine alloc] initWithWSClient:wsClient];
|
||||||
|
_theContextId = nil;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -150,7 +152,7 @@ - (DoricAsyncResult *)createContext:(NSString *)contextId script:(NSString *)scr
|
|||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
[self.jsExecutor prepareContext:contextId script:script source:source];
|
self.theContextId = contextId;
|
||||||
[ret setupResult:@YES];
|
[ret setupResult:@YES];
|
||||||
} @catch (NSException *exception) {
|
} @catch (NSException *exception) {
|
||||||
[ret setupError:exception];
|
[ret setupError:exception];
|
||||||
@ -166,7 +168,9 @@ - (DoricAsyncResult *)destroyContext:(NSString *)contextId {
|
|||||||
__strong typeof(_self) self = _self;
|
__strong typeof(_self) self = _self;
|
||||||
if (!self) return;
|
if (!self) return;
|
||||||
@try {
|
@try {
|
||||||
[self.jsExecutor destroyContext:contextId];
|
if ([contextId isEqualToString:self.theContextId]) {
|
||||||
|
[DoricDev.instance stopDebugging:NO];
|
||||||
|
}
|
||||||
[ret setupResult:@YES];
|
[ret setupResult:@YES];
|
||||||
} @catch (NSException *exception) {
|
} @catch (NSException *exception) {
|
||||||
[ret setupError:exception];
|
[ret setupError:exception];
|
||||||
|
@ -24,11 +24,11 @@
|
|||||||
#import <JavaScriptCore/JavaScriptCore.h>
|
#import <JavaScriptCore/JavaScriptCore.h>
|
||||||
|
|
||||||
#import <DoricCore/DoricJSEngine.h>
|
#import <DoricCore/DoricJSEngine.h>
|
||||||
|
#import "DoricWSClient.h"
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface DoricDebugJSEngine : DoricJSEngine
|
@interface DoricDebugJSEngine : DoricJSEngine
|
||||||
|
- (instancetype)initWithWSClient:(DoricWSClient *)wsClient;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -22,68 +22,22 @@
|
|||||||
|
|
||||||
#import "DoricContext.h"
|
#import "DoricContext.h"
|
||||||
#import "DoricDebugJSEngine.h"
|
#import "DoricDebugJSEngine.h"
|
||||||
#import "DoricJSRemoteExecutor.h"
|
#import "DoricRemoteJSExecutor.h"
|
||||||
#import "DoricUtil.h"
|
|
||||||
#import "NSString+JsonString.h"
|
|
||||||
#import "DoricDev.h"
|
|
||||||
|
|
||||||
@interface DoricDebugMonitor : NSObject <DoricMonitorProtocol>
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation DoricDebugMonitor
|
|
||||||
- (void)onException:(NSException *)exception inContext:(DoricContext *)context {
|
|
||||||
DoricLog(@"DefaultMonitor - source: %@- onException - %@", context.source, exception.reason);
|
|
||||||
NSDictionary *jsonDic = @{
|
|
||||||
@"cmd": @"EXCEPTION",
|
|
||||||
@"data": @{
|
|
||||||
@"source": [context.source stringByReplacingOccurrencesOfString:@".js" withString:@".ts"],
|
|
||||||
@"exception": exception.reason
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NSString *jsonStr = [NSString dc_convertToJsonWithDic:jsonDic];
|
|
||||||
[[DoricDev instance] sendDevCommand:jsonStr];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)onLog:(DoricLogType)type message:(NSString *)message {
|
|
||||||
DoricLog(message);
|
|
||||||
|
|
||||||
NSString *typeString = @"DEFAULT";
|
|
||||||
if (type == DoricLogTypeDebug) {
|
|
||||||
typeString = @"DEFAULT";
|
|
||||||
} else if (type == DoricLogTypeWarning) {
|
|
||||||
typeString = @"WARN";
|
|
||||||
} else if (type == DoricLogTypeError) {
|
|
||||||
typeString = @"ERROR";
|
|
||||||
}
|
|
||||||
|
|
||||||
NSDictionary *jsonDic = @{
|
|
||||||
@"cmd": @"LOG",
|
|
||||||
@"data": @{
|
|
||||||
@"type": typeString,
|
|
||||||
@"message": message
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NSString *jsonStr = [NSString dc_convertToJsonWithDic:jsonDic];
|
|
||||||
[[DoricDev instance] sendDevCommand:jsonStr];
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface DoricDebugJSEngine ()
|
@interface DoricDebugJSEngine ()
|
||||||
|
@property(nonatomic, weak) DoricWSClient *wsClient;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation DoricDebugJSEngine
|
@implementation DoricDebugJSEngine
|
||||||
|
|
||||||
- (instancetype)init {
|
- (instancetype)initWithWSClient:(DoricWSClient *)wsClient {
|
||||||
if (self = [super init]) {
|
if (self = [super init]) {
|
||||||
|
_wsClient = wsClient;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)initJSEngine {
|
- (void)initJSEngine {
|
||||||
[self.registry registerMonitor:[DoricDebugMonitor new]];
|
self.jsExecutor = [[DoricRemoteJSExecutor alloc] initWithWSClient:self.wsClient];
|
||||||
self.jsExecutor = [[DoricJSRemoteExecutor alloc] init];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -19,10 +19,12 @@
|
|||||||
//
|
//
|
||||||
// Created by jingpeng.wang on 2020/2/25.
|
// Created by jingpeng.wang on 2020/2/25.
|
||||||
//
|
//
|
||||||
|
#import "DoricWSClient.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface DoricDev : NSObject
|
@interface DoricDev : NSObject
|
||||||
|
@property(nonatomic, strong) DoricWSClient *wsClient;
|
||||||
+ (instancetype)instance;
|
+ (instancetype)instance;
|
||||||
|
|
||||||
- (void)openDevMode;
|
- (void)openDevMode;
|
||||||
@ -33,8 +35,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
- (void)connectDevKit:(NSString *)url;
|
- (void)connectDevKit:(NSString *)url;
|
||||||
|
|
||||||
- (void)sendDevCommand:(NSString *)command;
|
- (void)startDebugging:(NSString *)source;
|
||||||
|
|
||||||
|
- (void)stopDebugging:(BOOL)resume;
|
||||||
|
|
||||||
|
- (void)reload:(NSString *)source script:(NSString *)script;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -20,20 +20,50 @@
|
|||||||
// Created by jingpeng.wang on 2020/2/25.
|
// Created by jingpeng.wang on 2020/2/25.
|
||||||
//
|
//
|
||||||
#import <DoricCore/Doric.h>
|
#import <DoricCore/Doric.h>
|
||||||
#import <DoricCore/DoricContextManager.h>
|
|
||||||
#import <DoricCore/DoricNativeDriver.h>
|
#import <DoricCore/DoricNativeDriver.h>
|
||||||
#import <DoricCore/DoricConstant.h>
|
#import <DoricCore/DoricContextManager.h>
|
||||||
|
|
||||||
#import "DoricDev.h"
|
#import "DoricDev.h"
|
||||||
#import "DoricWSClient.h"
|
|
||||||
#import "DoricDebugDriver.h"
|
#import "DoricDebugDriver.h"
|
||||||
#import "DoricDevViewController.h"
|
#import "DoricDevViewController.h"
|
||||||
#import "DoricDevMonitor.h"
|
#import "DoricDevMonitor.h"
|
||||||
|
|
||||||
|
@interface DoricContextDebuggable : NSObject
|
||||||
|
@property(nonatomic, weak) DoricContext *doricContext;
|
||||||
|
@property(nonatomic, weak) id <DoricDriverProtocol> nativeDriver;
|
||||||
|
@property(nonatomic, weak) DoricWSClient *wsClient;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation DoricContextDebuggable
|
||||||
|
- (instancetype)initWithWSClient:(DoricWSClient *)client context:(DoricContext *)context {
|
||||||
|
if (self = [super init]) {
|
||||||
|
_wsClient = client;
|
||||||
|
_doricContext = context;
|
||||||
|
_nativeDriver = context.driver;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)startDebug {
|
||||||
|
[self.doricContext setDriver:[[DoricDebugDriver alloc] initWithWSClient:self.wsClient]];
|
||||||
|
[self.doricContext reload:self.doricContext.script];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)stopDebug:(BOOL)resume {
|
||||||
|
id <DoricDriverProtocol> driver = self.doricContext.driver;
|
||||||
|
if ([driver isKindOfClass:DoricDebugDriver.class]) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (resume) {
|
||||||
|
self.doricContext.driver = self.nativeDriver;
|
||||||
|
[self.doricContext reload:self.doricContext.script];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
@interface DoricDev ()
|
@interface DoricDev ()
|
||||||
@property(nonatomic, strong) DoricWSClient *wsclient;
|
@property(nonatomic, strong) DoricContextDebuggable *debuggable;
|
||||||
@property(nonatomic, strong) DoricContext *context;
|
|
||||||
@property(nonatomic, strong) DoricDebugDriver *driver;
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation DoricDev
|
@implementation DoricDev
|
||||||
@ -43,10 +73,6 @@ - (instancetype)init {
|
|||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onOpenEvent) name:@"OpenEvent" object:nil];
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onOpenEvent) name:@"OpenEvent" object:nil];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onEOFEvent) name:@"EOFEvent" object:nil];
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onEOFEvent) name:@"EOFEvent" object:nil];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onConnectExceptionEvent) name:@"ConnectExceptionEvent" object:nil];
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onConnectExceptionEvent) name:@"ConnectExceptionEvent" object:nil];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onStartDebugEvent:) name:@"StartDebugEvent" object:nil];
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onEnterDebugEvent) name:@"EnterDebugEvent" object:nil];
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onStopDebugEvent) name:@"StopDebugEvent" object:nil];
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onDebuggerReadyEvent) name:@"DebuggerReadyEvent" object:nil];
|
|
||||||
[DoricNativeDriver.instance.registry registerMonitor:[DoricDevMonitor new]];
|
[DoricNativeDriver.instance.registry registerMonitor:[DoricDevMonitor new]];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
@ -75,25 +101,21 @@ - (void)openDevMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)closeDevMode {
|
- (void)closeDevMode {
|
||||||
if (self.wsclient) {
|
if (self.wsClient) {
|
||||||
[self.wsclient close];
|
[self.wsClient close];
|
||||||
self.wsclient = nil;
|
self.wsClient = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isInDevMode {
|
- (BOOL)isInDevMode {
|
||||||
return self.wsclient != nil;
|
return self.wsClient != nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)connectDevKit:(NSString *)url {
|
- (void)connectDevKit:(NSString *)url {
|
||||||
if (self.wsclient) {
|
if (self.wsClient) {
|
||||||
[self.wsclient close];
|
[self.wsClient close];
|
||||||
}
|
}
|
||||||
self.wsclient = [[DoricWSClient alloc] initWithUrl:url];
|
self.wsClient = [[DoricWSClient alloc] initWithUrl:url];
|
||||||
}
|
|
||||||
|
|
||||||
- (void)sendDevCommand:(NSString *)command {
|
|
||||||
[self.wsclient send:command];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)onOpenEvent {
|
- (void)onOpenEvent {
|
||||||
@ -108,34 +130,51 @@ - (void)onConnectExceptionEvent {
|
|||||||
ShowToast(@"dev kit connection exception", DoricGravityBottom);
|
ShowToast(@"dev kit connection exception", DoricGravityBottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)onStartDebugEvent:(NSNotification *)notification {
|
- (DoricContext *)matchContext:(NSString *)source {
|
||||||
NSString *contextId = notification.object;
|
for (DoricContext *context in [DoricContextManager.instance aliveContexts]) {
|
||||||
ShowToast(contextId, DoricGravityBottom);
|
if ([source containsString:context.source] || [context.source isEqualToString:@"__dev__"]) {
|
||||||
for (DoricContext *context in [[DoricContextManager instance] aliveContexts]) {
|
return context;
|
||||||
BOOL result = [context.contextId compare:contextId] == NSOrderedSame;
|
|
||||||
if (result) {
|
|
||||||
_context = context;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)reload:(NSString *)source script:(NSString *)script {
|
||||||
|
DoricContext *context = [self matchContext:source];
|
||||||
|
if (context) {
|
||||||
|
if ([context.driver isKindOfClass:DoricDebugDriver.class]) {
|
||||||
|
DoricLog(@"Context source %@ in debugging,skip reload", source);
|
||||||
|
} else {
|
||||||
|
DoricLog(@"Context reload :id %@,source %@", context.contextId, source);
|
||||||
|
[context reload:script];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DoricLog(@"Cannot find context source %@ for reload", source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)onEnterDebugEvent {
|
- (void)startDebugging:(NSString *)source {
|
||||||
_driver = [DoricDebugDriver new];
|
[self.debuggable stopDebug:YES];
|
||||||
|
DoricContext *context = [self matchContext:source];
|
||||||
|
if (context) {
|
||||||
|
[self.wsClient sendToDebugger:@"DEBUG_RES" payload:@{
|
||||||
|
@"contextId": context.contextId
|
||||||
|
}];
|
||||||
|
self.debuggable = [[DoricContextDebuggable alloc] initWithWSClient:self.wsClient context:context];
|
||||||
|
[self.debuggable startDebug];
|
||||||
|
} else {
|
||||||
|
DoricLog(@"Cannot find context source %@ for debugging", source);
|
||||||
|
[self.wsClient sendToDebugger:@"DEBUG_STOP" payload:@{
|
||||||
|
@"msg": @"Cannot find suitable alive context for debugging"
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
- (void)onStopDebugEvent {
|
- (void)stopDebugging:(BOOL)resume {
|
||||||
_context.driver = [DoricNativeDriver instance];
|
[self.wsClient sendToDebugger:@"DEBUG_STOP" payload:@{
|
||||||
_context.rootNode.viewId = nil;
|
@"msg": @"Stop debugging"
|
||||||
[_context callEntity:DORIC_ENTITY_INIT, _context.extra, nil];
|
}];
|
||||||
[_context callEntity:DORIC_ENTITY_CREATE, nil];
|
[self.debuggable stopDebug:resume];
|
||||||
[_context callEntity:DORIC_ENTITY_BUILD withArgumentsArray:@[_context.initialParams]];
|
self.debuggable = nil;
|
||||||
}
|
|
||||||
|
|
||||||
- (void)onDebuggerReadyEvent {
|
|
||||||
_context.driver = _driver;
|
|
||||||
_context.rootNode.viewId = nil;
|
|
||||||
[_context callEntity:DORIC_ENTITY_INIT, _context.extra, nil];
|
|
||||||
[_context callEntity:DORIC_ENTITY_CREATE, nil];
|
|
||||||
[_context callEntity:DORIC_ENTITY_BUILD withArgumentsArray:@[_context.initialParams]];
|
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright [2019] [Doric.Pub]
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
//
|
//
|
||||||
// DoricDevMonitor.h
|
// DoricDevMonitor.h
|
||||||
// DoricDevkit
|
// DoricDevkit
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright [2019] [Doric.Pub]
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
//
|
//
|
||||||
// DoricDevMonitor.m
|
// DoricDevMonitor.m
|
||||||
// DoricDevkit
|
// DoricDevkit
|
||||||
@ -8,7 +23,6 @@
|
|||||||
#import "DoricDevMonitor.h"
|
#import "DoricDevMonitor.h"
|
||||||
|
|
||||||
#import "DoricDev.h"
|
#import "DoricDev.h"
|
||||||
#import "NSString+JsonString.h"
|
|
||||||
#import "Doric.h"
|
#import "Doric.h"
|
||||||
|
|
||||||
@implementation DoricDevMonitor
|
@implementation DoricDevMonitor
|
||||||
@ -16,16 +30,11 @@ - (void)onException:(NSException *)exception inContext:(DoricContext *)context {
|
|||||||
if (!DoricDev.instance.isInDevMode) {
|
if (!DoricDev.instance.isInDevMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NSDictionary *jsonDic = @{
|
[DoricDev.instance.wsClient sendToServer:@"EXCEPTION"
|
||||||
@"cmd": @"EXCEPTION",
|
payload:@{
|
||||||
@"data": @{
|
|
||||||
@"source": [context.source stringByReplacingOccurrencesOfString:@".js" withString:@".ts"],
|
@"source": [context.source stringByReplacingOccurrencesOfString:@".js" withString:@".ts"],
|
||||||
@"exception": exception.reason
|
@"exception": exception.reason
|
||||||
}
|
}];
|
||||||
};
|
|
||||||
|
|
||||||
NSString *jsonStr = [NSString dc_convertToJsonWithDic:jsonDic];
|
|
||||||
[[DoricDev instance] sendDevCommand:jsonStr];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)onLog:(DoricLogType)type message:(NSString *)message {
|
- (void)onLog:(DoricLogType)type message:(NSString *)message {
|
||||||
@ -33,23 +42,16 @@ - (void)onLog:(DoricLogType)type message:(NSString *)message {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NSString *typeString = @"DEFAULT";
|
NSString *typeString = @"DEFAULT";
|
||||||
if (type == DoricLogTypeDebug) {
|
if (type == DoricLogTypeWarning) {
|
||||||
typeString = @"DEFAULT";
|
|
||||||
} else if (type == DoricLogTypeWarning) {
|
|
||||||
typeString = @"WARN";
|
typeString = @"WARN";
|
||||||
} else if (type == DoricLogTypeError) {
|
} else if (type == DoricLogTypeError) {
|
||||||
typeString = @"ERROR";
|
typeString = @"ERROR";
|
||||||
}
|
}
|
||||||
|
|
||||||
NSDictionary *jsonDic = @{
|
[DoricDev.instance.wsClient sendToServer:@"EXCEPTION"
|
||||||
@"cmd": @"LOG",
|
payload:@{
|
||||||
@"data": @{
|
|
||||||
@"type": typeString,
|
@"type": typeString,
|
||||||
@"message": message
|
@"message": message
|
||||||
}
|
}];
|
||||||
};
|
|
||||||
|
|
||||||
NSString *jsonStr = [NSString dc_convertToJsonWithDic:jsonDic];
|
|
||||||
[[DoricDev instance] sendDevCommand:jsonStr];
|
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#import "DoricDev.h"
|
#import "DoricDev.h"
|
||||||
#import "DoricDevViewController.h"
|
#import "DoricDevViewController.h"
|
||||||
#import "DoricJSRemoteExecutor.h"
|
|
||||||
#import "QRScanViewController.h"
|
#import "QRScanViewController.h"
|
||||||
|
|
||||||
@interface DoricDevViewController () <UITableViewDelegate, UITableViewDataSource>
|
@interface DoricDevViewController () <UITableViewDelegate, UITableViewDataSource>
|
||||||
@ -51,7 +50,6 @@ - (void)viewDidLoad {
|
|||||||
}
|
}
|
||||||
if (self.isSimulator) {
|
if (self.isSimulator) {
|
||||||
NSString *result = @"127.0.0.1";
|
NSString *result = @"127.0.0.1";
|
||||||
[DoricJSRemoteExecutor configIp:result];
|
|
||||||
[[DoricDev instance] connectDevKit:[NSString stringWithFormat:@"ws://%@:7777", result]];
|
[[DoricDev instance] connectDevKit:[NSString stringWithFormat:@"ws://%@:7777", result]];
|
||||||
ShowToast([NSString stringWithFormat:@"Connected to %@", result], DoricGravityBottom);
|
ShowToast([NSString stringWithFormat:@"Connected to %@", result], DoricGravityBottom);
|
||||||
} else {
|
} else {
|
||||||
@ -94,9 +92,6 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
|
|||||||
@"source": [context.source stringByReplacingOccurrencesOfString:@".js" withString:@".ts"]
|
@"source": [context.source stringByReplacingOccurrencesOfString:@".js" withString:@".ts"]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
NSString *jsonStr = [NSString dc_convertToJsonWithDic:jsonDic];
|
|
||||||
[[DoricDev instance] sendDevCommand:jsonStr];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -1,213 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2019] [Doric.Pub]
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
//
|
|
||||||
// DoricJSRemoteExecutor.m
|
|
||||||
// Doric
|
|
||||||
//
|
|
||||||
// Created by 王劲鹏 on 2019/10/31.
|
|
||||||
//
|
|
||||||
#import "DoricJSRemoteExecutor.h"
|
|
||||||
#import "SRWebSocket.h"
|
|
||||||
#import "DoricUtil.h"
|
|
||||||
#import "DoricJSRemoteArgType.h"
|
|
||||||
#import "NSString+JsonString.h"
|
|
||||||
|
|
||||||
static NSString *debuggerAddress = @"";
|
|
||||||
|
|
||||||
typedef id (^Block0)(void);
|
|
||||||
typedef id (^Block1)(id arg0);
|
|
||||||
typedef id (^Block2)(id arg0, id arg1);
|
|
||||||
typedef id (^Block3)(id arg0, id arg1, id arg2);
|
|
||||||
typedef id (^Block4)(id arg0, id arg1, id arg2, id arg3);
|
|
||||||
typedef id (^Block5)(id arg0, id arg1, id arg2, id arg3, id arg4);
|
|
||||||
|
|
||||||
@interface DoricJSRemoteExecutor () <SRWebSocketDelegate>
|
|
||||||
@property(nonatomic, strong) SRWebSocket *srWebSocket;
|
|
||||||
@property(nonatomic, strong) NSMutableDictionary <NSString *, id> *blockMDic;
|
|
||||||
@property(nonatomic, strong) JSValue *temp;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation DoricJSRemoteExecutor
|
|
||||||
- (instancetype)init {
|
|
||||||
if (self = [super init]) {
|
|
||||||
[self srWebSocket];
|
|
||||||
_semaphore = dispatch_semaphore_create(0);
|
|
||||||
DC_LOCK(self.semaphore);
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - SRWebSocketDelegate
|
|
||||||
- (void)webSocketDidOpen:(SRWebSocket *)webSocket {
|
|
||||||
DoricLog(@"debugger webSocketDidOpen");
|
|
||||||
DC_UNLOCK(self.semaphore);
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"DebuggerReadyEvent" object:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload {
|
|
||||||
DoricLog(@"debugger webSocketdidReceivePong");
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message {
|
|
||||||
NSData *jsonData = [message dataUsingEncoding:NSUTF8StringEncoding];
|
|
||||||
NSError *err;
|
|
||||||
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
|
|
||||||
options:NSJSONReadingMutableContainers
|
|
||||||
error:&err];
|
|
||||||
if (err) {
|
|
||||||
DoricLog(@"debugger webSocketdidReceiveMessage parse error:%@", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NSString *cmd = [[dic valueForKey:@"cmd"] copy];
|
|
||||||
|
|
||||||
if ([cmd isEqualToString:@"injectGlobalJSFunction"]) {
|
|
||||||
NSString *name = [dic valueForKey:@"name"];
|
|
||||||
NSArray *argsArr = [dic valueForKey:@"arguments"];
|
|
||||||
NSMutableArray *argsMarr = [NSMutableArray new];
|
|
||||||
for (NSUInteger i = 0; i < argsArr.count; i++) {
|
|
||||||
[argsMarr addObject:argsArr[i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
id result;
|
|
||||||
id tmpBlk = self.blockMDic[name];
|
|
||||||
if (argsArr.count == 0) {
|
|
||||||
result = ((Block0) tmpBlk)();
|
|
||||||
} else if (argsArr.count == 1) {
|
|
||||||
result = ((Block1) tmpBlk)(argsArr[0]);
|
|
||||||
} else if (argsArr.count == 2) {
|
|
||||||
result = ((Block2)tmpBlk)(argsArr[0], argsArr[1]);
|
|
||||||
} else if (argsArr.count == 3) {
|
|
||||||
result = ((Block3)tmpBlk)(argsArr[0], argsArr[1], argsArr[2]);
|
|
||||||
} else if (argsArr.count == 4) {
|
|
||||||
result = ((Block4)tmpBlk)(argsArr[0], argsArr[1], argsArr[2], argsArr[3]);
|
|
||||||
} else if (argsArr.count == 5) {
|
|
||||||
result = ((Block5)tmpBlk)(argsArr[0], argsArr[1], argsArr[2], argsArr[3], argsArr[4]);
|
|
||||||
}else {
|
|
||||||
DoricLog(@"error:args to more than 5. args:%@",argsArr);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if ([cmd isEqualToString:@"invokeMethod"]) {
|
|
||||||
@try {
|
|
||||||
self.temp = [JSValue valueWithObject:[dic valueForKey:@"result"] inContext:nil];
|
|
||||||
} @catch (NSException *exception) {
|
|
||||||
DoricLog(@"debugger ", NSStringFromSelector(_cmd), exception.reason);
|
|
||||||
} @finally {
|
|
||||||
DC_UNLOCK(self.semaphore);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error {
|
|
||||||
DoricLog(@"debugger webSocketdidFailWithError");
|
|
||||||
DC_UNLOCK(self.semaphore);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean {
|
|
||||||
DoricLog(@"debugger webSocketdidCloseWithCode");
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"StopDebugEvent" object:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - DoricJSExecutorProtocol
|
|
||||||
- (NSString *)loadJSScript:(NSString *)script source:(NSString *)source {
|
|
||||||
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)injectGlobalJSObject:(NSString *)name obj:(id)obj {
|
|
||||||
if ([obj isKindOfClass:NSClassFromString(@"NSBlock")]) {
|
|
||||||
self.blockMDic[name] = obj;
|
|
||||||
}
|
|
||||||
NSDictionary *jsonDic = @{
|
|
||||||
@"cmd": @"injectGlobalJSFunction",
|
|
||||||
@"name": name
|
|
||||||
};
|
|
||||||
|
|
||||||
NSString *jsonStr = [NSString dc_convertToJsonWithDic:jsonDic];
|
|
||||||
if (!jsonStr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
[self.srWebSocket send:jsonStr];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (JSValue *)invokeObject:(NSString *)objName method:(NSString *)funcName args:(NSArray *)args {
|
|
||||||
|
|
||||||
NSMutableArray *argsMArr = [NSMutableArray new];
|
|
||||||
for (id arg in args) {
|
|
||||||
NSDictionary *dic = [self dicForArg:arg];
|
|
||||||
[argsMArr addObject:dic];
|
|
||||||
}
|
|
||||||
|
|
||||||
NSArray *argsArr = [argsMArr copy];
|
|
||||||
|
|
||||||
NSDictionary *jsonDic = @{
|
|
||||||
@"cmd": @"invokeMethod",
|
|
||||||
@"objectName": objName,
|
|
||||||
@"functionName": funcName,
|
|
||||||
@"values": argsArr
|
|
||||||
};
|
|
||||||
|
|
||||||
NSString *jsonStr = [NSString dc_convertToJsonWithDic:jsonDic];
|
|
||||||
if (!jsonStr) {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
[self.srWebSocket send:jsonStr];
|
|
||||||
DC_LOCK(self.semaphore);
|
|
||||||
|
|
||||||
return self.temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSDictionary *)dicForArg:(id)arg {
|
|
||||||
DoricJSRemoteArgType type = DoricargTypeWithArg(arg);
|
|
||||||
if (type == DoricJSRemoteArgTypeObject || type == DoricJSRemoteArgTypeArray) {
|
|
||||||
NSString *jsonStr = [NSString dc_convertToJsonWithDic:(NSDictionary *)arg];
|
|
||||||
arg = jsonStr;
|
|
||||||
}
|
|
||||||
NSDictionary *dic = @{
|
|
||||||
@"type": @(type),
|
|
||||||
@"value": arg
|
|
||||||
};
|
|
||||||
return dic;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)configIp:(NSString *)ip {
|
|
||||||
debuggerAddress = [[@"ws://" stringByAppendingString:ip] stringByAppendingString:@":2080"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)close {
|
|
||||||
[self.srWebSocket close];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Properties
|
|
||||||
- (SRWebSocket *)srWebSocket {
|
|
||||||
if (!_srWebSocket) {
|
|
||||||
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:debuggerAddress] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10];
|
|
||||||
_srWebSocket = [[SRWebSocket alloc] initWithURLRequest:request];
|
|
||||||
_srWebSocket.delegate = self;
|
|
||||||
[_srWebSocket open];
|
|
||||||
}
|
|
||||||
return _srWebSocket;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSMutableDictionary *)blockMDic {
|
|
||||||
if (!_blockMDic) {
|
|
||||||
_blockMDic = [NSMutableDictionary new];
|
|
||||||
}
|
|
||||||
return _blockMDic;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
@ -14,24 +14,20 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//
|
//
|
||||||
// DoricJSRemoteExecutor.h
|
// DoricRemoteJSExecutor.h
|
||||||
// Pods
|
// DoricDevkit
|
||||||
//
|
//
|
||||||
// Created by 王劲鹏 on 2019/10/31.
|
// Created by pengfei.zhou on 2021/2/22.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import <DoricCore/DoricJSExecutorProtocol.h>
|
#import <DoricCore/DoricJSExecutorProtocol.h>
|
||||||
|
#import "DoricWSClient.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface DoricJSRemoteExecutor : NSObject <DoricJSExecutorProtocol>
|
@interface DoricRemoteJSExecutor : NSObject <DoricJSExecutorProtocol>
|
||||||
|
- (instancetype)initWithWSClient:(DoricWSClient *)wsClient;
|
||||||
@property(nonatomic, strong) dispatch_semaphore_t semaphore;
|
|
||||||
|
|
||||||
+ (void)configIp:(NSString *)ip;
|
|
||||||
|
|
||||||
- (void)close;
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
194
doric-iOS/Devkit/Classes/DoricRemoteJSExecutor.m
Normal file
194
doric-iOS/Devkit/Classes/DoricRemoteJSExecutor.m
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
/*
|
||||||
|
* Copyright [2019] [Doric.Pub]
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
//
|
||||||
|
// DoricRemoteJSExecutor.m
|
||||||
|
// DoricDevkit
|
||||||
|
//
|
||||||
|
// Created by pengfei.zhou on 2021/2/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "DoricRemoteJSExecutor.h"
|
||||||
|
#import "NSString+JsonString.h"
|
||||||
|
#import <DoricCore/Doric.h>
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSUInteger, DoricJSRemoteArgType) {
|
||||||
|
DoricJSRemoteArgTypeNil = 0,
|
||||||
|
DoricJSRemoteArgTypeNumber,
|
||||||
|
DoricJSRemoteArgTypeBool,
|
||||||
|
DoricJSRemoteArgTypeString,
|
||||||
|
DoricJSRemoteArgTypeObject,
|
||||||
|
DoricJSRemoteArgTypeArray,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef id (^Block0)(void);
|
||||||
|
|
||||||
|
typedef id (^Block1)(id arg0);
|
||||||
|
|
||||||
|
typedef id (^Block2)(id arg0, id arg1);
|
||||||
|
|
||||||
|
typedef id (^Block3)(id arg0, id arg1, id arg2);
|
||||||
|
|
||||||
|
typedef id (^Block4)(id arg0, id arg1, id arg2, id arg3);
|
||||||
|
|
||||||
|
typedef id (^Block5)(id arg0, id arg1, id arg2, id arg3, id arg4);
|
||||||
|
|
||||||
|
@interface DoricRemoteJSExecutor () <DoricWSClientInterceptor>
|
||||||
|
@property(nonatomic, weak) DoricWSClient *wsClient;
|
||||||
|
@property(nonatomic, strong) NSMutableDictionary <NSString *, id> *blockMDic;
|
||||||
|
@property(nonatomic, strong) JSValue *temp;
|
||||||
|
@property(nonatomic, strong) dispatch_semaphore_t semaphore;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation DoricRemoteJSExecutor
|
||||||
|
- (instancetype)initWithWSClient:(DoricWSClient *)wsClient {
|
||||||
|
if (self = [super init]) {
|
||||||
|
_wsClient = wsClient;
|
||||||
|
[_wsClient addInterceptor:self];
|
||||||
|
_blockMDic = [NSMutableDictionary new];
|
||||||
|
_semaphore = dispatch_semaphore_create(0);
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)loadJSScript:(NSString *)script source:(NSString *)source {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)injectGlobalJSObject:(NSString *)name obj:(id)obj {
|
||||||
|
if ([obj isKindOfClass:NSClassFromString(@"NSBlock")]) {
|
||||||
|
self.blockMDic[name] = obj;
|
||||||
|
[self.wsClient sendToDebugger:@"injectGlobalJSFunction" payload:@{
|
||||||
|
@"name": name,
|
||||||
|
}];
|
||||||
|
} else if ([obj isKindOfClass:NSNumber.class]) {
|
||||||
|
[self.wsClient sendToDebugger:@"injectGlobalJSObject" payload:@{
|
||||||
|
@"name": name,
|
||||||
|
@"type": @(DoricJSRemoteArgTypeNumber),
|
||||||
|
@"value": obj,
|
||||||
|
}];
|
||||||
|
} else if ([obj isKindOfClass:NSString.class]) {
|
||||||
|
[self.wsClient sendToDebugger:@"injectGlobalJSObject" payload:@{
|
||||||
|
@"name": name,
|
||||||
|
@"type": @(DoricJSRemoteArgTypeString),
|
||||||
|
@"value": obj,
|
||||||
|
}];
|
||||||
|
} else if ([obj isKindOfClass:NSObject.class]) {
|
||||||
|
[self.wsClient sendToDebugger:@"injectGlobalJSObject" payload:@{
|
||||||
|
@"name": name,
|
||||||
|
@"type": @(DoricJSRemoteArgTypeObject),
|
||||||
|
@"value": obj,
|
||||||
|
}];
|
||||||
|
} else if ([obj isKindOfClass:NSArray.class]) {
|
||||||
|
[self.wsClient sendToDebugger:@"injectGlobalJSObject" payload:@{
|
||||||
|
@"name": name,
|
||||||
|
@"type": @(DoricJSRemoteArgTypeArray),
|
||||||
|
@"value": obj,
|
||||||
|
}];
|
||||||
|
} else if (obj == nil) {
|
||||||
|
[self.wsClient sendToDebugger:@"injectGlobalJSObject" payload:@{
|
||||||
|
@"name": name,
|
||||||
|
@"type": @(DoricJSRemoteArgTypeNil),
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (JSValue *)invokeObject:(NSString *)objName method:(NSString *)funcName args:(NSArray *)args {
|
||||||
|
|
||||||
|
NSMutableArray *argsMArr = [NSMutableArray new];
|
||||||
|
|
||||||
|
for (id arg in args) {
|
||||||
|
NSDictionary *dic = [self dicForArg:arg];
|
||||||
|
[argsMArr addObject:dic];
|
||||||
|
}
|
||||||
|
|
||||||
|
[self.wsClient sendToDebugger:@"invokeMethod" payload:@{
|
||||||
|
@"cmd": @"invokeMethod",
|
||||||
|
@"objectName": objName,
|
||||||
|
@"functionName": funcName,
|
||||||
|
@"values": [argsMArr copy]
|
||||||
|
}];
|
||||||
|
|
||||||
|
DC_LOCK(self.semaphore);
|
||||||
|
|
||||||
|
return self.temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDictionary *)dicForArg:(id)arg {
|
||||||
|
DoricJSRemoteArgType type = [self argType:arg];
|
||||||
|
if (type == DoricJSRemoteArgTypeObject || type == DoricJSRemoteArgTypeArray) {
|
||||||
|
NSString *jsonStr = [NSString dc_convertToJsonWithDic:arg];
|
||||||
|
arg = jsonStr;
|
||||||
|
}
|
||||||
|
NSDictionary *dic = @{
|
||||||
|
@"type": @(type),
|
||||||
|
@"value": arg
|
||||||
|
};
|
||||||
|
return dic;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (DoricJSRemoteArgType)argType:(id)arg {
|
||||||
|
DoricJSRemoteArgType type = DoricJSRemoteArgTypeNil;
|
||||||
|
if ([arg isKindOfClass:[NSNumber class]]) {
|
||||||
|
type = DoricJSRemoteArgTypeNumber;
|
||||||
|
} else if ([arg isKindOfClass:[NSString class]]) {
|
||||||
|
type = DoricJSRemoteArgTypeString;
|
||||||
|
} else if ([arg isKindOfClass:[NSDictionary class]]) {
|
||||||
|
type = DoricJSRemoteArgTypeObject;
|
||||||
|
} else if ([arg isKindOfClass:[NSMutableArray class]]) {
|
||||||
|
type = DoricJSRemoteArgTypeArray;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)interceptType:(NSString *)type command:(NSString *)cmd payload:(NSDictionary *)payload {
|
||||||
|
if ([type isEqualToString:@"D2C"]) {
|
||||||
|
if ([cmd isEqualToString:@"injectGlobalJSFunction"]) {
|
||||||
|
NSString *name = payload[@"name"];
|
||||||
|
NSArray *argsArr = payload[@"arguments"];
|
||||||
|
id tmpBlk = self.blockMDic[name];
|
||||||
|
id result;
|
||||||
|
if (argsArr.count == 0) {
|
||||||
|
result = ((Block0) tmpBlk)();
|
||||||
|
} else if (argsArr.count == 1) {
|
||||||
|
result = ((Block1) tmpBlk)(argsArr[0]);
|
||||||
|
} else if (argsArr.count == 2) {
|
||||||
|
result = ((Block2) tmpBlk)(argsArr[0], argsArr[1]);
|
||||||
|
} else if (argsArr.count == 3) {
|
||||||
|
result = ((Block3) tmpBlk)(argsArr[0], argsArr[1], argsArr[2]);
|
||||||
|
} else if (argsArr.count == 4) {
|
||||||
|
result = ((Block4) tmpBlk)(argsArr[0], argsArr[1], argsArr[2], argsArr[3]);
|
||||||
|
} else if (argsArr.count == 5) {
|
||||||
|
result = ((Block5) tmpBlk)(argsArr[0], argsArr[1], argsArr[2], argsArr[3], argsArr[4]);
|
||||||
|
} else {
|
||||||
|
DoricLog(@"error:args to more than 5. args:%@", argsArr);
|
||||||
|
result = nil;
|
||||||
|
}
|
||||||
|
} else if ([cmd isEqualToString:@"invokeMethod"]) {
|
||||||
|
@try {
|
||||||
|
self.temp = [JSValue valueWithObject:payload[@"result"] inContext:nil];
|
||||||
|
} @catch (NSException *exception) {
|
||||||
|
DoricLog(@"debugger ", NSStringFromSelector(_cmd), exception.reason);
|
||||||
|
} @finally {
|
||||||
|
DC_UNLOCK(self.semaphore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
@ -24,12 +24,22 @@
|
|||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@protocol DoricWSClientInterceptor <NSObject>
|
||||||
|
- (BOOL)interceptType:(NSString *)type command:(NSString *)cmd payload:(NSDictionary *)payload;
|
||||||
|
@end
|
||||||
|
|
||||||
@interface DoricWSClient : NSObject
|
@interface DoricWSClient : NSObject
|
||||||
- (instancetype)initWithUrl:(NSString *)url;
|
- (instancetype)initWithUrl:(NSString *)url;
|
||||||
|
|
||||||
- (void)send:(NSString *)command;
|
|
||||||
|
|
||||||
- (void)close;
|
- (void)close;
|
||||||
|
|
||||||
|
- (void)addInterceptor:(id <DoricWSClientInterceptor>)interceptor;
|
||||||
|
|
||||||
|
- (void)removeInterceptor:(id <DoricWSClientInterceptor>)interceptor;
|
||||||
|
|
||||||
|
- (void)sendToDebugger:(NSString *)cmd payload:(NSDictionary *)payload;
|
||||||
|
|
||||||
|
- (void)sendToServer:(NSString *)cmd payload:(NSDictionary *)payload;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -22,16 +22,20 @@
|
|||||||
|
|
||||||
#import "DoricWSClient.h"
|
#import "DoricWSClient.h"
|
||||||
#import "SRWebSocket.h"
|
#import "SRWebSocket.h"
|
||||||
#import "DoricUtil.h"
|
#import <DoricCore/Doric.h>
|
||||||
#import "DoricContextManager.h"
|
#import <DoricCore/DoricContextManager.h>
|
||||||
|
#import <DoricCore/NSString+JsonString.h>
|
||||||
|
#import "DoricDev.h"
|
||||||
|
|
||||||
@interface DoricWSClient () <SRWebSocketDelegate>
|
@interface DoricWSClient () <SRWebSocketDelegate>
|
||||||
@property(nonatomic, strong) SRWebSocket *websocket;
|
@property(nonatomic, strong) SRWebSocket *websocket;
|
||||||
|
@property(nonatomic, strong) NSHashTable <id <DoricWSClientInterceptor>> *interceptors;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation DoricWSClient
|
@implementation DoricWSClient
|
||||||
- (instancetype)initWithUrl:(NSString *)url {
|
- (instancetype)initWithUrl:(NSString *)url {
|
||||||
if (self = [super init]) {
|
if (self = [super init]) {
|
||||||
|
_interceptors = [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory];
|
||||||
_websocket = [[SRWebSocket alloc] initWithURL:[NSURL URLWithString:url]];
|
_websocket = [[SRWebSocket alloc] initWithURL:[NSURL URLWithString:url]];
|
||||||
_websocket.delegate = self;
|
_websocket.delegate = self;
|
||||||
[_websocket open];
|
[_websocket open];
|
||||||
@ -58,7 +62,27 @@ - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message {
|
|||||||
DoricLog(@"webSocketdidReceiveMessage parse error:%@", err);
|
DoricLog(@"webSocketdidReceiveMessage parse error:%@", err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NSString *cmd = [[dic valueForKey:@"cmd"] mutableCopy];
|
|
||||||
|
NSString *type = dic[@"type"];
|
||||||
|
NSString *cmd = dic[@"cmd"];
|
||||||
|
NSDictionary *payload = dic[@"payload"];
|
||||||
|
for (id <DoricWSClientInterceptor> interceptor in self.interceptors) {
|
||||||
|
if ([interceptor interceptType:type command:cmd payload:payload]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([cmd isEqualToString:@"DEBUG_REQ"]) {
|
||||||
|
NSString *source = payload[@"source"];
|
||||||
|
[DoricDev.instance startDebugging:source];
|
||||||
|
} else if ([cmd isEqualToString:@"DEBUG_STOP"]) {
|
||||||
|
[DoricDev.instance stopDebugging:YES];
|
||||||
|
} else if ([cmd isEqualToString:@"RELOAD"]) {
|
||||||
|
NSString *source = payload[@"source"];
|
||||||
|
NSString *script = payload[@"script"];
|
||||||
|
[DoricDev.instance reload:source script:script];
|
||||||
|
}
|
||||||
|
|
||||||
if ([cmd compare:@"SWITCH_TO_DEBUG"] == NSOrderedSame) {
|
if ([cmd compare:@"SWITCH_TO_DEBUG"] == NSOrderedSame) {
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"EnterDebugEvent" object:nil];
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"EnterDebugEvent" object:nil];
|
||||||
} else if ([cmd compare:@"RELOAD"] == NSOrderedSame) {
|
} else if ([cmd compare:@"RELOAD"] == NSOrderedSame) {
|
||||||
@ -82,8 +106,33 @@ - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reas
|
|||||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"EOFEvent" object:nil];
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"EOFEvent" object:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)send:(NSString *)command {
|
- (void)send:(NSDictionary *)command {
|
||||||
[_websocket send:command];
|
NSString *jsonStr = [NSString dc_convertToJsonWithDic:command];
|
||||||
|
[_websocket send:jsonStr];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)addInterceptor:(id <DoricWSClientInterceptor>)interceptor {
|
||||||
|
[self.interceptors addObject:interceptor];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)removeInterceptor:(id <DoricWSClientInterceptor>)interceptor {
|
||||||
|
[self.interceptors removeObject:interceptor];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)sendToDebugger:(NSString *)cmd payload:(NSDictionary *)payload {
|
||||||
|
[self send:@{
|
||||||
|
@"type": @"C2D",
|
||||||
|
@"cmd": cmd,
|
||||||
|
@"payload": payload,
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)sendToServer:(NSString *)cmd payload:(NSDictionary *)payload {
|
||||||
|
[self send:@{
|
||||||
|
@"type": @"C2S",
|
||||||
|
@"cmd": cmd,
|
||||||
|
@"payload": payload,
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)close {
|
- (void)close {
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#import <AVFoundation/AVFoundation.h>
|
#import <AVFoundation/AVFoundation.h>
|
||||||
#import <DoricCore/Doric.h>
|
#import <DoricCore/Doric.h>
|
||||||
#import <DoricDevkit/DoricDev.h>
|
#import <DoricDevkit/DoricDev.h>
|
||||||
#import "DoricJSRemoteExecutor.h"
|
|
||||||
|
|
||||||
@interface QRScanViewController () <AVCaptureMetadataOutputObjectsDelegate>
|
@interface QRScanViewController () <AVCaptureMetadataOutputObjectsDelegate>
|
||||||
@property(strong, nonatomic) AVCaptureDevice *device;
|
@property(strong, nonatomic) AVCaptureDevice *device;
|
||||||
@ -105,7 +104,6 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:
|
|||||||
NSString *result = qrObject.stringValue;
|
NSString *result = qrObject.stringValue;
|
||||||
NSLog(@"Scan result is %@", result);
|
NSLog(@"Scan result is %@", result);
|
||||||
[[DoricDev instance] connectDevKit:[NSString stringWithFormat:@"ws://%@:7777", result]];
|
[[DoricDev instance] connectDevKit:[NSString stringWithFormat:@"ws://%@:7777", result]];
|
||||||
[DoricJSRemoteExecutor configIp:result];
|
|
||||||
ShowToast([NSString stringWithFormat:@"Connected to %@", result], DoricGravityBottom);
|
ShowToast([NSString stringWithFormat:@"Connected to %@", result], DoricGravityBottom);
|
||||||
[self.navigationController popViewControllerAnimated:NO];
|
[self.navigationController popViewControllerAnimated:NO];
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
- (JSValue *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArray *)args;
|
- (JSValue *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArray *)args;
|
||||||
|
|
||||||
- (void)ensureRunOnJSThread:(dispatch_block_t)block;
|
- (void)ensureRunOnJSThread:(dispatch_block_t)block;
|
||||||
|
|
||||||
|
- (void)initJSEngine;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -96,6 +96,7 @@ - (instancetype)init {
|
|||||||
[self initJSExecutor];
|
[self initJSExecutor];
|
||||||
[self initDoricEnvironment];
|
[self initDoricEnvironment];
|
||||||
}];
|
}];
|
||||||
|
[self.registry registerMonitor:[DoricDefaultMonitor new]];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -126,7 +127,6 @@ - (void)threadRun {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)initJSEngine {
|
- (void)initJSEngine {
|
||||||
[self.registry registerMonitor:[DoricDefaultMonitor new]];
|
|
||||||
self.jsExecutor = [DoricJSCoreExecutor new];
|
self.jsExecutor = [DoricJSCoreExecutor new];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface NSString (JsonString)
|
@interface NSString (JsonString)
|
||||||
+ (NSString *)dc_convertToJsonWithDic:(NSDictionary *)dic;
|
+ (NSString *)dc_convertToJsonWithDic:(id)obj;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
#import "DoricUtil.h"
|
#import "DoricUtil.h"
|
||||||
|
|
||||||
@implementation NSString (JsonString)
|
@implementation NSString (JsonString)
|
||||||
+ (NSString *)dc_convertToJsonWithDic:(NSDictionary *)dic {
|
+ (NSString *)dc_convertToJsonWithDic:(id)obj {
|
||||||
NSError *err;
|
NSError *err;
|
||||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&err];
|
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:obj options:NSJSONWritingPrettyPrinted error:&err];
|
||||||
NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
//
|
|
||||||
// DoricJSRemoteArgType.h
|
|
||||||
// Doric
|
|
||||||
//
|
|
||||||
// Created by Insomnia on 2019/11/7.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
typedef NS_ENUM(NSUInteger, DoricJSRemoteArgType) {
|
|
||||||
DoricJSRemoteArgTypeNil = 0,
|
|
||||||
DoricJSRemoteArgTypeNumber,
|
|
||||||
DoricJSRemoteArgTypeBool,
|
|
||||||
DoricJSRemoteArgTypeString,
|
|
||||||
DoricJSRemoteArgTypeObject,
|
|
||||||
DoricJSRemoteArgTypeArray,
|
|
||||||
};
|
|
||||||
|
|
||||||
DoricJSRemoteArgType DoricargTypeWithArg(id arg);
|
|
||||||
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
@ -1,21 +0,0 @@
|
|||||||
//
|
|
||||||
// DoricJSRemoteArgType.m
|
|
||||||
// Doric
|
|
||||||
//
|
|
||||||
// Created by Insomnia on 2019/11/7.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "DoricJSRemoteArgType.h"
|
|
||||||
DoricJSRemoteArgType DoricargTypeWithArg(id arg) {
|
|
||||||
DoricJSRemoteArgType type = DoricJSRemoteArgTypeNil;
|
|
||||||
if ([arg isKindOfClass:[NSNumber class]]) {
|
|
||||||
type = DoricJSRemoteArgTypeNumber;
|
|
||||||
}else if ([arg isKindOfClass:[NSString class]]) {
|
|
||||||
type = DoricJSRemoteArgTypeString;
|
|
||||||
}else if ([arg isKindOfClass:[NSDictionary class]]) {
|
|
||||||
type = DoricJSRemoteArgTypeObject;
|
|
||||||
}else if ([arg isKindOfClass:[NSMutableArray class]]) {
|
|
||||||
type = DoricJSRemoteArgTypeArray;
|
|
||||||
}
|
|
||||||
return type;
|
|
||||||
}
|
|
Reference in New Issue
Block a user