Refactor SKSubDescriptor

Reviewed By: d16r

Differential Revision: D20458337

fbshipit-source-id: e8ea848c6e2f7521c5a6c6eb4110bba0bfe25593
This commit is contained in:
Adam Ernst
2020-03-15 19:39:20 -07:00
committed by Facebook GitHub Bot
parent 19876273a3
commit d9a2167019
7 changed files with 27 additions and 107 deletions

View File

@@ -115,50 +115,17 @@ Sometimes all you need is to extend the functionality of an existing descriptor.
### Subdescriptors
If you want to extend the `SKComponentKitLayoutDescriptor` and add an additional section based on the nodes of the `SKComponentLayoutDescriptor`, you will have to subclass `SKSubDescriptor`.
If you want to extend the `SKComponentKitLayoutDescriptor` and add an additional section based on the nodes of the `SKComponentLayoutDescriptor`, you can use `SKSubDescriptor`.
```objc
#import <FlipperKitLayoutComponentKitSupport/SKSubDescriptor.h>
#import <FlipperKitLayoutComponentKitSupport/SKComponentLayoutWrapper.h>
@interface YourSubDescriptor: SKSubDescriptor
@end
@implementation YourSubDescriptor
- (NSString *) getName {
return @"Section Name";
NSString *YourSubDescriptor(SKComponentLayoutWrapper *)node {
return @"Meta data";
}
- (NSString *)getDataForNode:(SKComponentLayoutWrapper *)node {
return @"Meta data"
}
@end
#endif
// At setup time, you must register it:
[SKComponentLayoutDescriptor registerSubDescriptor:&YourSubDescriptor forName:@"Section Name"];
```
Once you have implemented the descriptor, you will have to setup the Layout plugin as follows.
<!--DOCUSAURUS_CODE_TABS-->
<!--Objective-C-->
```objc
NSArray<SKSubDescriptor *> *registeredSubDescriptors = @[ yourSubDescriptors ];
SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
[FlipperKitLayoutComponentKitSupport setUpWithDescriptorMapper: layoutDescriptorMapper subDescriptors: registeredSubDescriptors];
[client addPlugin: [[FlipperKitLayoutPlugin alloc] initWithRootNode: application
withDescriptorMapper: layoutDescriptorMapper]];
```
<!--Swift-->
```swift
let subDescriptors = [ yourSubDescriptors ]
let layoutDescriptorMapper = SKDescriptorMapper(defaults: ())
FlipperKitLayoutComponentKitSupport.setUpWith(layoutDescriptorMapper, subDescriptors: subDescriptors)
client?.add(FlipperKitLayoutPlugin(rootNode: application, with: layoutDescriptorMapper!))
```
<!--END_DOCUSAURUS_CODE_TABS-->
Swift support is not yet available because you must access `SKComponentLayoutWrapper` to implement a subdescriptor.

View File

@@ -8,13 +8,9 @@
#import <Foundation/Foundation.h>
#import <FlipperKitLayoutPlugin/SKDescriptorMapper.h>
#import "SKSubDescriptor.h"
@interface FlipperKitLayoutComponentKitSupport : NSObject
+ (void)setUpWithDescriptorMapper:(SKDescriptorMapper*)mapper;
+ (void)setUpWithDescriptorMapper:(SKDescriptorMapper*)mapper
subDescriptors:(NSArray<SKSubDescriptor*>*)subDescriptors;
@end

View File

