diff --git a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm index 2ef733b97..74d691a6d 100644 --- a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm +++ b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm @@ -321,17 +321,30 @@ __block id rootNode = _rootNode; [_tapListener listenForTapWithBlock:^(CGPoint touchPoint) { - SKTouch* touch = [[SKTouch alloc] - initWithTouchPoint:touchPoint - withRootNode:rootNode - withDescriptorMapper:self->_descriptorMapper - finishWithBlock:^(NSArray* path) { - [connection send:@"select" withParams:@{@"path" : path}]; - }]; + SKTouch* touch = + [[SKTouch alloc] initWithTouchPoint:touchPoint + withRootNode:rootNode + withDescriptorMapper:self->_descriptorMapper + finishWithBlock:^(id node) { + [self updateNodeReference:node]; + }]; SKNodeDescriptor* descriptor = [self->_descriptorMapper descriptorForClass:[rootNode class]]; [descriptor hitTest:touch forNode:rootNode]; + [touch retrieveSelectTree:^(NSDictionary* tree) { + NSMutableArray* path = [NSMutableArray new]; + NSDictionary* subtree = tree; + NSEnumerator* enumerator = [tree keyEnumerator]; + id nodeId; + while ((nodeId = [enumerator nextObject])) { + subtree = subtree[nodeId]; + [path addObject:nodeId]; + enumerator = [subtree keyEnumerator]; + } + [connection send:@"select" + withParams:@{@"path" : path, @"tree" : tree}]; + }]; }]; } else { [_tapListener unmount]; diff --git a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/SKTouch.h b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/SKTouch.h index 8b3b77f84..0f85fa543 100644 --- a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/SKTouch.h +++ b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/SKTouch.h @@ -9,7 +9,8 @@ #import "SKDescriptorMapper.h" -typedef void (^SKTouchFinishDelegate)(NSArray* path); +typedef void (^SKTouchFinishDelegate)(id currentNode); +typedef void (^SKProcessFinishDelegate)(NSDictionary* tree); @interface SKTouch : NSObject @@ -23,6 +24,8 @@ typedef void (^SKTouchFinishDelegate)(NSArray* path); - (void)finish; +- (void)retrieveSelectTree:(SKProcessFinishDelegate)callback; + - (BOOL)containedIn:(CGRect)bounds; @end diff --git a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/SKTouch.m b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/SKTouch.m index 53efa3222..6907ee20e 100644 --- a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/SKTouch.m +++ b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/SKTouch.m @@ -12,12 +12,13 @@ @implementation SKTouch { SKTouchFinishDelegate _onFinish; - NSMutableArray* _path; CGPoint _currentTouchPoint; - id _currentNode; SKDescriptorMapper* _descriptorMapper; + + NSMutableArray>* _nodeStack; + NSMutableArray* _treeStack; } - (instancetype)initWithTouchPoint:(CGPoint)touchPoint @@ -27,9 +28,11 @@ if (self = [super init]) { _onFinish = finishBlock; _currentTouchPoint = touchPoint; - _currentNode = node; _descriptorMapper = mapper; - _path = [NSMutableArray new]; + _nodeStack = [NSMutableArray new]; + [_nodeStack addObject:node]; + _treeStack = [NSMutableArray new]; + [_treeStack addObject:[[NSMutableDictionary alloc] init]]; } return self; @@ -40,18 +43,34 @@ _currentTouchPoint.x -= offset.x; _currentTouchPoint.y -= offset.y; + id currentNode = _nodeStack.lastObject; SKNodeDescriptor* descriptor = - [_descriptorMapper descriptorForClass:[_currentNode class]]; - _currentNode = [descriptor childForNode:_currentNode atIndex:childIndex]; + [_descriptorMapper descriptorForClass:[currentNode class]]; + id nextNode = [descriptor childForNode:currentNode + atIndex:childIndex]; + [_nodeStack addObject:nextNode]; + [_treeStack addObject:[[NSMutableDictionary alloc] init]]; - descriptor = [_descriptorMapper descriptorForClass:[_currentNode class]]; - [_path addObject:[descriptor identifierForNode:_currentNode]]; + descriptor = [_descriptorMapper descriptorForClass:[nextNode class]]; + NSString* currentId = [descriptor identifierForNode:nextNode]; + [descriptor hitTest:self forNode:nextNode]; - [descriptor hitTest:self forNode:_currentNode]; + // After finish this component + _currentTouchPoint.x += offset.x; + _currentTouchPoint.y += offset.y; + [_nodeStack removeLastObject]; + NSDictionary* currentDict = _treeStack.lastObject; + [_treeStack removeLastObject]; + [_treeStack.lastObject setObject:currentDict forKey:currentId]; } - (void)finish { - _onFinish(_path); + _onFinish(_nodeStack.lastObject); +} + +- (void)retrieveSelectTree:(SKProcessFinishDelegate)callback { + callback(_treeStack.lastObject); + [_treeStack removeAllObjects]; } - (BOOL)containedIn:(CGRect)bounds { diff --git a/iOS/Plugins/FlipperKitLayoutPlugin/SonarKitLayoutPluginTests/SonarKitLayoutPluginTests.m b/iOS/Plugins/FlipperKitLayoutPlugin/SonarKitLayoutPluginTests/SonarKitLayoutPluginTests.m index 41b375bdb..bd887e409 100644 --- a/iOS/Plugins/FlipperKitLayoutPlugin/SonarKitLayoutPluginTests/SonarKitLayoutPluginTests.m +++ b/iOS/Plugins/FlipperKitLayoutPlugin/SonarKitLayoutPluginTests/SonarKitLayoutPluginTests.m @@ -207,8 +207,11 @@ // Fake a tap at `testNode3` [tapListener tapAt:(CGPoint){26, 43}]; - XCTAssertTrue(([connection.sent[@"select"] - containsObject:@{@"path" : @[ @"testNode2", @"testNode3" ]}])); + NSLog(@"%@", connection.sent[@"select"]); + XCTAssertTrue(([connection.sent[@"select"] containsObject:@{ + @"path" : @[ @"testNode2", @"testNode3" ], + @"tree" : @{@"testNode2" : @{@"testNode3" : @{}}} + }])); } - (void)testSetSearchActiveMountAndUnmount {