For AI agents: the complete documentation index is available at /next/llms.txt, the full documentation bundle is available at /next/llms-full.txt, and this page is available as Markdown at /next/api/lynx-devtool-native-api/lynx-inspector-console-delegate.md.
Lynx
  • English
  • 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

    TestConsoleDelegate.java
    import android.os.Handler;
    import android.os.Looper;
    import android.util.Log;
    import com.lynx.devtool.LynxInspectorConsoleDelegate;
    import com.lynx.devtoolwrapper.LynxBaseInspectorOwner;
    import com.lynx.react.bridge.Callback;
    import java.lang.ref.WeakReference;
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    
    public class TestConsoleDelegate implements LynxInspectorConsoleDelegate {
      private final WeakReference<LynxBaseInspectorOwner> mOwner;
    
      public TestConsoleDelegate(LynxBaseInspectorOwner owner) {
        mOwner = new WeakReference<>(owner);
      }
    
      @Override
      public void onConsoleMessage(String msg) {
        LynxBaseInspectorOwner owner = mOwner.get();
        if (owner == null) {
          return;
        }
        try {
          Log.i("TestConsoleDelegate", "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() {
                  LynxBaseInspectorOwner strongOwner = mOwner.get();
                  if (strongOwner == null) {
                    return;
                  }
                  strongOwner.getConsoleObject(
                      objectId, false, new Callback() {
                        @Override
                        public void invoke(Object... args) {
                          Log.i("TestConsoleDelegate", "getConsoleObject: " + args[0].toString());
                        }
                      });
                  strongOwner.getConsoleObject(
                      objectId, true, new Callback() {
                        @Override
                        public void invoke(Object... args) {
                          Log.i("TestConsoleDelegate", "getConsoleObject: " + args[0].toString());
                        }
                      });
                }
              });
            }
          }
        } catch (JSONException e) {
          // ...
        }
      }
    }
    MainActivity.java
    import com.lynx.devtoolwrapper.LynxBaseInspectorOwner;
    
    public class MainActivity extends Activity {
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // ...
    
        handleConsoleMessage(lynxView);
      }
    
      private void handleConsoleMessage(LynxView lynxView) {
        LynxBaseInspectorOwner owner = lynxView.getBaseInspectorOwner();
        if (owner == null) {
          return;
        }
        TestConsoleDelegate delegate = new TestConsoleDelegate(owner);
        owner.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.