Skip to content

Commit ae2bacb

Browse files
yogevbdvshkl
authored andcommitted
SetRoot wait for render (wix#4688)
* Layout changes * WIP * Revert "Layout changes" This reverts commit 4da8cfb. * Clean topBar.component and topBar.background.component when not needed * Move custom components login from viewController to presenters * Change waitForRender and enabled property from primitive bool to Bool object * Fix ios unit tests * Add unit tests * Remove RNNReactView observer when view ready * Load react components from component manager * Remove createCustomReactView duplication * Handle render children in each Layout * Wait for navigation presenter components render, refactor RNNTitleViewHelper * Fix unit tests * Add waitForRender for custom react components * Fixes e2e
1 parent ac4e4ff commit ae2bacb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+621
-305
lines changed

lib/ios/RNNBasePresenter.m

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
#import "RNNBasePresenter.h"
22
#import "UIViewController+RNNOptions.h"
33
#import "RNNTabBarItemCreator.h"
4+
#import "RNNReactComponentManager.h"
5+
6+
@interface RNNBasePresenter ()
7+
@property (nonatomic, strong) RNNReactComponentManager* componentManager;
8+
@end
9+
410

511
@implementation RNNBasePresenter
612

13+
- (instancetype)initWithComponentManager:(RNNReactComponentManager *)componentManager {
14+
self = [super init];
15+
self.componentManager = componentManager;
16+
return self;
17+
}
18+
719
- (void)bindViewController:(UIViewController *)bindedViewController {
820
_bindedViewController = bindedViewController;
921
}

lib/ios/RNNBridgeManager.m

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88
#import "RNNBridgeModule.h"
99
#import "RNNRootViewCreator.h"
1010
#import "RNNReactRootViewCreator.h"
11+
#import "RNNReactComponentManager.h"
1112

1213
@interface RNNBridgeManager() <RCTBridgeDelegate>
1314

1415
@property (nonatomic, strong, readwrite) RCTBridge *bridge;
1516
@property (nonatomic, strong, readwrite) RNNStore *store;
17+
@property (nonatomic, strong, readwrite) RNNReactComponentManager *componentManager;
1618

1719
@end
1820

@@ -77,7 +79,8 @@ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
7779
RNNEventEmitter *eventEmitter = [[RNNEventEmitter alloc] init];
7880

7981
id<RNNRootViewCreator> rootViewCreator = [[RNNReactRootViewCreator alloc] initWithBridge:bridge];
80-
RNNControllerFactory *controllerFactory = [[RNNControllerFactory alloc] initWithRootViewCreator:rootViewCreator eventEmitter:eventEmitter andBridge:bridge];
82+
_componentManager = [[RNNReactComponentManager alloc] initWithCreator:rootViewCreator];
83+
RNNControllerFactory *controllerFactory = [[RNNControllerFactory alloc] initWithRootViewCreator:rootViewCreator eventEmitter:eventEmitter store:_store componentManager:_componentManager andBridge:bridge];
8184

8285
_commandsHandler = [[RNNCommandsHandler alloc] initWithStore:_store controllerFactory:controllerFactory eventEmitter:eventEmitter stackManager:[RNNNavigationStackManager new] modalManager:[RNNModalManager new] overlayManager:[RNNOverlayManager new] mainWindow:_mainWindow];
8386
RNNBridgeModule *bridgeModule = [[RNNBridgeModule alloc] initWithCommandsHandler:_commandsHandler];
@@ -89,6 +92,7 @@ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
8992

9093
- (void)onJavaScriptWillLoad {
9194
[_store clean];
95+
[_componentManager clean];
9296
}
9397

9498
- (void)onJavaScriptLoaded {

lib/ios/RNNCommandsHandler.m

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,13 @@ - (void)setRoot:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)c
5858
[_modalManager dismissAllModalsAnimated:NO];
5959
[_store removeAllComponentsFromWindow:_mainWindow];
6060

61-
UIViewController *vc = [_controllerFactory createLayout:layout[@"root"] saveToStore:_store];
61+
UIViewController<RNNLayoutProtocol> *vc = [_controllerFactory createLayout:layout[@"root"]];
6262

63-
_mainWindow.rootViewController = vc;
64-
65-
[_eventEmitter sendOnNavigationCommandCompletion:setRoot params:@{@"layout": layout}];
66-
completion();
63+
[vc renderTreeAndWait:[vc.resolveOptions.animations.setRoot.waitForRender getWithDefaultValue:NO] perform:^{
64+
_mainWindow.rootViewController = vc;
65+
[_eventEmitter sendOnNavigationCommandCompletion:setRoot params:@{@"layout": layout}];
66+
completion() ;
67+
}];
6768
}
6869

