LynxInspectorConsoleDelegate

A protocol (or interface) used to receive all Console messages from a LynxView instance.

INFO

Currently, it only supports getting BTS Console messages when using the PrimJS engine.

Syntax

Implement LynxInspectorConsoleDelegate protocol (or interface) and receive Console messages through the onConsoleMessage method.

iOS

LynxInspectorConsoleDelegate.h
@protocol LynxInspectorConsoleDelegate <NSObject>

- (void)onConsoleMessage:(NSString *)msg;

@end

Android

LynxInspectorConsoleDelegate.java
public interface LynxInspectorConsoleDelegate {
  void onConsoleMessage(String msg);
}

Harmony

LynxInspectorConsoleDelegate.ets
export interface LynxInspectorConsoleDelegate {
  onConsoleMessage: (msg: string) => void;
}

Data Format

All data is in the form of a JSON formatted string.

For Object type data, only the basic information of the Object is included. You can use getConsoleObject to get more detailed data.

onConsoleMessage

FieldTypeDescription
typestringThe log type, such as log, debug, info, error, warning, etc.
argsarray[argument]The log arguments, an array where each element is an argument object.

argument

FieldTypeDescription
typestringThe argument type, such as string, number, boolean, object, function, undefined, etc.
subtypestringOptional field, the subtype of the argument, such as array, null, error, etc. This is specified only for arguments of type object.
objectIdstringOptional field, the unique identifier when the argument is an Object type.
descriptionstringOptional field, a preview or description of the argument.
valueanyOptional field, the value of the argument.

Example

let testObj = { a: 1, b: 'test', c: true, d: undefined, e: null, f: { g: 2 } };
console.log('test object: ', testObj);

The code above will trigger the onConsoleMessage event, and the event data is as follows:

"{\"type\":\"log\",\"args\":[{\"value\":\"test object: \",\"type\":\"string\"},{\"type\":\"object\",\"objectId\":\"546729222512\",\"className\":\"Object\",\"description\":\"Object\"}]}"

Take the objectId field from the second argument and call the getConsoleObject method.

When needStringify is false, the returned data is as follows:

"[{\"name\":\"a\",\"value\":{\"description\":\"1\",\"value\":1,\"type\":\"number\"}},{\"name\":\"b\",\"value\":{\"value\":\"test\",\"type\":\"string\"}},{\"name\":\"c\",\"value\":{\"value\":true,\"type\":\"boolean\"}},{\"name\":\"d\",\"value\":{\"type\":\"undefined\"}},{\"name\":\"e\",\"value\":{\"subtype\":\"null\",\"value\":null,\"type\":\"object\"}},{\"name\":\"f\",\"value\":{\"type\":\"object\",\"objectId\":\"546729222592\",\"className\":\"Object\",\"description\":\"Object\"}},{\"name\":\"__proto__\",\"value\":{\"type\":\"object\",\"objectId\":\"546824040688\",\"className\":\"Object\",\"description\":\"Object\"}}]"

When needStringify is true, the returned data is as follows:

"{\n\t\"a\": 1,\n\t\"b\": \"test\",\n\t\"c\": true,\n\t\"e\": null,\n\t\"f\": {\n\t\t\"g\": 2\n\t}\n}"

Usage Example

Implementation Steps

  1. Implement LynxInspectorConsoleDelegate.
  2. Get the LynxBaseInspectorOwner instance.
  3. Register LynxInspectorConsoleDelegate.
  4. Get detailed Object information.

Code Example

iOS

TestConsoleDelegate.h
#import <Foundation/Foundation.h>
#import <Lynx/LynxBaseInspectorOwner.h>
#import <Lynx/LynxInspectorConsoleDelegate.h>

@interface TestConsoleDelegate : NSObject <LynxInspectorConsoleDelegate>

- (instancetype)initWithInspectorOwner:(id<LynxBaseInspectorOwner>)owner;

@end
TestConsoleDelegate.m
#import "TestConsoleDelegate.h"

@implementation TestConsoleDelegate {
  __weak id<LynxBaseInspectorOwner> _owner;
}

- (instancetype)initWithInspectorOwner:(id<LynxBaseInspectorOwner>)owner {
  self = [super init];
  if (self) {
    _owner = owner;
  }
  return self;
}

