diff --git a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm index 1badbc419..f7c7e1adf 100644 --- a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm +++ b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm @@ -20,6 +20,9 @@ #import "SKTapListener.h" #import "SKTapListenerImpl.h" +NSObject* parseLayoutEditorMessage(NSObject* message); +NSObject* flattenLayoutEditorMessage(NSObject* field); + @implementation FlipperKitLayoutPlugin { NSMapTable* _trackedObjects; NSString* _lastHighlightedNode; @@ -246,6 +249,8 @@ return; } + value = parseLayoutEditorMessage(value); + SKNodeDescriptor* descriptor = [_descriptorMapper descriptorForClass:[node class]]; @@ -270,6 +275,45 @@ } } +/** + Layout editor messages are tagged with the types they contain, allowing for + heterogeneous NSArray and NSDictionary supported by Android and iOS. The method + parseLayoutEditorMessage traverses the message and flattens the messages to + their original types. + */ +NSObject* parseLayoutEditorMessage(NSObject* message) { + if ([message isKindOfClass:[NSDictionary class]]) { + NSDictionary* wrapper = (NSDictionary*)message; + if (wrapper[@"kind"]) { + NSObject* newData = wrapper[@"data"]; + return flattenLayoutEditorMessage(newData); + } + } + return message; +} + +NSObject* flattenLayoutEditorMessage(NSObject* field) { + if ([field isKindOfClass:[NSDictionary class]]) { + NSDictionary* wrapper = (NSDictionary*)field; + NSMutableDictionary* dictionary = + [[NSMutableDictionary alloc] initWithCapacity:[wrapper count]]; + for (NSString* key in wrapper) { + NSObject* value = wrapper[key]; + dictionary[key] = parseLayoutEditorMessage(value); + } + return dictionary; + } else if ([field isKindOfClass:[NSArray class]]) { + NSArray* wrapper = (NSArray*)field; + NSMutableArray* array = + [[NSMutableArray alloc] initWithCapacity:[wrapper count]]; + for (NSObject* value in wrapper) { + [array addObject:parseLayoutEditorMessage(value)]; + } + return array; + } + return field; +} + - (void)onCallGetSearchResults:(NSString*)query withResponder:(id)responder { const auto alreadyAddedElements = [NSMutableSet new];