Extending the Layout Inspector
The Layout Inspector plugin can be extended to support new kinds of UI components. You can also extend it to customize the data made available in the sidebar. Depending on whether or not you want to expose new data on Android or iOS, there are different interfaces you can use.
The following screenshot shows the Layout Inspector in action.
Androidβ
NodeDescriptorβ
To expose an object to the Layout Inspector in Flipper, you have to implement a NodeDescriptor
that describes your object. For example, the ViewDescriptor
describes View
objects and the FragmentDescriptor
describe Fragment
instances. These descriptors have a set of callbacks used to expose children and data associated with the object they describe.
For the full API, see See NodeDescriptor.java in GitHub.
NodeDescriptor
implementations should not subclass other NodeDescriptor
implementations. Instead, re-use existing behavior from a more generic descriptor, it's best to use a delegate.
Following are code snippets that illustrate how to use and how not to use the NodeDescriptor on Android.
How to use the NodeDescriptor on Androidβ
class ViewGroupDescriptor extends NodeDescriptor<ViewGroup> {
public String getName(ViewGroup node) {
NodeDescriptor descriptor = descriptorForClass(View.class);
return descriptor.getName(node);
}
}
How not to use the NodeDescriptor on Androidβ
class ViewGroupDescriptor extends ViewDescriptor<ViewGroup> {
public String getName(ViewGroup node) {
return super.getName(node);
}
}
Register a descriptorβ
Register your descriptor in the DescriptorMapping
used to instantiate the InspectorFlipperPlugin
:
final FlipperClient client = FlipperClient.createInstance(mContext);
final DescriptorMapping descriptorMapping = DescriptorMapping.withDefaults();
descriptorMapping.register(MyObject.class, new MyObjectDescriptor());
client.addPlugin(new InspectorFlipperPlugin(mContext, descriptorMapping));
Extending an existing descriptorβ
You may not need to create a whole new descriptor. Instead, you may just want to change extend an existing one to expose some new piece of data. In such a case, just locate the correct descriptor and edit its getData
, getAttributes
, and perhaps setData
methods.
iOSβ
SKNodeDescriptorβ
To expose an object to the layout inspector in Sonar, you have to implement a SKNodeDescriptor
that describes the object. For example, SKViewDescriptor
describes UIView
objects, and the SKComponentDescriptor
describes CKComponent
objects. These descriptors have necessary callbacks that are used to expose its children and data associated with the object they describe.
For the full available API, see SKNodeDescriptor.h in GitHub.
SKNodeDescriptor
implementations should never be subclass other SKNodeDescriptor
implementations. Instead, re-use existing behaviour by explicitly using other descriptors and delegate behaviour.
Following are code snippets that illustrate how to use and how not to use the SKNodeDescriptor on iOS.
How to use the SKNodeDescriptor on iOSβ
@interface SKArbitraryViewDescriptor : SKNodeDescriptor<ArbitraryView *>
@end
@implementation SKArbitraryViewDescriptor
- (NSString *)identifierForNode:(ArbitraryView *)node
{
SKNodeDescriptor *descriptor = [self descriptorForClass:[UIView class]];
return [descriptor identifierForNode:node];
}
@end
How not to use the SKNodeDescriptor on iOSβ
@interface SKArbitraryViewDescriptor : SKViewDescriptor<ArbitraryView *>
@end
@implementation SKArbitraryViewDescriptor
- (NSString *)identifierForNode:(ArbitraryView *)node
{
return [super identifierForNode:node];
}
@end
Register a Descriptorβ
In order to register your descriptor for an object, use SKDescriptorMapper
. After registering all descriptors, pass on the descriptor-mapper object to the plugin during initialisation:
[descriptorMapper registerDescriptor:[SKArbitraryViewDescriptor new]
forClass:[ArbitraryView class]];
There's already a set of descriptors registered by default in SKDescriptorMapper
. If you want to add a descriptor to the default set, you can do it in the SKDescriptorMapper.
Extending an existing Descriptorβ
Sometimes, all you need is to extend the functionality of an existing descriptor. In such as case, you just need to locate the correct descriptor and edit the methods dataForNode
, attributesForNode
, and possibly dataMutationsForNode
.
Subdescriptorsβ
If you want to extend the SKComponentKitLayoutDescriptor
and add an additional section based on the nodes of the SKComponentLayoutDescriptor
, you can use SKSubDescriptor
:
#import <FlipperKitLayoutComponentKitSupport/SKComponentLayoutWrapper.h>
NSString *YourSubDescriptor(SKComponentLayoutWrapper *)node {
return @"Meta data";
}
// At setup time, you must register it:
[SKComponentLayoutDescriptor registerSubDescriptor:&YourSubDescriptor forName:@"Section Name"];
Swift support is not yet available because you must access SKComponentLayoutWrapper
to implement a subdescriptor.