- (void)onConsoleMessage:(NSString *)msg {
  NSLog(@"onConsoleMessage: %@", msg);
  NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
  NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
  for (NSDictionary *item in [dic objectForKey:@"args"]) {
    if ([item objectForKey:@"type"] && [[item objectForKey:@"type"] isEqualToString:@"object"]) {
      NSString *objectId = [item objectForKey:@"objectId"];
      id<LynxBaseInspectorOwner> strongOwner = _owner;
      if (!strongOwner) {
        break;
      }
      [strongOwner getConsoleObject:objectId
                      needStringify:NO
                      resultHandler:^(NSString *detail) {
                        NSLog(@"getConsoleObject: %@", detail);
                      }];
      [strongOwner getConsoleObject:objectId
                      needStringify:YES
                      resultHandler:^(NSString *detail) {
                        NSLog(@"getConsoleObject: %@", detail);
                      }];
    }
  }
}

@end
ViewController.m
#import <Lynx/LynxView.h>
#import <Lynx/LynxBaseInspectorOwner.h>

#import "TestConsoleDelegate.h"

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  // ...

  id<LynxBaseInspectorOwner> owner = lynxView.baseInspectorOwner;
  TestConsoleDelegate* delegate =
      [[TestConsoleDelegate alloc] initWithInspectorOwner:owner];
  [owner setLynxInspectorConsoleDelegate:delegate];
}

@end

Android

MainActivity.java
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.lynx.devtoolwrapper.LynxInspectorConsoleDelegate;
import com.lynx.react.bridge.Callback;
import com.lynx.tasm.LynxView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...

    handleConsoleMessage(lynxView);
  }

  private void handleConsoleMessage(LynxView lynxView) {
    LynxInspectorConsoleDelegate delegate = new LynxInspectorConsoleDelegate() {
      @Override
      public void onConsoleMessage(String msg) {
        try {
          Log.i("MainActivity", "onConsoleMessage: " + msg);
          JSONObject jsonObject = new JSONObject(msg);
          JSONArray args = jsonObject.getJSONArray("args");
          for (int i = 0; i < args.length(); i++) {
            JSONObject obj = new JSONObject(args.get(i).toString());
            if (obj.get("type").toString().equals("object")) {
              String objectId = obj.get("objectId").toString();
              Handler mainHandler = new Handler(Looper.getMainLooper());
              // Post task instead of calling `getConsoleObject` directly to avoid deadlock.
              mainHandler.post(new Runnable() {
                @Override
                public void run() {
                  lynxView.getBaseInspectorOwner().getConsoleObject(
                      objectId, false, new Callback() {
                        @Override
                        public void invoke(Object... args) {
                          Log.i("MainActivity", "getConsoleObject: " + args[0].toString());
                        }
                      });
                  lynxView.getBaseInspectorOwner().getConsoleObject(
                      objectId, true, new Callback() {
                        @Override
                        public void invoke(Object... args) {
                          Log.i("MainActivity", "getConsoleObject: " + args[0].toString());
                        }
                      });
                }
              });
            }
          }
        } catch (JSONException e) {
          // ...
        }
      }
    };

    if (lynxView.getBaseInspectorOwner() != null) {
      lynxView.getBaseInspectorOwner().setLynxInspectorConsoleDelegate(delegate);
    }
  }
}

Harmony

TestConsoleDelegate.ets
import {
  LynxBaseInspectorOwner,
  LynxInspectorConsoleDelegate,
} from '@lynx/lynx';

export class TestConsoleDelegate implements LynxInspectorConsoleDelegate {
  private owner: WeakRef<LynxBaseInspectorOwner>;

  constructor(owner: LynxBaseInspectorOwner) {
    this.owner = new WeakRef(owner);
  }

  public onConsoleMessage(msg: string): void {
    console.log('onConsoleMessage:', msg);
    let json: object = JSON.parse(msg);
    let args: Array<object> = json['args'];
    args.forEach((value) => {
      if (value['type'] === 'object') {
        let objectId: string = value['objectId'];
        let owner = this.owner.deref();
        if (owner) {
          owner.getConsoleObject(objectId, true, (detail: string) => {
            console.log('getConsoleObject:', detail);
          });
          owner.getConsoleObject(objectId, false, (detail: string) => {
            console.log('getConsoleObject:', detail);
          });
        }
      }
    });
  }
}
Index.ets
import { LynxView, LynxContext } from '@lynx/lynx';
import { TestConsoleDelegate } from './TestConsoleDelegate';

@Entry
@Component
struct Index {
  // ...

  build() {
    Column() {
      LynxView({
        // ...
        onCreate: (context: LynxContext) => {
          let owner = context?.getBaseInspectorOwner();
          if (owner) {
            let delegate = new TestConsoleDelegate(owner);
            owner.setLynxInspectorConsoleDelegate(delegate);
          }
        }
      }).width('100%').height('100%');
    }
  }
}

Compatibility

LCD tables only load in the browser

Except as otherwise noted, this work is licensed under a Creative Commons Attribution 4.0 International License, and code samples are licensed under the Apache License 2.0.