5#import <Foundation/Foundation.h>
6#import <OCMock/OCMock.h>
7#import <XCTest/XCTest.h>
9#import <objc/runtime.h>
15#import "flutter/shell/platform/darwin/common/test_utils_swift/test_utils_swift.h"
16#import "flutter/shell/platform/darwin/ios/InternalFlutterSwift/InternalFlutterSwift.h"
27@protocol TestFlutterPluginWithSceneEvents <NSObject, FlutterPlugin, FlutterSceneLifeCycleDelegate>
36+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
41@property(nonatomic)
BOOL ensureSemanticsEnabledCalled;
46- (void)ensureSemanticsEnabled {
47 _ensureSemanticsEnabledCalled = YES;
61@property(nonatomic, assign)
BOOL failOnDealloc;
67 XCTFail(
"FakeBinaryMessageRelay should not be deallocated");
89- (void)testShellGetters {
100- (void)testTaskRunnerPropertyStability {
115- (void)testInfoPlist {
117 NSURL* flutterFrameworkURL =
118 [NSBundle.mainBundle.privateFrameworksURL URLByAppendingPathComponent:@"Flutter.framework"];
119 NSBundle* flutterBundle = [NSBundle bundleWithURL:flutterFrameworkURL];
120 XCTAssertEqualObjects(flutterBundle.bundleIdentifier,
@"io.flutter.flutter");
122 NSDictionary<NSString*, id>* infoDictionary = flutterBundle.infoDictionary;
125 NSError* regexError = NULL;
126 NSRegularExpression* osVersionRegex =
127 [NSRegularExpression regularExpressionWithPattern:@"((0|[1-9]\\d*)\\.)*(0|[1-9]\\d*)"
128 options:NSRegularExpressionCaseInsensitive
130 XCTAssertNil(regexError);
133 NSString* testString =
@"9";
134 NSUInteger versionMatches =
135 [osVersionRegex numberOfMatchesInString:testString
136 options:NSMatchingAnchored
137 range:NSMakeRange(0, testString.length)];
138 XCTAssertEqual(versionMatches, 1UL);
140 versionMatches = [osVersionRegex numberOfMatchesInString:testString
141 options:NSMatchingAnchored
142 range:NSMakeRange(0, testString.length)];
143 XCTAssertEqual(versionMatches, 1UL);
144 testString =
@"9.0.1";
145 versionMatches = [osVersionRegex numberOfMatchesInString:testString
146 options:NSMatchingAnchored
147 range:NSMakeRange(0, testString.length)];
148 XCTAssertEqual(versionMatches, 1UL);
149 testString =
@".0.1";
150 versionMatches = [osVersionRegex numberOfMatchesInString:testString
151 options:NSMatchingAnchored
152 range:NSMakeRange(0, testString.length)];
153 XCTAssertEqual(versionMatches, 0UL);
156 NSString* minimumOSVersion = infoDictionary[@"MinimumOSVersion"];
157 versionMatches = [osVersionRegex numberOfMatchesInString:minimumOSVersion
158 options:NSMatchingAnchored
159 range:NSMakeRange(0, minimumOSVersion.length)];
160 XCTAssertEqual(versionMatches, 1UL);
163 XCTAssertEqual(((NSString*)infoDictionary[
@"FlutterEngine"]).
length, 40UL);
168 XCTAssertTrue(((NSString*)infoDictionary[
@"ClangVersion"]).
length > 15UL);
171- (void)testDeallocated {
177 XCTAssertNotNil(weakEngine);
179 XCTAssertNil(weakEngine);
182- (void)testSendMessageBeforeRun {
188 message:[@"bar" dataUsingEncoding:NSUTF8StringEncoding]
192- (void)testSetMessageHandlerBeforeRun {
197 setMessageHandlerOnChannel:
@"foo"
203- (void)testNilSetMessageHandlerBeforeRun {
208 binaryMessageHandler:nil]);
211- (void)testNotifyPluginOfDealloc {
212 id plugin = OCMProtocolMock(
@protocol(FlutterPlugin));
213 OCMStub([plugin detachFromEngineForRegistrar:[OCMArg any]]);
218 [registrar publish:plugin];
220 OCMVerify([plugin detachFromEngineForRegistrar:[OCMArg any]]);
223- (void)testGetViewControllerFromRegistrar {
226 id mockEngine = OCMPartialMock(
engine);
227 NSObject<FlutterPluginRegistrar>* registrar = [mockEngine registrarForPlugin:@"plugin"];
234- (void)testSetBinaryMessengerToSameBinaryMessenger {
248- (void)testRunningInitialRouteSendsNavigationMessage {
261 NSData* encodedSetInitialRouteMethod =
263 OCMVerify([mockBinaryMessenger sendOnChannel:
@"flutter/navigation"
264 message:encodedSetInitialRouteMethod]);
267- (void)testInitialRouteSettingsSendsNavigationMessage {
271 settings.route =
"test";
281 NSData* encodedSetInitialRouteMethod =
283 OCMVerify([mockBinaryMessenger sendOnChannel:
@"flutter/navigation"
284 message:encodedSetInitialRouteMethod]);
287- (void)testPlatformViewsControllerRenderingMetalBackend {
295- (void)testWaitForFirstFrameTimeout {
298 XCTestExpectation* timeoutFirstFrame = [
self expectationWithDescription:@"timeoutFirstFrame"];
301 if (timeoutFirstFrame) {
302 [timeoutFirstFrame fulfill];
305 [
self waitForExpectations:@[ timeoutFirstFrame ]];
315 XCTAssertNotNil(spawn);
318- (void)testEngineId {
321 int64_t id1 =
engine.engineIdentifier;
322 XCTAssertTrue(id1 != 0);
327 int64_t id2 = spawn.engineIdentifier;
329 XCTAssertEqual([
FlutterEngine engineForIdentifier:id2], spawn);
332- (void)testSetHandlerAfterRun {
334 XCTestExpectation* gotMessage = [
self expectationWithDescription:@"gotMessage"];
335 dispatch_async(dispatch_get_main_queue(), ^{
342 flutter::Engine::Delegate& delegate = shell;
343 auto message = std::make_unique<flutter::PlatformMessage>(
"foo", nullptr);
344 delegate.OnEngineHandlePlatformMessage(std::move(message));
348 [registrar.messenger setMessageHandlerOnChannel:@"foo"
349 binaryMessageHandler:^(NSData* message, FlutterBinaryReply reply) {
350 [gotMessage fulfill];
353 [
self waitForExpectations:@[ gotMessage ]];
356- (void)testThreadPrioritySetCorrectly {
357 XCTestExpectation* prioritiesSet = [
self expectationWithDescription:@"prioritiesSet"];
358 prioritiesSet.expectedFulfillmentCount = 2;
360 IMP mockSetThreadPriority =
361 imp_implementationWithBlock(^(NSThread* thread,
double threadPriority) {
362 if ([thread.name hasSuffix:
@".raster"]) {
363 XCTAssertEqual(threadPriority, 1.0);
364 [prioritiesSet fulfill];
365 }
else if ([thread.name hasSuffix:
@".io"]) {
366 XCTAssertEqual(threadPriority, 0.5);
367 [prioritiesSet fulfill];
370 Method method = class_getInstanceMethod([NSThread
class],
@selector(setThreadPriority:));
371 IMP originalSetThreadPriority = method_getImplementation(method);
372 method_setImplementation(method, mockSetThreadPriority);
376 [
self waitForExpectations:@[ prioritiesSet ]];
378 method_setImplementation(method, originalSetThreadPriority);
381- (void)testCanEnableDisableEmbedderAPIThroughInfoPlist {
385 settings.enable_software_rendering =
true;
392 id mockMainBundle = OCMPartialMock([NSBundle mainBundle]);
393 OCMStub([mockMainBundle objectForInfoDictionaryKey:
@"FLTEnableIOSEmbedderAPI"])
396 settings.enable_software_rendering =
true;
403- (void)testFlutterTextInputViewDidResignFirstResponderWillCallTextInputClientConnectionClosed {
408 [engine flutterTextInputView:nil didResignFirstResponderWithTextInputClient:1];
413 OCMVerify([mockBinaryMessenger sendOnChannel:
@"flutter/textinput" message:encodedMethodCall]);
416- (void)testFlutterEngineUpdatesDisplays {
418 id mockEngine = OCMPartialMock(
engine);
421 OCMVerify(times(1), [mockEngine updateDisplays]);
423 OCMVerify(times(2), [mockEngine updateDisplays]);
426- (void)testLifeCycleNotificationDidEnterBackgroundForApplication {
430 NSNotification* sceneNotification =
431 [NSNotification notificationWithName:UISceneDidEnterBackgroundNotification
434 NSNotification* applicationNotification =
435 [NSNotification notificationWithName:UIApplicationDidEnterBackgroundNotification
438 id mockEngine = OCMPartialMock(
engine);
439 [NSNotificationCenter.defaultCenter postNotification:sceneNotification];
440 [NSNotificationCenter.defaultCenter postNotification:applicationNotification];
441 OCMVerify(times(1), [mockEngine applicationDidEnterBackground:[OCMArg any]]);
443 BOOL gpuDisabled = NO;
444 [engine
shell].GetIsGpuDisabledSyncSwitch()->Execute(
448 XCTAssertTrue(gpuDisabled);
451- (void)testLifeCycleNotificationDidEnterBackgroundForScene {
452 id mockBundle = OCMPartialMock([NSBundle mainBundle]);
453 OCMStub([mockBundle objectForInfoDictionaryKey:
@"NSExtension"]).andReturn(@{
454 @"NSExtensionPointIdentifier" :
@"com.apple.share-services"
459 NSNotification* sceneNotification =
460 [NSNotification notificationWithName:UISceneDidEnterBackgroundNotification
463 NSNotification* applicationNotification =
464 [NSNotification notificationWithName:UIApplicationDidEnterBackgroundNotification
467 id mockEngine = OCMPartialMock(
engine);
468 [NSNotificationCenter.defaultCenter postNotification:sceneNotification];
469 [NSNotificationCenter.defaultCenter postNotification:applicationNotification];
470 OCMVerify(times(1), [mockEngine sceneDidEnterBackground:[OCMArg any]]);
472 BOOL gpuDisabled = NO;
473 [engine
shell].GetIsGpuDisabledSyncSwitch()->Execute(
477 XCTAssertTrue(gpuDisabled);
478 [mockBundle stopMocking];
481- (void)testLifeCycleNotificationWillEnterForegroundForApplication {
485 NSNotification* sceneNotification =
486 [NSNotification notificationWithName:UISceneWillEnterForegroundNotification
489 NSNotification* applicationNotification =
490 [NSNotification notificationWithName:UIApplicationWillEnterForegroundNotification
493 id mockEngine = OCMPartialMock(
engine);
494 [NSNotificationCenter.defaultCenter postNotification:sceneNotification];
495 [NSNotificationCenter.defaultCenter postNotification:applicationNotification];
496 OCMVerify(times(1), [mockEngine applicationWillEnterForeground:[OCMArg any]]);
498 BOOL gpuDisabled = YES;
499 [engine
shell].GetIsGpuDisabledSyncSwitch()->Execute(
503 XCTAssertFalse(gpuDisabled);
506- (void)testLifeCycleNotificationWillEnterForegroundForScene {
507 id mockBundle = OCMPartialMock([NSBundle mainBundle]);
508 OCMStub([mockBundle objectForInfoDictionaryKey:
@"NSExtension"]).andReturn(@{
509 @"NSExtensionPointIdentifier" :
@"com.apple.share-services"
514 NSNotification* sceneNotification =
515 [NSNotification notificationWithName:UISceneWillEnterForegroundNotification
518 NSNotification* applicationNotification =
519 [NSNotification notificationWithName:UIApplicationWillEnterForegroundNotification
522 id mockEngine = OCMPartialMock(
engine);
523 [NSNotificationCenter.defaultCenter postNotification:sceneNotification];
524 [NSNotificationCenter.defaultCenter postNotification:applicationNotification];
525 OCMVerify(times(1), [mockEngine sceneWillEnterForeground:[OCMArg any]]);
527 BOOL gpuDisabled = YES;
528 [engine
shell].GetIsGpuDisabledSyncSwitch()->Execute(
532 XCTAssertFalse(gpuDisabled);
533 [mockBundle stopMocking];
536- (void)testLifeCycleNotificationSceneWillConnect {
540 id mockScene = OCMClassMock([UIWindowScene
class]);
541 id mockLifecycleProvider = OCMProtocolMock(
@protocol(FlutterSceneLifeCycleProvider));
543 OCMStub([mockScene delegate]).andReturn(mockLifecycleProvider);
544 OCMStub([mockLifecycleProvider sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
546 NSNotification* sceneNotification =
547 [NSNotification notificationWithName:UISceneWillConnectNotification
551 [NSNotificationCenter.defaultCenter postNotification:sceneNotification];
552 OCMVerify(times(1), [mockLifecycleDelegate
engine:
engine
553 receivedConnectNotificationFor:mockScene]);
556- (void)testSpawnsShareGpuContext {
563 XCTAssertNotNil(spawn);
568 XCTAssertEqual(engine_context, spawn_context);
571- (void)testEnableSemanticsWhenFlutterViewAccessibilityDidCall {
573 engine.ensureSemanticsEnabledCalled = NO;
574 [engine flutterViewAccessibilityDidCall];
575 XCTAssertTrue(
engine.ensureSemanticsEnabledCalled);
578- (void)testCanMergePlatformAndUIThread {
579#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
590- (void)testCanUnMergePlatformAndUIThread {
591#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
603- (void)testAddSceneDelegateToRegistrar {
606 id mockEngine = OCMPartialMock(
engine);
607 NSObject<FlutterPluginRegistrar>* registrar = [mockEngine registrarForPlugin:@"plugin"];
608 id mockPlugin = OCMProtocolMock(
@protocol(TestFlutterPluginWithSceneEvents));
609 [registrar addSceneDelegate:mockPlugin];
611 OCMVerify(times(1), [mockEngine addSceneLifeCycleDelegate:[OCMArg any]]);
614- (void)testNotifyAppDelegateOfEngineInitialization {
618 id mockApplication = OCMClassMock([UIApplication
class]);
619 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
620 id mockAppDelegate = OCMProtocolMock(
@protocol(FlutterImplicitEngineDelegate));
621 OCMStub([mockApplication delegate]).andReturn(mockAppDelegate);
623 [engine performImplicitEngineCallback];
624 OCMVerify(times(1), [mockAppDelegate didInitializeImplicitFlutterEngine:[OCMArg any]]);
627- (void)testRegistrarForPlugin {
632 id mockBinaryMessenger = OCMProtocolMock(
@protocol(FlutterBinaryMessenger));
633 id mockTextureRegistry = OCMProtocolMock(
@protocol(FlutterTextureRegistry));
635 OCMStub([mockEngine
viewController]).andReturn(mockViewController);
636 OCMStub([mockEngine binaryMessenger]).andReturn(mockBinaryMessenger);
637 OCMStub([mockEngine textureRegistry]).andReturn(mockTextureRegistry);
638 OCMStub([mockEngine platformViewsController]).andReturn(mockPlatformViewController);
640 NSString* pluginKey =
@"plugin";
641 NSString* assetKey =
@"asset";
642 NSString* factoryKey =
@"platform_view_factory";
644 NSObject<FlutterPluginRegistrar>* registrar = [mockEngine
registrarForPlugin:pluginKey];
646 XCTAssertTrue([registrar respondsToSelector:
@selector(messenger)]);
647 XCTAssertTrue([registrar respondsToSelector:
@selector(textures)]);
648 XCTAssertTrue([registrar respondsToSelector:
@selector(registerViewFactory:withId:)]);
649 XCTAssertTrue([registrar
650 respondsToSelector:
@selector(registerViewFactory:withId:gestureRecognizersBlockingPolicy:)]);
651 XCTAssertTrue([registrar respondsToSelector:
@selector(
viewController)]);
652 XCTAssertTrue([registrar respondsToSelector:
@selector(publish:)]);
653 XCTAssertTrue([registrar respondsToSelector:
@selector(valuePublishedByPlugin:)]);
654 XCTAssertTrue([registrar respondsToSelector:
@selector(addMethodCallDelegate:
channel:)]);
655 XCTAssertTrue([registrar respondsToSelector:
@selector(addApplicationDelegate:)]);
656 XCTAssertTrue([registrar respondsToSelector:
@selector(lookupKeyForAsset:)]);
657 XCTAssertTrue([registrar respondsToSelector:
@selector(lookupKeyForAsset:fromPackage:)]);
660 XCTAssertEqual(registrar.messenger, mockBinaryMessenger);
661 XCTAssertEqual(registrar.textures, mockTextureRegistry);
662 XCTAssertEqual(registrar.viewController, mockViewController);
667 [registrar registerViewFactory:mockPlatformViewFactory withId:factoryKey];
668 [registrar registerViewFactory:mockPlatformViewFactory
670 gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager];
671 OCMVerify(times(2), [mockPlatformViewController registerViewFactory:mockPlatformViewFactory
673 gestureRecognizersBlockingPolicy:
677 id plugin = OCMProtocolMock(
@protocol(FlutterPlugin));
678 [registrar publish:plugin];
682 id published = [registrar valuePublishedByPlugin:pluginKey];
683 XCTAssertEqual(plugin, published);
686 [registrar lookupKeyForAsset:assetKey];
687 OCMVerify(times(1), [mockEngine lookupKeyForAsset:assetKey]);
688 [registrar lookupKeyForAsset:assetKey fromPackage:pluginKey];
689 OCMVerify(times(1), [mockEngine lookupKeyForAsset:assetKey fromPackage:pluginKey]);
692- (void)testRegistrarForApplication {
697 id mockBinaryMessenger = OCMProtocolMock(
@protocol(FlutterBinaryMessenger));
698 id mockTextureRegistry = OCMProtocolMock(
@protocol(FlutterTextureRegistry));
700 OCMStub([mockEngine
viewController]).andReturn(mockViewController);
701 OCMStub([mockEngine binaryMessenger]).andReturn(mockBinaryMessenger);
702 OCMStub([mockEngine textureRegistry]).andReturn(mockTextureRegistry);
703 OCMStub([mockEngine platformViewsController]).andReturn(mockPlatformViewController);
705 NSString* pluginKey =
@"plugin";
706 NSString* factoryKey =
@"platform_view_factory";
708 NSObject<FlutterApplicationRegistrar>* registrar = [mockEngine registrarForApplication:pluginKey];
710 XCTAssertTrue([registrar respondsToSelector:
@selector(messenger)]);
711 XCTAssertTrue([registrar respondsToSelector:
@selector(textures)]);
712 XCTAssertTrue([registrar respondsToSelector:
@selector(registerViewFactory:withId:)]);
713 XCTAssertTrue([registrar
714 respondsToSelector:
@selector(registerViewFactory:withId:gestureRecognizersBlockingPolicy:)]);
715 XCTAssertFalse([registrar respondsToSelector:
@selector(
viewController)]);
716 XCTAssertFalse([registrar respondsToSelector:
@selector(publish:)]);
717 XCTAssertFalse([registrar respondsToSelector:
@selector(valuePublishedByPlugin:)]);
718 XCTAssertFalse([registrar respondsToSelector:
@selector(addMethodCallDelegate:
channel:)]);
719 XCTAssertFalse([registrar respondsToSelector:
@selector(addApplicationDelegate:)]);
720 XCTAssertFalse([registrar respondsToSelector:
@selector(lookupKeyForAsset:)]);
721 XCTAssertFalse([registrar respondsToSelector:
@selector(lookupKeyForAsset:fromPackage:)]);
724 XCTAssertEqual(registrar.messenger, mockBinaryMessenger);
725 XCTAssertEqual(registrar.textures, mockTextureRegistry);
730 [registrar registerViewFactory:mockPlatformViewFactory withId:factoryKey];
731 [registrar registerViewFactory:mockPlatformViewFactory
733 gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager];
734 OCMVerify(times(2), [mockPlatformViewController registerViewFactory:mockPlatformViewFactory
736 gestureRecognizersBlockingPolicy:
740- (void)testSendDeepLinkToFrameworkTimesOut {
743 id mockEngine = OCMPartialMock(
engine);
744 id mockEngineFirstFrameCallback = [OCMArg invokeBlockWithArgs:@YES, nil];
745 OCMStub([mockEngine waitForFirstFrame:3.0
callback:mockEngineFirstFrameCallback]);
747 NSURL* url = [NSURL URLWithString:@"example.com"];
749 [mockEngine sendDeepLinkToFramework:url
750 completionHandler:^(BOOL success) {
751 XCTAssertFalse(success);
755- (void)testSendDeepLinkToFrameworkUsingNavigationChannel {
756 NSString* urlString =
@"example.com";
757 NSURL* url = [NSURL URLWithString:urlString];
760 id mockEngine = OCMPartialMock(
engine);
761 id mockEngineFirstFrameCallback = [OCMArg invokeBlockWithArgs:@NO, nil];
762 OCMStub([mockEngine waitForFirstFrame:3.0
callback:mockEngineFirstFrameCallback]);
764 OCMStub([mockEngine navigationChannel]).andReturn(mockNavigationChannel);
765 id mockNavigationChannelCallback = [OCMArg invokeBlockWithArgs:@1, nil];
766 OCMStub([mockNavigationChannel invokeMethod:
@"pushRouteInformation"
767 arguments:@{
@"location" : urlString}
768 result:mockNavigationChannelCallback]);
770 [mockEngine sendDeepLinkToFramework:url
771 completionHandler:^(BOOL success) {
772 XCTAssertTrue(success);
776- (void)testSendDeepLinkToFrameworkUsingNavigationChannelFails {
777 NSString* urlString =
@"example.com";
778 NSURL* url = [NSURL URLWithString:urlString];
781 id mockEngine = OCMPartialMock(
engine);
782 id mockEngineFirstFrameCallback = [OCMArg invokeBlockWithArgs:@NO, nil];
783 OCMStub([mockEngine waitForFirstFrame:3.0
callback:mockEngineFirstFrameCallback]);
785 OCMStub([mockEngine navigationChannel]).andReturn(mockNavigationChannel);
786 id mockNavigationChannelCallback = [OCMArg invokeBlockWithArgs:@0, nil];
787 OCMStub([mockNavigationChannel invokeMethod:
@"pushRouteInformation"
788 arguments:@{
@"location" : urlString}
789 result:mockNavigationChannelCallback]);
791 [mockEngine sendDeepLinkToFramework:url
792 completionHandler:^(BOOL success) {
793 XCTAssertFalse(success);
797#pragma mark - Scene Lifecycle Warning Tests
799- (void)testAddApplicationDelegateLogsWarningWhenPluginDoesNotConformToSceneDelegate {
800 FlutterStringOutputWriter* writer = [[FlutterStringOutputWriter alloc] init];
801 writer.expectedOutput =
@"uses deprecated application lifecycle events";
802 FlutterLogger.outputWriter = writer;
808 id mockPlugin = OCMProtocolMock(
@protocol(FlutterPlugin));
810 id mockAppDelegate = OCMProtocolMock(
@protocol(FlutterAppLifeCycleProvider));
811 id mockApplication = OCMClassMock([UIApplication
class]);
812 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
813 OCMStub([mockApplication delegate]).andReturn(mockAppDelegate);
815 [registrar addApplicationDelegate:mockPlugin];
817 XCTAssertTrue(writer.gotExpectedOutput,
818 @"Expected warning about plugin not adopting scenes was not logged");
821- (void)testAddApplicationDelegateDoesNotLogWarningWhenPluginConformsToSceneDelegate {
822 FlutterStringOutputWriter* writer = [[FlutterStringOutputWriter alloc] init];
823 FlutterLogger.outputWriter = writer;
826 id<FlutterPluginRegistrar> registrar = [engine
registrarForPlugin:@"TestPluginWithSceneEvents"];
828 id mockPlugin = OCMProtocolMock(
@protocol(TestFlutterPluginWithSceneEvents));
830 id mockAppDelegate = OCMProtocolMock(
@protocol(FlutterAppLifeCycleProvider));
831 id mockApplication = OCMClassMock([UIApplication
class]);
832 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
833 OCMStub([mockApplication delegate]).andReturn(mockAppDelegate);
835 [registrar addApplicationDelegate:mockPlugin];
837 XCTAssertFalse(writer.didLog,
@"No warning should be logged for scene-conforming plugin");
840- (void)testAddApplicationDelegateDoesNotLogWarningWhenPluginDoesNotUseLifecycleEvents {
841 FlutterStringOutputWriter* writer = [[FlutterStringOutputWriter alloc] init];
842 FlutterLogger.outputWriter = writer;
852 id mockAppDelegate = OCMProtocolMock(
@protocol(FlutterAppLifeCycleProvider));
853 id mockApplication = OCMClassMock([UIApplication
class]);
854 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
855 OCMStub([mockApplication delegate]).andReturn(mockAppDelegate);
857 [registrar addApplicationDelegate:plugin];
859 XCTAssertFalse(writer.didLog,
860 @"No warning should be logged for a plugin that doesn't use lifecycle events");
NS_ASSUME_NONNULL_BEGIN typedef void(^ FlutterBinaryReply)(NSData *_Nullable reply)
@ FlutterPlatformViewGestureRecognizersBlockingPolicyEager
const TaskRunners & GetTaskRunners() const override
If callers wish to interact directly with any shell subcomponents, they must (on the platform thread)...
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
fml::RefPtr< fml::TaskRunner > GetPlatformTaskRunner() const
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
HWND(* FlutterPlatformViewFactory)(const FlutterPlatformViewCreationParameters *)
FlutterDesktopBinaryReply callback
nullable FlutterFMLTaskRunner * uiTaskRunner()
nullable FlutterFMLTaskRunner * platformTaskRunner()
FlutterEngine * spawnWithEntrypoint:libraryURI:initialRoute:entrypointArgs:(nullable NSString *entrypoint,[libraryURI] nullable NSString *libraryURI,[initialRoute] nullable NSString *initialRoute,[entrypointArgs] nullable NSArray< NSString * > *entrypointArgs)
NSObject< FlutterBinaryMessenger > * binaryMessenger
flutter::PlatformViewIOS * platformView()
void setBinaryMessenger:(FlutterBinaryMessengerRelay *binaryMessenger)
flutter::IOSRenderingAPI platformViewsRenderingAPI()
BOOL runWithEntrypoint:initialRoute:(nullable NSString *entrypoint,[initialRoute] nullable NSString *initialRoute)
nullable FlutterFMLTaskRunner * rasterTaskRunner()
NSMutableDictionary * pluginPublications
FlutterViewController * viewController
void waitForFirstFrame:callback:(NSTimeInterval timeout,[callback] void(^ callback)(BOOL didTimeout))
instancetype methodCallWithMethodName:arguments:(NSString *method,[arguments] id _Nullable arguments)
flutter::Settings FLTDefaultSettingsForBundle(NSBundle *bundle, NSProcessInfo *processInfoOrNil)
FlutterViewController * viewController
nullable NSObject< FlutterPluginRegistrar > * registrarForPlugin:(NSString *pluginKey)
Represents the 2 code paths available when calling |SyncSwitchExecute|.