Flutter Engine
 
Loading...
Searching...
No Matches
FlutterPluginAppLifeCycleDelegateTest.mm
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#import <OCMock/OCMock.h>
6#import <XCTest/XCTest.h>
7
13
15
16@protocol TestFlutterPluginWithSceneEvents <NSObject,
17 FlutterApplicationLifeCycleDelegate,
18 FlutterSceneLifeCycleDelegate>
19@end
20
22@end
23
25- (BOOL)application:(UIApplication*)application
26 didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
27 return NO;
28}
29
30- (BOOL)application:(UIApplication*)application
31 openURL:(NSURL*)url
32 options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options {
33 return YES;
34}
35
36- (BOOL)application:(UIApplication*)application
37 continueUserActivity:(NSUserActivity*)userActivity
38 restorationHandler:(void (^)(NSArray*))restorationHandler {
39 return YES;
40}
41
42- (BOOL)application:(UIApplication*)application
43 performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
44 completionHandler:(void (^)(BOOL succeeded))completionHandler
45 API_AVAILABLE(ios(9.0)) {
46 return YES;
47}
48@end
49
51@end
52
53@implementation FakePlugin
54- (BOOL)application:(UIApplication*)application
55 openURL:(NSURL*)url
56 options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options {
57 return YES;
58}
59
60- (BOOL)application:(UIApplication*)application
61 continueUserActivity:(NSUserActivity*)userActivity
62 restorationHandler:(void (^)(NSArray*))restorationHandler {
63 return YES;
64}
65
66- (BOOL)application:(UIApplication*)application
67 performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
68 completionHandler:(void (^)(BOOL succeeded))completionHandler
69 API_AVAILABLE(ios(9.0)) {
70 return YES;
71}
72
73- (BOOL)application:(UIApplication*)application
74 didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
75 return YES;
76}
77
78- (BOOL)application:(UIApplication*)application
79 willFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
80 return YES;
81}
82@end
83
85@end
86
88
89- (void)testCreate {
91 XCTAssertNotNil(delegate);
92}
93
94- (void)testSceneWillConnectFallback {
96 id plugin = [[FakePlugin alloc] init];
97 id mockPlugin = OCMPartialMock(plugin);
98 [delegate addDelegate:mockPlugin];
99
100 id mockOptions = OCMClassMock([UISceneConnectionOptions class]);
101 id mockShortcutItem = OCMClassMock([UIApplicationShortcutItem class]);
102 OCMStub([mockOptions shortcutItem]).andReturn(mockShortcutItem);
103 OCMStub([mockOptions sourceApplication]).andReturn(@"bundle_id");
104 id urlContext = OCMClassMock([UIOpenURLContext class]);
105 NSURL* url = [NSURL URLWithString:@"http://example.com"];
106 OCMStub([urlContext URL]).andReturn(url);
107 NSSet<UIOpenURLContext*>* urlContexts = [NSSet setWithObjects:urlContext, nil];
108 OCMStub([mockOptions URLContexts]).andReturn(urlContexts);
109
110 NSDictionary<UIApplicationOpenURLOptionsKey, id>* expectedApplicationOptions = @{
111 UIApplicationLaunchOptionsShortcutItemKey : mockShortcutItem,
112 UIApplicationLaunchOptionsSourceApplicationKey : @"bundle_id",
113 UIApplicationLaunchOptionsURLKey : url,
114 };
115
116 [delegate sceneWillConnectFallback:mockOptions];
117 OCMVerify([mockPlugin application:[UIApplication sharedApplication]
118 didFinishLaunchingWithOptions:expectedApplicationOptions]);
119}
120
121- (void)testSceneWillConnectFallbackSkippedSupportsScenes {
123 id plugin = [[FakeTestFlutterPluginWithSceneEvents alloc] init];
124 id mockPlugin = OCMPartialMock(plugin);
125 [delegate addDelegate:mockPlugin];
126
127 id mockOptions = OCMClassMock([UISceneConnectionOptions class]);
128 id mockShortcutItem = OCMClassMock([UIApplicationShortcutItem class]);
129 OCMStub([mockOptions shortcutItem]).andReturn(mockShortcutItem);
130 OCMStub([mockOptions sourceApplication]).andReturn(@"bundle_id");
131 id urlContext = OCMClassMock([UIOpenURLContext class]);
132 NSURL* url = [NSURL URLWithString:@"http://example.com"];
133 OCMStub([urlContext URL]).andReturn(url);
134 NSSet<UIOpenURLContext*>* urlContexts = [NSSet setWithObjects:urlContext, nil];
135 OCMStub([mockOptions URLContexts]).andReturn(urlContexts);
136
137 [delegate sceneWillConnectFallback:mockOptions];
138 OCMReject([mockPlugin application:[OCMArg any] didFinishLaunchingWithOptions:[OCMArg any]]);
139}
140
141- (void)testSceneWillConnectFallbackSkippedNoOptions {
143 id plugin = [[FakePlugin alloc] init];
144 id mockPlugin = OCMPartialMock(plugin);
145 [delegate addDelegate:mockPlugin];
146
147 id mockOptions = OCMClassMock([UISceneConnectionOptions class]);
148
149 [delegate sceneWillConnectFallback:mockOptions];
150 OCMReject([mockPlugin application:[OCMArg any] didFinishLaunchingWithOptions:[OCMArg any]]);
151}
152
153- (void)testDidEnterBackground {
154 XCTNSNotificationExpectation* expectation = [[XCTNSNotificationExpectation alloc]
155 initWithName:UIApplicationDidEnterBackgroundNotification];
157 id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
158 [delegate addDelegate:plugin];
159 [[NSNotificationCenter defaultCenter]
160 postNotificationName:UIApplicationDidEnterBackgroundNotification
161 object:nil];
162
163 [self waitForExpectations:@[ expectation ] timeout:5.0];
164 OCMVerify([plugin applicationDidEnterBackground:[UIApplication sharedApplication]]);
165}
166
167- (void)testDidEnterBackgroundWithUIScene {
168 XCTNSNotificationExpectation* expectation = [[XCTNSNotificationExpectation alloc]
169 initWithName:UIApplicationDidEnterBackgroundNotification];
171 id mockApplication = OCMClassMock([FlutterSharedApplication class]);
172 OCMStub([mockApplication hasSceneDelegate]).andReturn(YES);
173 id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
174 [delegate addDelegate:plugin];
175 [[NSNotificationCenter defaultCenter]
176 postNotificationName:UIApplicationDidEnterBackgroundNotification
177 object:nil];
178
179 [self waitForExpectations:@[ expectation ] timeout:5.0];
180 OCMReject([plugin applicationDidEnterBackground:[OCMArg any]]);
181}
182
183- (void)testSceneDidEnterBackgroundFallback {
185 id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
186 [delegate addDelegate:plugin];
187
188 [delegate sceneDidEnterBackgroundFallback];
189 OCMVerify([plugin applicationDidEnterBackground:[UIApplication sharedApplication]]);
190}
191
192- (void)testUnnecessarySceneDidEnterBackgroundFallback {
194 id plugin = OCMProtocolMock(@protocol(TestFlutterPluginWithSceneEvents));
195 [delegate addDelegate:plugin];
196
197 [delegate sceneDidEnterBackgroundFallback];
198 OCMReject([plugin applicationDidEnterBackground:[OCMArg any]]);
199}
200
201- (void)testWillEnterForeground {
202 XCTNSNotificationExpectation* expectation = [[XCTNSNotificationExpectation alloc]
203 initWithName:UIApplicationWillEnterForegroundNotification];
204
206 id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
207 [delegate addDelegate:plugin];
208 [[NSNotificationCenter defaultCenter]
209 postNotificationName:UIApplicationWillEnterForegroundNotification
210 object:nil];
211 [self waitForExpectations:@[ expectation ] timeout:5.0];
212 OCMVerify([plugin applicationWillEnterForeground:[UIApplication sharedApplication]]);
213}
214
215- (void)testWillEnterForegroundWithUIScene {
216 XCTNSNotificationExpectation* expectation = [[XCTNSNotificationExpectation alloc]
217 initWithName:UIApplicationWillEnterForegroundNotification];
219 id mockApplication = OCMClassMock([FlutterSharedApplication class]);
220 OCMStub([mockApplication hasSceneDelegate]).andReturn(YES);
221 id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
222 [delegate addDelegate:plugin];
223 [[NSNotificationCenter defaultCenter]
224 postNotificationName:UIApplicationWillEnterForegroundNotification
225 object:nil];
226
227 [self waitForExpectations:@[ expectation ] timeout:5.0];
228 OCMReject([plugin applicationWillEnterForeground:[OCMArg any]]);
229}
230
231- (void)testSceneWillEnterForegroundFallback {
233 id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
234 [delegate addDelegate:plugin];
235
236 [delegate sceneWillEnterForegroundFallback];
237 OCMVerify([plugin applicationWillEnterForeground:[UIApplication sharedApplication]]);
238}
239
240- (void)testUnnecessarySceneWillEnterForegroundFallback {
242 id plugin = OCMProtocolMock(@protocol(TestFlutterPluginWithSceneEvents));
243 [delegate addDelegate:plugin];
244
245 [delegate sceneWillEnterForegroundFallback];
246 OCMReject([plugin applicationWillEnterForeground:[OCMArg any]]);
247}
248
249- (void)testWillResignActive {
250 XCTNSNotificationExpectation* expectation =
251 [[XCTNSNotificationExpectation alloc] initWithName:UIApplicationWillResignActiveNotification];
252
254 id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
255 [delegate addDelegate:plugin];
256 [[NSNotificationCenter defaultCenter]
257 postNotificationName:UIApplicationWillResignActiveNotification
258 object:nil];
259 [self waitForExpectations:@[ expectation ] timeout:5.0];
260 OCMVerify([plugin applicationWillResignActive:[UIApplication sharedApplication]]);
261}
262
263- (void)testWillResignActiveWithUIScene {
264 XCTNSNotificationExpectation* expectation =
265 [[XCTNSNotificationExpectation alloc] initWithName:UIApplicationWillResignActiveNotification];
267 id mockApplication = OCMClassMock([FlutterSharedApplication class]);
268 OCMStub([mockApplication hasSceneDelegate]).andReturn(YES);
269 id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
270 [delegate addDelegate:plugin];
271 [[NSNotificationCenter defaultCenter]
272 postNotificationName:UIApplicationWillResignActiveNotification
273 object:nil];
274
275 [self waitForExpectations:@[ expectation ] timeout:5.0];
276 OCMReject([plugin applicationWillResignActive:[OCMArg any]]);
277}
278
279- (void)testSceneWillResignActiveFallback {
281 id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
282 [delegate addDelegate:plugin];
283
284 [delegate sceneWillResignActiveFallback];
285 OCMVerify([plugin applicationWillResignActive:[UIApplication sharedApplication]]);
286}
287
288- (void)testUnnecessarySceneWillResignActiveFallback {
290 id plugin = OCMProtocolMock(@protocol(TestFlutterPluginWithSceneEvents));
291 [delegate addDelegate:plugin];
292
293 [delegate sceneWillResignActiveFallback];
294 OCMReject([plugin applicationWillResignActive:[OCMArg any]]);
295}
296
297- (void)testDidBecomeActive {
298 XCTNSNotificationExpectation* expectation =
299 [[XCTNSNotificationExpectation alloc] initWithName:UIApplicationDidBecomeActiveNotification];
300
302 id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
303 [delegate addDelegate:plugin];
304 [[NSNotificationCenter defaultCenter]
305 postNotificationName:UIApplicationDidBecomeActiveNotification
306 object:nil];
307 [self waitForExpectations:@[ expectation ] timeout:5.0];
308 OCMVerify([plugin applicationDidBecomeActive:[UIApplication sharedApplication]]);
309}
310
311- (void)testDidBecomeActiveWithUIScene {
312 XCTNSNotificationExpectation* expectation =
313 [[XCTNSNotificationExpectation alloc] initWithName:UIApplicationDidBecomeActiveNotification];
315 id mockApplication = OCMClassMock([FlutterSharedApplication class]);
316 OCMStub([mockApplication hasSceneDelegate]).andReturn(YES);
317 id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
318 [delegate addDelegate:plugin];
319 [[NSNotificationCenter defaultCenter]
320 postNotificationName:UIApplicationDidBecomeActiveNotification
321 object:nil];
322
323 [self waitForExpectations:@[ expectation ] timeout:5.0];
324 OCMReject([plugin applicationDidBecomeActive:[OCMArg any]]);
325}
326
327- (void)testSceneDidBecomeActiveFallback {
329 id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
330 [delegate addDelegate:plugin];
331
332 [delegate sceneDidBecomeActiveFallback];
333 OCMVerify([plugin applicationDidBecomeActive:[UIApplication sharedApplication]]);
334}
335
336- (void)testUnnecessarySceneDidBecomeActiveFallback {
338 id plugin = OCMProtocolMock(@protocol(TestFlutterPluginWithSceneEvents));
339 [delegate addDelegate:plugin];
340
341 [delegate sceneDidBecomeActiveFallback];
342 OCMReject([plugin applicationDidBecomeActive:[OCMArg any]]);
343}
344
345- (void)testSceneFallbackOpenURLContexts {
347 id plugin = [[FakePlugin alloc] init];
348 id mockPlugin = OCMPartialMock(plugin);
349 [delegate addDelegate:mockPlugin];
350
351 id urlContext = OCMClassMock([UIOpenURLContext class]);
352 NSURL* url = [NSURL URLWithString:@"http://example.com"];
353 OCMStub([urlContext URL]).andReturn(url);
354 NSSet<UIOpenURLContext*>* urlContexts = [NSSet setWithObjects:urlContext, nil];
355
356 NSDictionary<UIApplicationOpenURLOptionsKey, id>* expectedApplicationOptions = @{
357 UIApplicationOpenURLOptionsOpenInPlaceKey : @(NO),
358 };
359
360 [delegate sceneFallbackOpenURLContexts:urlContexts];
361 OCMVerify([mockPlugin application:[UIApplication sharedApplication]
362 openURL:url
363 options:expectedApplicationOptions]);
364}
365
366- (void)testConvertURLOptions {
368 id plugin = [[FakePlugin alloc] init];
369 id mockPlugin = OCMPartialMock(plugin);
370 [delegate addDelegate:mockPlugin];
371
372 NSString* bundleId = @"app.bundle.id";
373 id annotation = @{@"key" : @"value"};
374 id eventAttribution = OCMClassMock([UIEventAttribution class]);
375
376 UIOpenURLContext* urlContext = OCMClassMock([UIOpenURLContext class]);
377 NSURL* url = [NSURL URLWithString:@"http://example.com"];
378 OCMStub([urlContext URL]).andReturn(url);
379 id sceneOptions = OCMClassMock([UISceneOpenURLOptions class]);
380 OCMStub([sceneOptions sourceApplication]).andReturn(bundleId);
381 OCMStub([sceneOptions annotation]).andReturn(annotation);
382 OCMStub([sceneOptions openInPlace]).andReturn(YES);
383 OCMStub([sceneOptions eventAttribution]).andReturn(eventAttribution);
384
385 OCMStub([urlContext options]).andReturn(sceneOptions);
386 NSSet<UIOpenURLContext*>* urlContexts = [NSSet setWithObjects:urlContext, nil];
387
388 [delegate sceneFallbackOpenURLContexts:urlContexts];
389
390 NSDictionary<UIApplicationOpenURLOptionsKey, id>* expectedApplicationOptions = @{
391 UIApplicationOpenURLOptionsSourceApplicationKey : bundleId,
392 UIApplicationOpenURLOptionsAnnotationKey : annotation,
393 UIApplicationOpenURLOptionsOpenInPlaceKey : @(YES),
394 UIApplicationOpenURLOptionsEventAttributionKey : eventAttribution,
395 };
396
397 OCMVerify([mockPlugin application:[UIApplication sharedApplication]
398 openURL:url
399 options:expectedApplicationOptions]);
400}
401
402- (void)testUnnecessarySceneFallbackOpenURLContexts {
404 id plugin = [[FakeTestFlutterPluginWithSceneEvents alloc] init];
405 id mockPlugin = OCMPartialMock(plugin);
406 [delegate addDelegate:mockPlugin];
407
408 id urlContext = OCMClassMock([UIOpenURLContext class]);
409 NSSet<UIOpenURLContext*>* urlContexts = [NSSet setWithObjects:urlContext, nil];
410
411 [delegate sceneFallbackOpenURLContexts:urlContexts];
412 OCMReject([mockPlugin application:[OCMArg any] openURL:[OCMArg any] options:[OCMArg any]]);
413}
414
415- (void)testSceneFallbackContinueUserActivity {
417 id plugin = [[FakePlugin alloc] init];
418 id mockPlugin = OCMPartialMock(plugin);
419 [delegate addDelegate:mockPlugin];
420
421 id userActivity = OCMClassMock([NSUserActivity class]);
422
423 [delegate sceneFallbackContinueUserActivity:userActivity];
424 OCMVerify([mockPlugin application:[UIApplication sharedApplication]
425 continueUserActivity:userActivity
426 restorationHandler:[OCMArg any]]);
427}
428
429- (void)testUnnecessarySceneFallbackContinueUserActivity {
431 id plugin = [[FakeTestFlutterPluginWithSceneEvents alloc] init];
432 id mockPlugin = OCMPartialMock(plugin);
433 [delegate addDelegate:mockPlugin];
434
435 id userActivity = OCMClassMock([NSUserActivity class]);
436
437 [delegate sceneFallbackContinueUserActivity:userActivity];
438 OCMReject([mockPlugin application:[UIApplication sharedApplication]
439 continueUserActivity:userActivity
440 restorationHandler:[OCMArg any]]);
441}
442
443- (void)testSceneFallbackPerformActionForShortcutItem {
445 FakePlugin* plugin = [[FakePlugin alloc] init];
446 FakePlugin* mockPlugin = OCMPartialMock(plugin);
447 [delegate addDelegate:mockPlugin];
448
449 id shortcut = OCMClassMock([UIApplicationShortcutItem class]);
450 id handler = ^(BOOL succeeded) {
451 };
452
453 [delegate sceneFallbackPerformActionForShortcutItem:shortcut completionHandler:handler];
454 OCMVerify([mockPlugin application:[UIApplication sharedApplication]
455 performActionForShortcutItem:shortcut
456 completionHandler:handler]);
457}
458
459- (void)testUnnecessarySceneFallbackPerformActionForShortcutItem {
463 FakeTestFlutterPluginWithSceneEvents* mockPlugin = OCMPartialMock(plugin);
464 [delegate addDelegate:mockPlugin];
465
466 id shortcut = OCMClassMock([UIApplicationShortcutItem class]);
467 [delegate sceneFallbackPerformActionForShortcutItem:shortcut
468 completionHandler:^(BOOL succeeded){
469 }];
470 OCMReject([mockPlugin application:[OCMArg any]
471 performActionForShortcutItem:[OCMArg any]
472 completionHandler:[OCMArg any]]);
473}
474
475- (void)testWillTerminate {
476 XCTNSNotificationExpectation* expectation =
477 [[XCTNSNotificationExpectation alloc] initWithName:UIApplicationWillTerminateNotification];
478
480 id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
481 [delegate addDelegate:plugin];
482 [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationWillTerminateNotification
483 object:nil];
484 [self waitForExpectations:@[ expectation ] timeout:5.0];
485 OCMVerify([plugin applicationWillTerminate:[UIApplication sharedApplication]]);
486}
487
488- (void)testReleasesPluginOnDealloc {
489 __weak id<FlutterApplicationLifeCycleDelegate> weakPlugin;
490 __weak FlutterPluginAppLifeCycleDelegate* weakDelegate;
491 @autoreleasepool {
492 FakePlugin* fakePlugin = [[FakePlugin alloc] init];
493 weakPlugin = fakePlugin;
495 [delegate addDelegate:fakePlugin];
496 weakDelegate = delegate;
497 }
498 XCTAssertNil(weakPlugin);
499 XCTAssertNil(weakDelegate);
500}
501
502- (void)testApplicationWillFinishLaunchingSceneFallbackForwards {
504 id plugin = [[FakePlugin alloc] init];
505 id mockPlugin = OCMPartialMock(plugin);
506 [delegate addDelegate:mockPlugin];
507 id mockApplication = OCMClassMock([UIApplication class]);
508 NSDictionary* options = @{};
509
510 [delegate sceneFallbackWillFinishLaunchingApplication:mockApplication];
511 OCMVerify(times(1), [mockPlugin application:mockApplication
512 willFinishLaunchingWithOptions:options]);
513}
514
515- (void)testApplicationWillFinishLaunchingSceneFallbackNoForwardAfterWillLaunch {
517 id plugin = [[FakePlugin alloc] init];
518 id mockPlugin = OCMPartialMock(plugin);
519 [delegate addDelegate:mockPlugin];
520 id mockApplication = OCMClassMock([UIApplication class]);
521 NSDictionary* options = @{@"key" : @"value"};
522
523 [delegate application:mockApplication willFinishLaunchingWithOptions:options];
524 [delegate sceneFallbackWillFinishLaunchingApplication:mockApplication];
525 OCMVerify(times(1), [mockPlugin application:mockApplication
526 willFinishLaunchingWithOptions:options]);
527}
528
529- (void)testApplicationWillFinishLaunchingSceneFallbackNoForwardAfterDidLaunch {
531 id plugin = [[FakePlugin alloc] init];
532 id mockPlugin = OCMPartialMock(plugin);
533 [delegate addDelegate:mockPlugin];
534 id mockApplication = OCMClassMock([UIApplication class]);
535 NSDictionary* options = @{@"key" : @"value"};
536
537 [delegate application:mockApplication didFinishLaunchingWithOptions:options];
538 [delegate sceneFallbackWillFinishLaunchingApplication:mockApplication];
539 OCMVerify(times(0), [mockPlugin application:mockApplication
540 willFinishLaunchingWithOptions:options]);
541}
542
543- (void)testApplicationDidFinishLaunchingSceneFallbackForwards {
545 id plugin = [[FakePlugin alloc] init];
546 id mockPlugin = OCMPartialMock(plugin);
547 [delegate addDelegate:mockPlugin];
548 id mockApplication = OCMClassMock([UIApplication class]);
549 NSDictionary* options = @{};
550
551 [delegate sceneFallbackDidFinishLaunchingApplication:mockApplication];
552 OCMVerify(times(1), [mockPlugin application:mockApplication
553 didFinishLaunchingWithOptions:options]);
554}
555
556- (void)testApplicationDidFinishLaunchingSceneFallbackNoForward {
558 id plugin = [[FakePlugin alloc] init];
559 id mockPlugin = OCMPartialMock(plugin);
560 [delegate addDelegate:mockPlugin];
561 id mockApplication = OCMClassMock([UIApplication class]);
562 NSDictionary* options = @{@"key" : @"value"};
563
564 [delegate application:mockApplication didFinishLaunchingWithOptions:options];
565 [delegate sceneFallbackDidFinishLaunchingApplication:mockApplication];
566 OCMVerify(times(1), [mockPlugin application:mockApplication
567 didFinishLaunchingWithOptions:options]);
568}
569
570@end
const gchar FlBinaryMessengerMessageHandler handler
BOOL application:didFinishLaunchingWithOptions:(UIApplication *application,[didFinishLaunchingWithOptions] NSDictionary *launchOptions)
BOOL application:willFinishLaunchingWithOptions:(UIApplication *application,[willFinishLaunchingWithOptions] NSDictionary *launchOptions)
void addDelegate:(NSObject< FlutterApplicationLifeCycleDelegate > *delegate)
UITextSmartQuotesType smartQuotesType API_AVAILABLE(ios(11.0))
int BOOL