@@ -17,22 +17,9 @@
#import "SKComponentLayoutDescriptor.h"
#import "SKComponentLayoutWrapper.h"
#import "SKComponentRootViewDescriptor.h"
#import "SKSubDescriptor.h"
@implementation FlipperKitLayoutComponentKitSupport
+ (void)setUpWithDescriptorMapper:(SKDescriptorMapper*)mapper
subDescriptors:(NSArray<SKSubDescriptor*>*)subDescriptors {
[mapper registerDescriptor:[[SKComponentRootViewDescriptor alloc]
initWithDescriptorMapper:mapper]
forClass:[CKComponentRootView class]];
SKComponentLayoutDescriptor* layoutDescriptor =
[[SKComponentLayoutDescriptor alloc] initWithDescriptorMapper:mapper];
[layoutDescriptor addSubDescriptors:subDescriptors];
[mapper registerDescriptor:layoutDescriptor
forClass:[SKComponentLayoutWrapper class]];
}
+ (void)setUpWithDescriptorMapper:(SKDescriptorMapper*)mapper {
// What we really want here is "forProtocol:@protocol(CKInspectableView)" but
// no such luck.

View File

@@ -14,6 +14,7 @@
@interface SKComponentLayoutDescriptor
: SKNodeDescriptor<SKComponentLayoutWrapper*>
- (void)addSubDescriptors:(NSArray<SKSubDescriptor*>*)subDescriptors;
+ (void)registerSubDescriptor:(SKSubDescriptor)descriptor
forName:(NSString*)name;
@end

View File

@@ -9,6 +9,9 @@
#import "SKComponentLayoutDescriptor.h"
#import <utility>
#import <vector>
#import <ComponentKit/CKComponent.h>
#import <ComponentKit/CKComponentAccessibility.h>
#import <ComponentKit/CKComponentActionInternal.h>
@@ -29,15 +32,18 @@
#import "SKSubDescriptor.h"
#import "Utils.h"
@implementation SKComponentLayoutDescriptor {
NSArray<SKSubDescriptor*>* _registeredSubdescriptors;
@implementation SKComponentLayoutDescriptor
static std::vector<std::pair<NSString*, SKSubDescriptor>>& subDescriptors() {
// Avoid a global constructor; we want to lazily initialize this when needed.
static std::vector<std::pair<NSString*, SKSubDescriptor>> d;
return d;
}
- (void)setUp {
[super setUp];
if (!_registeredSubdescriptors) {
_registeredSubdescriptors = [NSArray new];
+ (void)registerSubDescriptor:(SKSubDescriptor)descriptor
forName:(NSString*)name {
if (name && descriptor) {
subDescriptors().push_back({name, descriptor});
}
}
@@ -90,8 +96,8 @@
NSMutableDictionary<NSString*, NSObject*>* extraData =
[[NSMutableDictionary alloc] init];
for (SKSubDescriptor* s in _registeredSubdescriptors) {
[extraData setObject:[s getDataForNode:node] forKey:[s getName]];
for (const auto& pair : subDescriptors()) {
[extraData setObject:pair.second(node) forKey:pair.first];
}
if (extraData.count > 0) {
[data addObject:[SKNamed newWithName:@"Extra Sections"
@@ -102,10 +108,6 @@
return data;
}
- (void)addSubDescriptors:(nonnull NSArray<SKSubDescriptor*>*)subDescriptors {
_registeredSubdescriptors = subDescriptors;
}
- (NSDictionary<NSString*, NSObject*>*)propsForFlexboxChild:
(CKFlexboxComponentChild)child {
return @{

View File

@@ -10,20 +10,8 @@
@class SKComponentLayoutWrapper;
/**
A SKSubDescriptor is an object which knows how to expose an Object of type T
to the SKLayoutDescriptor. This class is for frameworks wanting to pass data
A SKSubDescriptor is a function which knows how to expose additional data
to SKLayoutDescriptor. This class is for frameworks wanting to pass data
along through the Layout Descriptor.
*/
@interface SKSubDescriptor : NSObject
/**
This is the SubDescriptor name.
*/
- (NSString*)getName;
/**
This is the data the SubDescriptor wants to pass up to the SKLayoutDescriptor.
*/
- (NSString*)getDataForNode:(SKComponentLayoutWrapper*)node;
@end
typedef NSString* (*SKSubDescriptor)(SKComponentLayoutWrapper* node);

View File

@@ -4,24 +4,3 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#if FB_SONARKIT_ENABLED
#import "SKSubDescriptor.h"
#import "SKComponentLayoutWrapper.h"
@implementation SKSubDescriptor {
}
- (NSDictionary<NSString*, NSObject*>*)getDataForNode:
(SKComponentLayoutWrapper*)node {
return @{};
}
- (NSString*)getName {
return @"";
}
@end
#endif