6970
- (void)mergeOptions:(NSString*)componentId options:(NSDictionary*)mergeOptions completion:(RNNTransitionCompletionBlock)completion {
@@ -96,7 +97,7 @@ - (void)setDefaultOptions:(NSDictionary*)optionsDict completion:(RNNTransitionCo
9697
- (void)push:(NSString*)componentId layout:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
9798
[self assertReady];
9899

99-
UIViewController<RNNLayoutProtocol> *newVc = [_controllerFactory createLayout:layout saveToStore:_store];
100+
UIViewController<RNNLayoutProtocol> *newVc = [_controllerFactory createLayout:layout];
100101
UIViewController *fromVC = [_store findComponentForId:componentId];
101102

102103
if ([[newVc.resolveOptions.preview.reactTag getWithDefaultValue:@(0)] floatValue] > 0) {
@@ -141,8 +142,8 @@ - (void)push:(NSString*)componentId layout:(NSDictionary*)layout completion:(RNN
141142
}
142143
} else {
143144
id animationDelegate = (newVc.resolveOptions.animations.push.hasCustomAnimation || newVc.getCurrentLeaf.isCustomTransitioned) ? newVc : nil;
144-
[newVc.getCurrentLeaf waitForReactViewRender:(newVc.resolveOptions.animations.push.waitForRender || animationDelegate) perform:^{
145-
[_stackManager push:newVc onTop:fromVC animated:newVc.resolveOptions.animations.push.enable animationDelegate:animationDelegate completion:^{
145+
[newVc renderTreeAndWait:([newVc.resolveOptions.animations.push.waitForRender getWithDefaultValue:NO] || animationDelegate) perform:^{
146+
[_stackManager push:newVc onTop:fromVC animated:[newVc.resolveOptions.animations.push.enable getWithDefaultValue:YES] animationDelegate:animationDelegate completion:^{
146147
[_eventEmitter sendOnNavigationCommandCompletion:push params:@{@"componentId": componentId}];
147148
completion();
148149
} rejection:rejection];
@@ -153,11 +154,14 @@ - (void)push:(NSString*)componentId layout:(NSDictionary*)layout completion:(RNN
153154
- (void)setStackRoot:(NSString*)componentId children:(NSArray*)children completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
154155
[self assertReady];
155156

156-
NSArray<RNNLayoutProtocol> *childViewControllers = [_controllerFactory createChildrenLayout:children saveToStore:_store];
157+
NSArray<RNNLayoutProtocol> *childViewControllers = [_controllerFactory createChildrenLayout:children];
158+
for (UIViewController<RNNLayoutProtocol>* viewController in childViewControllers) {
159+
[viewController renderTreeAndWait:NO perform:nil];
160+
}
157161
RNNNavigationOptions* options = [childViewControllers.lastObject getCurrentChild].resolveOptions;
158162
UIViewController *fromVC = [_store findComponentForId:componentId];
159163
__weak typeof(RNNEventEmitter*) weakEventEmitter = _eventEmitter;
160-
[_stackManager setStackChildren:childViewControllers fromViewController:fromVC animated:options.animations.setStackRoot.enable completion:^{
164+
[_stackManager setStackChildren:childViewControllers fromViewController:fromVC animated:[options.animations.setStackRoot.enable getWithDefaultValue:YES] completion:^{
161165
[weakEventEmitter sendOnNavigationCommandCompletion:setStackRoot params:@{@"componentId": componentId}];
162166
completion();
163167
} rejection:rejection];
@@ -181,10 +185,10 @@ - (void)pop:(NSString*)componentId mergeOptions:(NSDictionary*)mergeOptions comp
181185
} else {
182186
NSMutableArray * vcs = nvc.viewControllers.mutableCopy;
183187
[vcs removeObject:vc];
184-
[nvc setViewControllers:vcs animated:vc.resolveOptions.animations.pop.enable];
188+
[nvc setViewControllers:vcs animated:[vc.resolveOptions.animations.pop.enable getWithDefaultValue:YES]];
185189
}
186190

187-
[_stackManager pop:vc animated:vc.resolveOptions.animations.pop.enable completion:^{
191+
[_stackManager pop:vc animated:[vc.resolveOptions.animations.pop.enable getWithDefaultValue:YES] completion:^{
188192
[_store removeComponent:componentId];
189193
[_eventEmitter sendOnNavigationCommandCompletion:pop params:@{@"componentId": componentId}];
190194
completion();
@@ -197,7 +201,7 @@ - (void)popTo:(NSString*)componentId mergeOptions:(NSDictionary *)mergeOptions c
197201
RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions];
198202
[vc overrideOptions:options];
199203

200-
[_stackManager popTo:vc animated:vc.resolveOptions.animations.pop.enable completion:^(NSArray *poppedViewControllers) {
204+
[_stackManager popTo:vc animated:[vc.resolveOptions.animations.pop.enable getWithDefaultValue:YES] completion:^(NSArray *poppedViewControllers) {
201205
[_eventEmitter sendOnNavigationCommandCompletion:popTo params:@{@"componentId": componentId}];
202206
[self removePopedViewControllers:poppedViewControllers];
203207
completion();
@@ -216,7 +220,7 @@ - (void)popToRoot:(NSString*)componentId mergeOptions:(NSDictionary *)mergeOptio
216220
completion();
217221
}];
218222

219-
[_stackManager popToRoot:vc animated:vc.resolveOptions.animations.pop.enable completion:^(NSArray *poppedViewControllers) {
223+
[_stackManager popToRoot:vc animated:[vc.resolveOptions.animations.pop.enable getWithDefaultValue:YES] completion:^(NSArray *poppedViewControllers) {
220224
[self removePopedViewControllers:poppedViewControllers];
221225
} rejection:^(NSString *code, NSString *message, NSError *error) {
222226

@@ -228,10 +232,10 @@ - (void)popToRoot:(NSString*)componentId mergeOptions:(NSDictionary *)mergeOptio
228232
- (void)showModal:(NSDictionary*)layout completion:(RNNTransitionWithComponentIdCompletionBlock)completion {
229233
[self assertReady];
230234

231-
UIViewController<RNNParentProtocol> *newVc = [_controllerFactory createLayout:layout saveToStore:_store];
235+
UIViewController<RNNParentProtocol> *newVc = [_controllerFactory createLayout:layout];
232236

233-
[newVc.getCurrentLeaf waitForReactViewRender:newVc.getCurrentLeaf.resolveOptions.animations.showModal.waitForRender perform:^{
234-
[_modalManager showModal:newVc animated:newVc.getCurrentChild.resolveOptions.animations.showModal.enable hasCustomAnimation:newVc.getCurrentChild.resolveOptions.animations.showModal.hasCustomAnimation completion:^(NSString *componentId) {
237+
[newVc renderTreeAndWait:[newVc.getCurrentLeaf.resolveOptions.animations.showModal.waitForRender getWithDefaultValue:NO] perform:^{
238+
[_modalManager showModal:newVc animated:[newVc.getCurrentChild.resolveOptions.animations.showModal.enable getWithDefaultValue:YES] hasCustomAnimation:newVc.getCurrentChild.resolveOptions.animations.showModal.hasCustomAnimation completion:^(NSString *componentId) {
235239
[_eventEmitter sendOnNavigationCommandCompletion:showModal params:@{@"layout": layout}];
236240
completion(componentId);
237241
}];
@@ -272,20 +276,22 @@ - (void)dismissAllModals:(NSDictionary *)mergeOptions completion:(RNNTransitionC
272276
completion();
273277
}];
274278
RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions];
275-
[_modalManager dismissAllModalsAnimated:options.animations.dismissModal.enable];
279+
[_modalManager dismissAllModalsAnimated:[options.animations.dismissModal.enable getWithDefaultValue:YES]];
276280

277281
[CATransaction commit];
278282
}
279283

280284
- (void)showOverlay:(NSDictionary *)layout completion:(RNNTransitionCompletionBlock)completion {
281285
[self assertReady];
282286

283-
UIViewController<RNNParentProtocol>* overlayVC = [_controllerFactory createLayout:layout saveToStore:_store];
284-
UIWindow* overlayWindow = [[RNNOverlayWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
285-
overlayWindow.rootViewController = overlayVC;
286-
[_overlayManager showOverlayWindow:overlayWindow];
287-
[_eventEmitter sendOnNavigationCommandCompletion:showOverlay params:@{@"layout": layout}];
288-
completion();
287+
UIViewController<RNNParentProtocol>* overlayVC = [_controllerFactory createLayout:layout];
288+
[overlayVC renderTreeAndWait:[overlayVC.options.animations.showOverlay.waitForRender getWithDefaultValue:NO] perform:^{
289+
UIWindow* overlayWindow = [[RNNOverlayWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
290+
overlayWindow.rootViewController = overlayVC;
291+
[_overlayManager showOverlayWindow:overlayWindow];
292+
[_eventEmitter sendOnNavigationCommandCompletion:showOverlay params:@{@"layout": layout}];
293+
completion();
294+
}];
289295
}
290296

291297
- (void)dismissOverlay:(NSString*)componentId completion:(RNNTransitionCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)reject {

lib/ios/RNNComponentOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
@property (nonatomic, strong) Text* name;
66
@property (nonatomic, strong) Text* componentId;
77
@property (nonatomic, strong) Text* alignment;
8+
@property (nonatomic, strong) Bool* waitForRender;
89

910
@end

lib/ios/RNNComponentOptions.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ - (instancetype)initWithDict:(NSDictionary *)dict {
88
self.name = [TextParser parse:dict key:@"name"];
99
self.componentId = [TextParser parse:dict key:@"componentId"];
1010
self.alignment = [TextParser parse:dict key:@"alignment"];
11+
self.waitForRender = [BoolParser parse:dict key:@"waitForRender"];
1112

1213
return self;
1314
}

lib/ios/RNNControllerFactory.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,19 @@
55
#import "RNNStore.h"
66
#import "RNNEventEmitter.h"
77
#import "RNNParentProtocol.h"
8+
#import "RNNReactComponentManager.h"
89

910
@interface RNNControllerFactory : NSObject
1011

1112
-(instancetype)initWithRootViewCreator:(id <RNNRootViewCreator>)creator
1213
eventEmitter:(RNNEventEmitter*)eventEmitter
14+
store:(RNNStore *)store
15+
componentManager:(RNNReactComponentManager *)componentManager
1316
andBridge:(RCTBridge*)bridge;
1417

15-
- (UIViewController<RNNParentProtocol> *)createLayout:(NSDictionary*)layout saveToStore:(RNNStore *)store;
18+
- (UIViewController<RNNParentProtocol> *)createLayout:(NSDictionary*)layout;
1619

17-
- (NSArray<RNNLayoutProtocol> *)createChildrenLayout:(NSArray*)children saveToStore:(RNNStore *)store;
20+
- (NSArray<RNNLayoutProtocol> *)createChildrenLayout:(NSArray*)children;
1821

1922
@property (nonatomic, strong) RNNEventEmitter *eventEmitter;
2023

lib/ios/RNNControllerFactory.m

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,38 +20,39 @@ @implementation RNNControllerFactory {
2020
id<RNNRootViewCreator> _creator;
2121
RNNStore *_store;
2222
RCTBridge *_bridge;
23+
RNNReactComponentManager* _componentManager;
2324
}
2425

2526
# pragma mark public
2627

2728

2829
- (instancetype)initWithRootViewCreator:(id <RNNRootViewCreator>)creator
2930
eventEmitter:(RNNEventEmitter*)eventEmitter
31+
store:(RNNStore *)store
32+
componentManager:(RNNReactComponentManager *)componentManager
3033
andBridge:(RCTBridge *)bridge {
3134

3235
self = [super init];
3336

3437
_creator = creator;
3538
_eventEmitter = eventEmitter;
3639
_bridge = bridge;
40+
_store = store;
41+
_componentManager = componentManager;
3742

3843
return self;
3944
}
4045

41-
- (UIViewController<RNNParentProtocol> *)createLayout:(NSDictionary*)layout saveToStore:(RNNStore *)store {
42-
_store = store;
46+
- (UIViewController<RNNParentProtocol> *)createLayout:(NSDictionary*)layout {
4347
UIViewController<RNNParentProtocol>* layoutViewController = [self fromTree:layout];
44-
_store = nil;
4548
return layoutViewController;
4649
}
4750

48-
- (NSArray<RNNLayoutProtocol> *)createChildrenLayout:(NSArray*)children saveToStore:(RNNStore *)store {
49-
_store = store;
51+
- (NSArray<RNNLayoutProtocol> *)createChildrenLayout:(NSArray*)children {
5052
NSMutableArray<RNNLayoutProtocol>* childViewControllers = [NSMutableArray<RNNLayoutProtocol> new];
5153
for (NSDictionary* layout in children) {
5254
[childViewControllers addObject:[self fromTree:layout]];
5355
}
54-
_store = nil;
5556
return childViewControllers;
5657
}
5758

@@ -114,17 +115,10 @@ - (instancetype)initWithRootViewCreator:(id <RNNRootViewCreator>)creator
114115
- (UIViewController<RNNParentProtocol> *)createComponent:(RNNLayoutNode*)node {
115116
RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
116117
RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
117-
118-
RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] init];
119-
118+
RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] initWithComponentManager:_componentManager];
120119

121120
RNNRootViewController* component = [[RNNRootViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:_creator eventEmitter:_eventEmitter presenter:presenter options:options defaultOptions:_defaultOptions];
122121

123-
if (!component.isExternalViewController) {
124-
CGSize availableSize = UIApplication.sharedApplication.delegate.window.bounds.size;
125-
[_bridge.uiManager setAvailableSize:availableSize forRootView:component.view];
126-
}
127-
128122
return (UIViewController<RNNParentProtocol> *)component;
129123
}
130124

@@ -143,14 +137,13 @@ - (instancetype)initWithRootViewCreator:(id <RNNRootViewCreator>)creator
143137

144138

145139
- (UIViewController<RNNParentProtocol> *)createStack:(RNNLayoutNode*)node {
146-
RNNNavigationControllerPresenter* presenter = [[RNNNavigationControllerPresenter alloc] init];
147-
140+
RNNNavigationControllerPresenter* presenter = [[RNNNavigationControllerPresenter alloc] initWithComponentManager:_componentManager];
148141
RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
149142
RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
150143

151144
NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node];
152145

153-
RNNNavigationController* stack = [[RNNNavigationController alloc] initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options defaultOptions:_defaultOptions presenter:presenter];
146+
RNNNavigationController* stack = [[RNNNavigationController alloc] initWithLayoutInfo:layoutInfo creator:_creator childViewControllers:childViewControllers options:options defaultOptions:_defaultOptions presenter:presenter];
154147

155148
return stack;
156149
}

lib/ios/RNNLayoutProtocol.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#import "RNNLayoutInfo.h"
2-
#import "RNNViewControllerPresenter.h"
32
#import "RNNLeafProtocol.h"
3+
#import "RNNBasePresenter.h"
4+
5+
typedef void (^RNNReactViewReadyCompletionBlock)(void);
46

57
@protocol RNNLayoutProtocol <NSObject, UINavigationControllerDelegate, UIViewControllerTransitioningDelegate, UISplitViewControllerDelegate>
68

@@ -11,6 +13,8 @@
1113
@property (nonatomic, strong) RNNNavigationOptions* options;
1214
@property (nonatomic, strong) RNNNavigationOptions* defaultOptions;
1315

16+
- (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock;
17+
1418
- (UIViewController<RNNLayoutProtocol> *)getCurrentChild;
1519

1620
- (UIViewController<RNNLeafProtocol, RNNLayoutProtocol> *)getCurrentLeaf;

lib/ios/RNNLeafProtocol.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
1-
#import "RNNRootViewCreator.h"
2-
3-
typedef void (^RNNReactViewReadyCompletionBlock)(void);
41

52
@protocol RNNLeafProtocol <NSObject>
63

7-
- (void)waitForReactViewRender:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock;
8-
94
- (void)bindViewController:(UIViewController *)viewController;
105

116
- (BOOL)isCustomTransitioned;
127

13-
- (id<RNNRootViewCreator>)creator;
14-
158
@end

lib/ios/RNNModalManager.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ -(void)removePendingNextModalIfOnTop:(RNNTransitionCompletionBlock)completion {
7373
}
7474

7575
if (modalToDismiss == topPresentedVC || [[topPresentedVC childViewControllers] containsObject:modalToDismiss]) {
76-
[modalToDismiss dismissViewControllerAnimated:options.animations.dismissModal.enable completion:^{
76+
[modalToDismiss dismissViewControllerAnimated:[options.animations.dismissModal.enable getWithDefaultValue:YES] completion:^{
7777
[_pendingModalIdsToDismiss removeObject:modalToDismiss];
7878
if (modalToDismiss.view) {
7979
[self dismissedModal:modalToDismiss];
@@ -88,7 +88,7 @@ -(void)removePendingNextModalIfOnTop:(RNNTransitionCompletionBlock)completion {
8888
} else {
8989
[modalToDismiss.view removeFromSuperview];
9090
modalToDismiss.view = nil;
91-
modalToDismiss.getCurrentChild.resolveOptions.animations.dismissModal.enable = NO;
91+
modalToDismiss.getCurrentChild.resolveOptions.animations.dismissModal.enable = [[Bool alloc] initWithBOOL:NO];
9292
[self dismissedModal:modalToDismiss];
9393

9494
if (completion) {

0 commit comments

Comments
 (0)