diff --git a/engine/src/flutter/shell/platform/darwin/ios/BUILD.gn b/engine/src/flutter/shell/platform/darwin/ios/BUILD.gn index 6bd0397b26..5e197c3158 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/BUILD.gn +++ b/engine/src/flutter/shell/platform/darwin/ios/BUILD.gn @@ -70,7 +70,9 @@ source_set("flutter_framework_source_arc") { "framework/Source/FlutterDartVMServicePublisher.mm", "framework/Source/FlutterEmbedderKeyResponder.h", "framework/Source/FlutterEmbedderKeyResponder.mm", + "framework/Source/FlutterEngine.mm", "framework/Source/FlutterEngineGroup.mm", + "framework/Source/FlutterEngine_Internal.h", "framework/Source/FlutterHeadlessDartRunner.mm", "framework/Source/FlutterKeyPrimaryResponder.h", "framework/Source/FlutterKeySecondaryResponder.h", @@ -186,8 +188,6 @@ source_set("flutter_framework_source") { # iOS embedder is migrating to ARC. # New files are highly encouraged to be in ARC. # To add new files in ARC, add them to the `flutter_framework_source_arc` target. - "framework/Source/FlutterEngine.mm", - "framework/Source/FlutterEngine_Internal.h", "framework/Source/FlutterViewController.mm", "framework/Source/FlutterViewController_Internal.h", "platform_view_ios.h", diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 713d4fd0e2..bcbb3575a0 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -42,6 +42,8 @@ #import "flutter/shell/platform/darwin/ios/rendering_api_selection.h" #include "flutter/shell/profiling/sampling_profiler.h" +FLUTTER_ASSERT_ARC + /// Inheriting ThreadConfigurer and use iOS platform thread API to configure the thread priorities /// Using iOS platform thread API to configure thread priority static void IOSPlatformThreadConfigSetter(const fml::Thread::ThreadConfig& config) { @@ -88,7 +90,7 @@ NSString* const kFlutterKeyDataChannel = @"flutter/keydata"; static constexpr int kNumProfilerSamplesPerSec = 5; @interface FlutterEngineRegistrar : NSObject -@property(nonatomic, assign) FlutterEngine* flutterEngine; +@property(nonatomic, weak) FlutterEngine* flutterEngine; - (instancetype)initWithPlugin:(NSString*)pluginKey flutterEngine:(FlutterEngine*)flutterEngine; @end @@ -97,6 +99,14 @@ static constexpr int kNumProfilerSamplesPerSec = 5; FlutterTextInputDelegate, FlutterBinaryMessenger, FlutterTextureRegistry> + +#pragma mark - Properties + +@property(nonatomic, readonly) FlutterDartProject* dartProject; +@property(nonatomic, readonly, copy) NSString* labelPrefix; +@property(nonatomic, readonly, assign) BOOL allowHeadlessExecution; +@property(nonatomic, readonly, assign) BOOL restorationEnabled; + // Maintains a dictionary of plugin names that have registered with the engine. Used by // FlutterEngineRegistrar to implement a FlutterPluginRegistrar. @property(nonatomic, readonly) NSMutableDictionary* pluginPublications; @@ -104,55 +114,53 @@ static constexpr int kNumProfilerSamplesPerSec = 5; @property(nonatomic, readwrite, copy) NSString* isolateId; @property(nonatomic, copy) NSString* initialRoute; -@property(nonatomic, retain) id flutterViewControllerWillDeallocObserver; +@property(nonatomic, strong) id flutterViewControllerWillDeallocObserver; +@property(nonatomic, strong) FlutterDartVMServicePublisher* publisher; +@property(nonatomic, assign) int64_t nextTextureId; + +#pragma mark - Channel properties + +@property(nonatomic, strong) FlutterPlatformPlugin* platformPlugin; +@property(nonatomic, strong) FlutterTextInputPlugin* textInputPlugin; +@property(nonatomic, strong) FlutterUndoManagerPlugin* undoManagerPlugin; +@property(nonatomic, strong) FlutterSpellCheckPlugin* spellCheckPlugin; +@property(nonatomic, strong) FlutterRestorationPlugin* restorationPlugin; +@property(nonatomic, strong) FlutterMethodChannel* localizationChannel; +@property(nonatomic, strong) FlutterMethodChannel* navigationChannel; +@property(nonatomic, strong) FlutterMethodChannel* restorationChannel; +@property(nonatomic, strong) FlutterMethodChannel* platformChannel; +@property(nonatomic, strong) FlutterMethodChannel* platformViewsChannel; +@property(nonatomic, strong) FlutterMethodChannel* textInputChannel; +@property(nonatomic, strong) FlutterMethodChannel* undoManagerChannel; +@property(nonatomic, strong) FlutterMethodChannel* scribbleChannel; +@property(nonatomic, strong) FlutterMethodChannel* spellCheckChannel; +@property(nonatomic, strong) FlutterBasicMessageChannel* lifecycleChannel; +@property(nonatomic, strong) FlutterBasicMessageChannel* systemChannel; +@property(nonatomic, strong) FlutterBasicMessageChannel* settingsChannel; +@property(nonatomic, strong) FlutterBasicMessageChannel* keyEventChannel; +@property(nonatomic, strong) FlutterMethodChannel* screenshotChannel; #pragma mark - Embedder API properties @property(nonatomic, assign) BOOL enableEmbedderAPI; // Function pointers for interacting with the embedder.h API. @property(nonatomic) FlutterEngineProcTable& embedderAPI; + @end @implementation FlutterEngine { - fml::scoped_nsobject _dartProject; std::shared_ptr _threadHost; std::unique_ptr _shell; - NSString* _labelPrefix; - std::unique_ptr> _weakFactory; + // TODO(cbracken): https://github.com/flutter/flutter/issues/155943 + // Migrate to @property(nonatomic, weak). fml::WeakNSObject _viewController; - fml::scoped_nsobject _publisher; std::shared_ptr _platformViewsController; flutter::IOSRenderingAPI _renderingApi; std::shared_ptr _profiler_metrics; std::shared_ptr _profiler; - // Channels - fml::scoped_nsobject _platformPlugin; - fml::scoped_nsobject _textInputPlugin; - fml::scoped_nsobject _undoManagerPlugin; - fml::scoped_nsobject _spellCheckPlugin; - fml::scoped_nsobject _restorationPlugin; - fml::scoped_nsobject _localizationChannel; - fml::scoped_nsobject _navigationChannel; - fml::scoped_nsobject _restorationChannel; - fml::scoped_nsobject _platformChannel; - fml::scoped_nsobject _platformViewsChannel; - fml::scoped_nsobject _textInputChannel; - fml::scoped_nsobject _undoManagerChannel; - fml::scoped_nsobject _scribbleChannel; - fml::scoped_nsobject _spellCheckChannel; - fml::scoped_nsobject _lifecycleChannel; - fml::scoped_nsobject _systemChannel; - fml::scoped_nsobject _settingsChannel; - fml::scoped_nsobject _keyEventChannel; - fml::scoped_nsobject _screenshotChannel; - - int64_t _nextTextureId; - - BOOL _allowHeadlessExecution; - BOOL _restorationEnabled; FlutterBinaryMessengerRelay* _binaryMessenger; FlutterTextureRegistryRelay* _textureRegistry; std::unique_ptr _connections; @@ -190,29 +198,21 @@ static constexpr int kNumProfilerSamplesPerSec = 5; _restorationEnabled = restorationEnabled; _allowHeadlessExecution = allowHeadlessExecution; _labelPrefix = [labelPrefix copy]; + _dartProject = project ?: [[FlutterDartProject alloc] init]; - _weakFactory = std::make_unique>(self); - - if (project == nil) { - _dartProject.reset([[FlutterDartProject alloc] init]); - } else { - _dartProject.reset([project retain]); - } - - _enableEmbedderAPI = _dartProject.get().settings.enable_embedder_api; + _enableEmbedderAPI = _dartProject.settings.enable_embedder_api; if (_enableEmbedderAPI) { NSLog(@"============== iOS: enable_embedder_api is on =============="); _embedderAPI.struct_size = sizeof(FlutterEngineProcTable); FlutterEngineGetProcAddresses(&_embedderAPI); } - if (!EnableTracingIfNecessary([_dartProject.get() settings])) { + if (!EnableTracingIfNecessary(_dartProject.settings)) { NSLog( @"Cannot create a FlutterEngine instance in debug mode without Flutter tooling or " @"Xcode.\n\nTo launch in debug mode in iOS 14+, run flutter run from Flutter tools, run " @"from an IDE with a Flutter IDE plugin or run the iOS project from Xcode.\nAlternatively " @"profile and release mode apps can be launched from the home screen."); - [self release]; return nil; } @@ -292,35 +292,22 @@ static constexpr int kNumProfilerSamplesPerSec = 5; object:self userInfo:nil]; - // It will be destroyed and invalidate its weak pointers - // before any other members are destroyed. - _weakFactory.reset(); - - /// nil out weak references. + // nil out weak references. + // TODO(cbracken): https://github.com/flutter/flutter/issues/156222 + // Ensure that FlutterEngineRegistrar is using weak pointers, then eliminate this code. [_registrars enumerateKeysAndObjectsUsingBlock:^(id key, FlutterEngineRegistrar* registrar, BOOL* stop) { registrar.flutterEngine = nil; }]; - [_labelPrefix release]; - [_initialRoute release]; - [_pluginPublications release]; - [_registrars release]; _binaryMessenger.parent = nil; _textureRegistry.parent = nil; - [_binaryMessenger release]; - [_textureRegistry release]; - _textureRegistry = nil; - [_isolateId release]; NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; if (_flutterViewControllerWillDeallocObserver) { [center removeObserver:_flutterViewControllerWillDeallocObserver]; - [_flutterViewControllerWillDeallocObserver release]; } [center removeObserver:self]; - - [super dealloc]; } - (flutter::Shell&)shell { @@ -328,10 +315,6 @@ static constexpr int kNumProfilerSamplesPerSec = 5; return *_shell; } -- (fml::WeakNSObject)getWeakNSObject { - return _weakFactory->GetWeakNSObject(); -} - - (void)updateViewportMetrics:(flutter::ViewportMetrics)viewportMetrics { if (!self.platformView) { return; @@ -429,16 +412,16 @@ static constexpr int kNumProfilerSamplesPerSec = 5; self.iosPlatformView->SetOwnerViewController(_viewController); [self maybeSetupPlatformViewChannels]; [self updateDisplays]; - _textInputPlugin.get().viewController = viewController; + self.textInputPlugin.viewController = viewController; if (viewController) { - __block FlutterEngine* blockSelf = self; + __weak __block FlutterEngine* weakSelf = self; self.flutterViewControllerWillDeallocObserver = [[NSNotificationCenter defaultCenter] addObserverForName:FlutterViewControllerWillDealloc object:viewController queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* note) { - [blockSelf notifyViewControllerDeallocated]; + [weakSelf notifyViewControllerDeallocated]; }]; } else { self.flutterViewControllerWillDeallocObserver = nil; @@ -455,16 +438,15 @@ static constexpr int kNumProfilerSamplesPerSec = 5; if (_flutterViewControllerWillDeallocObserver) { [[NSNotificationCenter defaultCenter] removeObserver:_flutterViewControllerWillDeallocObserver]; - [_flutterViewControllerWillDeallocObserver release]; } - _flutterViewControllerWillDeallocObserver = [observer retain]; + _flutterViewControllerWillDeallocObserver = observer; } } - (void)notifyViewControllerDeallocated { - [[self lifecycleChannel] sendMessage:@"AppLifecycleState.detached"]; - _textInputPlugin.get().viewController = nil; - if (!_allowHeadlessExecution) { + [self.lifecycleChannel sendMessage:@"AppLifecycleState.detached"]; + self.textInputPlugin.viewController = nil; + if (!self.allowHeadlessExecution) { [self destroyContext]; } else if (_shell) { flutter::PlatformViewIOS* platform_view = [self iosPlatformView]; @@ -472,7 +454,7 @@ static constexpr int kNumProfilerSamplesPerSec = 5; platform_view->SetOwnerViewController({}); } } - [_textInputPlugin.get() resetViewResponder]; + [self.textInputPlugin resetViewResponder]; _viewController.reset(); } @@ -492,88 +474,46 @@ static constexpr int kNumProfilerSamplesPerSec = 5; return _viewController.get(); } -- (FlutterPlatformPlugin*)platformPlugin { - return _platformPlugin.get(); -} - (std::shared_ptr&)platformViewsController { return _platformViewsController; } -- (FlutterTextInputPlugin*)textInputPlugin { - return _textInputPlugin.get(); -} -- (FlutterUndoManagerPlugin*)undoManagerPlugin { - return _undoManagerPlugin.get(); -} -- (FlutterRestorationPlugin*)restorationPlugin { - return _restorationPlugin.get(); -} -- (FlutterMethodChannel*)localizationChannel { - return _localizationChannel.get(); -} -- (FlutterMethodChannel*)navigationChannel { - return _navigationChannel.get(); -} -- (FlutterMethodChannel*)restorationChannel { - return _restorationChannel.get(); -} -- (FlutterMethodChannel*)platformChannel { - return _platformChannel.get(); -} -- (FlutterMethodChannel*)textInputChannel { - return _textInputChannel.get(); -} -- (FlutterMethodChannel*)undoManagerChannel { - return _undoManagerChannel.get(); -} -- (FlutterMethodChannel*)scribbleChannel { - return _scribbleChannel.get(); -} -- (FlutterMethodChannel*)spellCheckChannel { - return _spellCheckChannel.get(); -} -- (FlutterBasicMessageChannel*)lifecycleChannel { - return _lifecycleChannel.get(); -} -- (FlutterBasicMessageChannel*)systemChannel { - return _systemChannel.get(); -} -- (FlutterBasicMessageChannel*)settingsChannel { - return _settingsChannel.get(); -} -- (FlutterBasicMessageChannel*)keyEventChannel { - return _keyEventChannel.get(); -} - (NSURL*)observatoryUrl { - return [_publisher.get() url]; + return self.publisher.url; } - (NSURL*)vmServiceUrl { - return [_publisher.get() url]; + return self.publisher.url; } - (void)resetChannels { - _localizationChannel.reset(); - _navigationChannel.reset(); - _restorationChannel.reset(); - _platformChannel.reset(); - _platformViewsChannel.reset(); - _textInputChannel.reset(); - _undoManagerChannel.reset(); - _scribbleChannel.reset(); - _lifecycleChannel.reset(); - _systemChannel.reset(); - _settingsChannel.reset(); - _keyEventChannel.reset(); - _spellCheckChannel.reset(); + self.localizationChannel = nil; + self.navigationChannel = nil; + self.restorationChannel = nil; + self.platformChannel = nil; + self.platformViewsChannel = nil; + self.textInputChannel = nil; + self.undoManagerChannel = nil; + self.scribbleChannel = nil; + self.lifecycleChannel = nil; + self.systemChannel = nil; + self.settingsChannel = nil; + self.keyEventChannel = nil; + self.spellCheckChannel = nil; } - (void)startProfiler { FML_DCHECK(!_threadHost->name_prefix.empty()); _profiler_metrics = std::make_shared(); + __weak FlutterEngine* weakSelf = self; _profiler = std::make_shared( _threadHost->name_prefix.c_str(), _threadHost->profiler_thread->GetTaskRunner(), - [self]() { return self->_profiler_metrics->GenerateSample(); }, kNumProfilerSamplesPerSec); + [weakSelf]() { + FlutterEngine* strongSelf = weakSelf; + return strongSelf ? strongSelf->_profiler_metrics->GenerateSample() + : flutter::ProfileSample{}; + }, + kNumProfilerSamplesPerSec); _profiler->Start(); } @@ -583,165 +523,155 @@ static constexpr int kNumProfilerSamplesPerSec = 5; - (void)setUpChannels { // This will be invoked once the shell is done setting up and the isolate ID // for the UI isolate is available. - fml::WeakNSObject weakSelf = [self getWeakNSObject]; + __weak FlutterEngine* weakSelf = self; [_binaryMessenger setMessageHandlerOnChannel:@"flutter/isolate" binaryMessageHandler:^(NSData* message, FlutterBinaryReply reply) { if (weakSelf) { - weakSelf.get().isolateId = + weakSelf.isolateId = [[FlutterStringCodec sharedInstance] decode:message]; } }]; - _localizationChannel.reset([[FlutterMethodChannel alloc] - initWithName:@"flutter/localization" - binaryMessenger:self.binaryMessenger - codec:[FlutterJSONMethodCodec sharedInstance]]); + self.localizationChannel = + [[FlutterMethodChannel alloc] initWithName:@"flutter/localization" + binaryMessenger:self.binaryMessenger + codec:[FlutterJSONMethodCodec sharedInstance]]; - _navigationChannel.reset([[FlutterMethodChannel alloc] - initWithName:@"flutter/navigation" - binaryMessenger:self.binaryMessenger - codec:[FlutterJSONMethodCodec sharedInstance]]); + self.navigationChannel = + [[FlutterMethodChannel alloc] initWithName:@"flutter/navigation" + binaryMessenger:self.binaryMessenger + codec:[FlutterJSONMethodCodec sharedInstance]]; if ([_initialRoute length] > 0) { // Flutter isn't ready to receive this method call yet but the channel buffer will cache this. - [_navigationChannel invokeMethod:@"setInitialRoute" arguments:_initialRoute]; - [_initialRoute release]; + [self.navigationChannel invokeMethod:@"setInitialRoute" arguments:_initialRoute]; _initialRoute = nil; } - _restorationChannel.reset([[FlutterMethodChannel alloc] - initWithName:@"flutter/restoration" - binaryMessenger:self.binaryMessenger - codec:[FlutterStandardMethodCodec sharedInstance]]); + self.restorationChannel = + [[FlutterMethodChannel alloc] initWithName:@"flutter/restoration" + binaryMessenger:self.binaryMessenger + codec:[FlutterStandardMethodCodec sharedInstance]]; - _platformChannel.reset([[FlutterMethodChannel alloc] - initWithName:@"flutter/platform" - binaryMessenger:self.binaryMessenger - codec:[FlutterJSONMethodCodec sharedInstance]]); + self.platformChannel = + [[FlutterMethodChannel alloc] initWithName:@"flutter/platform" + binaryMessenger:self.binaryMessenger + codec:[FlutterJSONMethodCodec sharedInstance]]; - _platformViewsChannel.reset([[FlutterMethodChannel alloc] - initWithName:@"flutter/platform_views" - binaryMessenger:self.binaryMessenger - codec:[FlutterStandardMethodCodec sharedInstance]]); + self.platformViewsChannel = + [[FlutterMethodChannel alloc] initWithName:@"flutter/platform_views" + binaryMessenger:self.binaryMessenger + codec:[FlutterStandardMethodCodec sharedInstance]]; - _textInputChannel.reset([[FlutterMethodChannel alloc] - initWithName:@"flutter/textinput" - binaryMessenger:self.binaryMessenger - codec:[FlutterJSONMethodCodec sharedInstance]]); + self.textInputChannel = + [[FlutterMethodChannel alloc] initWithName:@"flutter/textinput" + binaryMessenger:self.binaryMessenger + codec:[FlutterJSONMethodCodec sharedInstance]]; - _undoManagerChannel.reset([[FlutterMethodChannel alloc] - initWithName:@"flutter/undomanager" - binaryMessenger:self.binaryMessenger - codec:[FlutterJSONMethodCodec sharedInstance]]); + self.undoManagerChannel = + [[FlutterMethodChannel alloc] initWithName:@"flutter/undomanager" + binaryMessenger:self.binaryMessenger + codec:[FlutterJSONMethodCodec sharedInstance]]; - _scribbleChannel.reset([[FlutterMethodChannel alloc] - initWithName:@"flutter/scribble" - binaryMessenger:self.binaryMessenger - codec:[FlutterJSONMethodCodec sharedInstance]]); + self.scribbleChannel = + [[FlutterMethodChannel alloc] initWithName:@"flutter/scribble" + binaryMessenger:self.binaryMessenger + codec:[FlutterJSONMethodCodec sharedInstance]]; - _spellCheckChannel.reset([[FlutterMethodChannel alloc] - initWithName:@"flutter/spellcheck" - binaryMessenger:self.binaryMessenger - codec:[FlutterStandardMethodCodec sharedInstance]]); + self.spellCheckChannel = + [[FlutterMethodChannel alloc] initWithName:@"flutter/spellcheck" + binaryMessenger:self.binaryMessenger + codec:[FlutterStandardMethodCodec sharedInstance]]; - _lifecycleChannel.reset([[FlutterBasicMessageChannel alloc] - initWithName:@"flutter/lifecycle" - binaryMessenger:self.binaryMessenger - codec:[FlutterStringCodec sharedInstance]]); + self.lifecycleChannel = + [[FlutterBasicMessageChannel alloc] initWithName:@"flutter/lifecycle" + binaryMessenger:self.binaryMessenger + codec:[FlutterStringCodec sharedInstance]]; - _systemChannel.reset([[FlutterBasicMessageChannel alloc] - initWithName:@"flutter/system" - binaryMessenger:self.binaryMessenger - codec:[FlutterJSONMessageCodec sharedInstance]]); + self.systemChannel = + [[FlutterBasicMessageChannel alloc] initWithName:@"flutter/system" + binaryMessenger:self.binaryMessenger + codec:[FlutterJSONMessageCodec sharedInstance]]; - _settingsChannel.reset([[FlutterBasicMessageChannel alloc] - initWithName:@"flutter/settings" - binaryMessenger:self.binaryMessenger - codec:[FlutterJSONMessageCodec sharedInstance]]); + self.settingsChannel = + [[FlutterBasicMessageChannel alloc] initWithName:@"flutter/settings" + binaryMessenger:self.binaryMessenger + codec:[FlutterJSONMessageCodec sharedInstance]]; - _keyEventChannel.reset([[FlutterBasicMessageChannel alloc] - initWithName:@"flutter/keyevent" - binaryMessenger:self.binaryMessenger - codec:[FlutterJSONMessageCodec sharedInstance]]); + self.keyEventChannel = + [[FlutterBasicMessageChannel alloc] initWithName:@"flutter/keyevent" + binaryMessenger:self.binaryMessenger + codec:[FlutterJSONMessageCodec sharedInstance]]; - FlutterTextInputPlugin* textInputPlugin = [[FlutterTextInputPlugin alloc] initWithDelegate:self]; - _textInputPlugin.reset(textInputPlugin); - textInputPlugin.indirectScribbleDelegate = self; - [textInputPlugin setUpIndirectScribbleInteraction:self.viewController]; + self.textInputPlugin = [[FlutterTextInputPlugin alloc] initWithDelegate:self]; + self.textInputPlugin.indirectScribbleDelegate = self; + [self.textInputPlugin setUpIndirectScribbleInteraction:self.viewController]; - FlutterUndoManagerPlugin* undoManagerPlugin = - [[FlutterUndoManagerPlugin alloc] initWithDelegate:self]; - _undoManagerPlugin.reset(undoManagerPlugin); + self.undoManagerPlugin = [[FlutterUndoManagerPlugin alloc] initWithDelegate:self]; + self.platformPlugin = [[FlutterPlatformPlugin alloc] initWithEngine:self]; - _platformPlugin.reset([[FlutterPlatformPlugin alloc] initWithEngine:[self getWeakNSObject]]); + self.restorationPlugin = + [[FlutterRestorationPlugin alloc] initWithChannel:self.restorationChannel + restorationEnabled:self.restorationEnabled]; + self.spellCheckPlugin = [[FlutterSpellCheckPlugin alloc] init]; - _restorationPlugin.reset([[FlutterRestorationPlugin alloc] - initWithChannel:_restorationChannel.get() - restorationEnabled:_restorationEnabled]); - _spellCheckPlugin.reset([[FlutterSpellCheckPlugin alloc] init]); + self.screenshotChannel = + [[FlutterMethodChannel alloc] initWithName:@"flutter/screenshot" + binaryMessenger:self.binaryMessenger + codec:[FlutterStandardMethodCodec sharedInstance]]; - _screenshotChannel.reset([[FlutterMethodChannel alloc] - initWithName:@"flutter/screenshot" - binaryMessenger:self.binaryMessenger - codec:[FlutterStandardMethodCodec sharedInstance]]); - - [_screenshotChannel.get() - setMethodCallHandler:^(FlutterMethodCall* _Nonnull call, FlutterResult _Nonnull result) { - if (!(weakSelf.get() && weakSelf.get()->_shell && weakSelf.get()->_shell->IsSetup())) { - return result([FlutterError - errorWithCode:@"invalid_state" - message:@"Requesting screenshot while engine is not running." - details:nil]); - } - flutter::Rasterizer::Screenshot screenshot = - [weakSelf.get() screenshot:flutter::Rasterizer::ScreenshotType::SurfaceData - base64Encode:NO]; - if (!screenshot.data) { - return result([FlutterError errorWithCode:@"failure" - message:@"Unable to get screenshot." - details:nil]); - } - // TODO(gaaclarke): Find way to eliminate this data copy. - NSData* data = [NSData dataWithBytes:screenshot.data->writable_data() - length:screenshot.data->size()]; - NSString* format = [NSString stringWithUTF8String:screenshot.format.c_str()]; - NSNumber* width = @(screenshot.frame_size.fWidth); - NSNumber* height = @(screenshot.frame_size.fHeight); - return result(@[ width, height, format ?: [NSNull null], data ]); - }]; + [self.screenshotChannel setMethodCallHandler:^(FlutterMethodCall* _Nonnull call, + FlutterResult _Nonnull result) { + FlutterEngine* strongSelf = weakSelf; + if (!(strongSelf && strongSelf->_shell && strongSelf->_shell->IsSetup())) { + return result([FlutterError + errorWithCode:@"invalid_state" + message:@"Requesting screenshot while engine is not running." + details:nil]); + } + flutter::Rasterizer::Screenshot screenshot = + [strongSelf screenshot:flutter::Rasterizer::ScreenshotType::SurfaceData base64Encode:NO]; + if (!screenshot.data) { + return result([FlutterError errorWithCode:@"failure" + message:@"Unable to get screenshot." + details:nil]); + } + // TODO(gaaclarke): Find way to eliminate this data copy. + NSData* data = [NSData dataWithBytes:screenshot.data->writable_data() + length:screenshot.data->size()]; + NSString* format = [NSString stringWithUTF8String:screenshot.format.c_str()]; + NSNumber* width = @(screenshot.frame_size.fWidth); + NSNumber* height = @(screenshot.frame_size.fHeight); + return result(@[ width, height, format ?: [NSNull null], data ]); + }]; } - (void)maybeSetupPlatformViewChannels { if (_shell && self.shell.IsSetup()) { - FlutterPlatformPlugin* platformPlugin = _platformPlugin.get(); - [_platformChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { - [platformPlugin handleMethodCall:call result:result]; + __weak FlutterEngine* weakSelf = self; + + [self.platformChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { + [weakSelf.platformPlugin handleMethodCall:call result:result]; }]; - fml::WeakNSObject weakSelf = [self getWeakNSObject]; - [_platformViewsChannel.get() + [self.platformViewsChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { if (weakSelf) { - weakSelf.get().platformViewsController->OnMethodCall(call, result); + weakSelf.platformViewsController->OnMethodCall(call, result); } }]; - FlutterTextInputPlugin* textInputPlugin = _textInputPlugin.get(); - [_textInputChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { - [textInputPlugin handleMethodCall:call result:result]; + [self.textInputChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { + [weakSelf.textInputPlugin handleMethodCall:call result:result]; }]; - FlutterUndoManagerPlugin* undoManagerPlugin = _undoManagerPlugin.get(); - [_undoManagerChannel.get() - setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { - [undoManagerPlugin handleMethodCall:call result:result]; - }]; + [self.undoManagerChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { + [weakSelf.undoManagerPlugin handleMethodCall:call result:result]; + }]; - FlutterSpellCheckPlugin* spellCheckPlugin = _spellCheckPlugin.get(); - [_spellCheckChannel.get() - setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { - [spellCheckPlugin handleMethodCall:call result:result]; - }]; + [self.spellCheckChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { + [weakSelf.spellCheckPlugin handleMethodCall:call result:result]; + }]; } } @@ -754,9 +684,9 @@ static constexpr int kNumProfilerSamplesPerSec = 5; libraryURI:(NSString*)libraryOrNil entrypointArgs:(NSArray*)entrypointArgs { // Launch the Dart application with the inferred run configuration. - self.shell.RunEngine([_dartProject.get() runConfigurationForEntrypoint:entrypoint - libraryOrNil:libraryOrNil - entrypointArgs:entrypointArgs]); + self.shell.RunEngine([self.dartProject runConfigurationForEntrypoint:entrypoint + libraryOrNil:libraryOrNil + entrypointArgs:entrypointArgs]); } - (void)setUpShell:(std::unique_ptr)shell @@ -765,8 +695,8 @@ static constexpr int kNumProfilerSamplesPerSec = 5; [self setUpChannels]; [self onLocaleUpdated:nil]; [self updateDisplays]; - _publisher.reset([[FlutterDartVMServicePublisher alloc] - initWithEnableVMServicePublication:doesVMServicePublication]); + self.publisher = [[FlutterDartVMServicePublisher alloc] + initWithEnableVMServicePublication:doesVMServicePublication]; [self maybeSetupPlatformViewChannels]; _shell->SetGpuAvailability(_isGpuDisabled ? flutter::GpuAvailability::kUnavailable : flutter::GpuAvailability::kAvailable); @@ -845,7 +775,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS self.initialRoute = initialRoute; - auto settings = [_dartProject.get() settings]; + auto settings = [self.dartProject settings]; if (initialRoute != nil) { self.initialRoute = initialRoute; } else if (settings.route.empty() == false) { @@ -854,24 +784,28 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS FlutterView.forceSoftwareRendering = settings.enable_software_rendering; - auto platformData = [_dartProject.get() defaultPlatformData]; + auto platformData = [self.dartProject defaultPlatformData]; SetEntryPoint(&settings, entrypoint, libraryURI); - NSString* threadLabel = [FlutterEngine generateThreadLabel:_labelPrefix]; + NSString* threadLabel = [FlutterEngine generateThreadLabel:self.labelPrefix]; _threadHost = std::make_shared(); *_threadHost = MakeThreadHost(threadLabel, settings); - // Lambda captures by pointers to ObjC objects are fine here because the - // create call is synchronous. + __weak FlutterEngine* weakSelf = self; flutter::Shell::CreateCallback on_create_platform_view = - [self](flutter::Shell& shell) { - [self recreatePlatformViewController]; - self->_platformViewsController->SetTaskRunner( + [weakSelf](flutter::Shell& shell) { + FlutterEngine* strongSelf = weakSelf; + if (!strongSelf) { + return std::unique_ptr(); + } + [strongSelf recreatePlatformViewController]; + strongSelf->_platformViewsController->SetTaskRunner( shell.GetTaskRunners().GetPlatformTaskRunner()); return std::make_unique( - shell, self->_renderingApi, self->_platformViewsController, shell.GetTaskRunners(), - shell.GetConcurrentWorkerTaskRunner(), shell.GetIsGpuDisabledSyncSwitch()); + shell, strongSelf->_renderingApi, strongSelf->_platformViewsController, + shell.GetTaskRunners(), shell.GetConcurrentWorkerTaskRunner(), + shell.GetIsGpuDisabledSyncSwitch()); }; flutter::Shell::CreateCallback on_create_rasterizer = @@ -988,7 +922,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS if (_shell) { _shell->NotifyLowMemoryWarning(); } - [_systemChannel sendMessage:@{@"type" : @"memoryPressure"}]; + [self.systemChannel sendMessage:@{@"type" : @"memoryPressure"}]; } #pragma mark - Text input delegate @@ -996,23 +930,23 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS - (void)flutterTextInputView:(FlutterTextInputView*)textInputView updateEditingClient:(int)client withState:(NSDictionary*)state { - [_textInputChannel.get() invokeMethod:@"TextInputClient.updateEditingState" - arguments:@[ @(client), state ]]; + [self.textInputChannel invokeMethod:@"TextInputClient.updateEditingState" + arguments:@[ @(client), state ]]; } - (void)flutterTextInputView:(FlutterTextInputView*)textInputView updateEditingClient:(int)client withState:(NSDictionary*)state withTag:(NSString*)tag { - [_textInputChannel.get() invokeMethod:@"TextInputClient.updateEditingStateWithTag" - arguments:@[ @(client), @{tag : state} ]]; + [self.textInputChannel invokeMethod:@"TextInputClient.updateEditingStateWithTag" + arguments:@[ @(client), @{tag : state} ]]; } - (void)flutterTextInputView:(FlutterTextInputView*)textInputView updateEditingClient:(int)client withDelta:(NSDictionary*)delta { - [_textInputChannel.get() invokeMethod:@"TextInputClient.updateEditingStateWithDeltas" - arguments:@[ @(client), delta ]]; + [self.textInputChannel invokeMethod:@"TextInputClient.updateEditingStateWithDeltas" + arguments:@[ @(client), delta ]]; } - (void)flutterTextInputView:(FlutterTextInputView*)textInputView @@ -1031,8 +965,8 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS stateString = @"FloatingCursorDragState.end"; break; } - [_textInputChannel.get() invokeMethod:@"TextInputClient.updateFloatingCursor" - arguments:@[ @(client), stateString, position ]]; + [self.textInputChannel invokeMethod:@"TextInputClient.updateFloatingCursor" + arguments:@[ @(client), stateString, position ]]; } - (void)flutterTextInputView:(FlutterTextInputView*)textInputView @@ -1078,22 +1012,22 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS actionString = @"TextInputAction.newline"; break; } - [_textInputChannel.get() invokeMethod:@"TextInputClient.performAction" - arguments:@[ @(client), actionString ]]; + [self.textInputChannel invokeMethod:@"TextInputClient.performAction" + arguments:@[ @(client), actionString ]]; } - (void)flutterTextInputView:(FlutterTextInputView*)textInputView showAutocorrectionPromptRectForStart:(NSUInteger)start end:(NSUInteger)end withClient:(int)client { - [_textInputChannel.get() invokeMethod:@"TextInputClient.showAutocorrectionPromptRect" - arguments:@[ @(client), @(start), @(end) ]]; + [self.textInputChannel invokeMethod:@"TextInputClient.showAutocorrectionPromptRect" + arguments:@[ @(client), @(start), @(end) ]]; } - (void)flutterTextInputView:(FlutterTextInputView*)textInputView willDismissEditMenuWithTextInputClient:(int)client { - [_platformChannel.get() invokeMethod:@"ContextMenu.onDismissSystemContextMenu" - arguments:@[ @(client) ]]; + [self.platformChannel invokeMethod:@"ContextMenu.onDismissSystemContextMenu" + arguments:@[ @(client) ]]; } #pragma mark - FlutterViewEngineDelegate @@ -1102,7 +1036,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS // TODO(justinmc): Switch from the TextInputClient to Scribble channel when // the framework has finished transitioning to the Scribble channel. // https://github.com/flutter/flutter/pull/115296 - [_textInputChannel.get() invokeMethod:@"TextInputClient.showToolbar" arguments:@[ @(client) ]]; + [self.textInputChannel invokeMethod:@"TextInputClient.showToolbar" arguments:@[ @(client) ]]; } - (void)flutterTextInputPlugin:(FlutterTextInputPlugin*)textInputPlugin @@ -1112,7 +1046,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS // TODO(justinmc): Switch from the TextInputClient to Scribble channel when // the framework has finished transitioning to the Scribble channel. // https://github.com/flutter/flutter/pull/115296 - [_textInputChannel.get() + [self.textInputChannel invokeMethod:@"TextInputClient.focusElement" arguments:@[ elementIdentifier, @(referencePoint.x), @(referencePoint.y) ] result:callback]; @@ -1124,7 +1058,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS // TODO(justinmc): Switch from the TextInputClient to Scribble channel when // the framework has finished transitioning to the Scribble channel. // https://github.com/flutter/flutter/pull/115296 - [_textInputChannel.get() + [self.textInputChannel invokeMethod:@"TextInputClient.requestElementsInRect" arguments:@[ @(rect.origin.x), @(rect.origin.y), @(rect.size.width), @(rect.size.height) ] result:callback]; @@ -1134,15 +1068,14 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS // TODO(justinmc): Switch from the TextInputClient to Scribble channel when // the framework has finished transitioning to the Scribble channel. // https://github.com/flutter/flutter/pull/115296 - [_textInputChannel.get() invokeMethod:@"TextInputClient.scribbleInteractionBegan" arguments:nil]; + [self.textInputChannel invokeMethod:@"TextInputClient.scribbleInteractionBegan" arguments:nil]; } - (void)flutterTextInputViewScribbleInteractionFinished:(FlutterTextInputView*)textInputView { // TODO(justinmc): Switch from the TextInputClient to Scribble channel when // the framework has finished transitioning to the Scribble channel. // https://github.com/flutter/flutter/pull/115296 - [_textInputChannel.get() invokeMethod:@"TextInputClient.scribbleInteractionFinished" - arguments:nil]; + [self.textInputChannel invokeMethod:@"TextInputClient.scribbleInteractionFinished" arguments:nil]; } - (void)flutterTextInputView:(FlutterTextInputView*)textInputView @@ -1151,8 +1084,8 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS // TODO(justinmc): Switch from the TextInputClient to Scribble channel when // the framework has finished transitioning to the Scribble channel. // https://github.com/flutter/flutter/pull/115296 - [_textInputChannel.get() invokeMethod:@"TextInputClient.insertTextPlaceholder" - arguments:@[ @(client), @(size.width), @(size.height) ]]; + [self.textInputChannel invokeMethod:@"TextInputClient.insertTextPlaceholder" + arguments:@[ @(client), @(size.width), @(size.height) ]]; } - (void)flutterTextInputView:(FlutterTextInputView*)textInputView @@ -1160,8 +1093,8 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS // TODO(justinmc): Switch from the TextInputClient to Scribble channel when // the framework has finished transitioning to the Scribble channel. // https://github.com/flutter/flutter/pull/115296 - [_textInputChannel.get() invokeMethod:@"TextInputClient.removeTextPlaceholder" - arguments:@[ @(client) ]]; + [self.textInputChannel invokeMethod:@"TextInputClient.removeTextPlaceholder" + arguments:@[ @(client) ]]; } - (void)flutterTextInputView:(FlutterTextInputView*)textInputView @@ -1169,8 +1102,8 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS // When flutter text input view resign first responder, send a message to // framework to ensure the focus state is correct. This is useful when close // keyboard from platform side. - [_textInputChannel.get() invokeMethod:@"TextInputClient.onConnectionClosed" - arguments:@[ @(client) ]]; + [self.textInputChannel invokeMethod:@"TextInputClient.onConnectionClosed" + arguments:@[ @(client) ]]; // Platform view's first responder detection logic: // @@ -1197,7 +1130,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS return; } - [_platformViewsChannel.get() invokeMethod:@"viewFocused" arguments:@(platform_view_id)]; + [self.platformViewsChannel invokeMethod:@"viewFocused" arguments:@(platform_view_id)]; }); } @@ -1205,7 +1138,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS - (void)handleUndoWithDirection:(FlutterUndoRedoDirection)direction { NSString* action = (direction == FlutterUndoRedoDirectionUndo) ? @"undo" : @"redo"; - [_undoManagerChannel.get() invokeMethod:@"UndoManagerClient.handleUndo" arguments:@[ action ]]; + [self.undoManagerChannel invokeMethod:@"UndoManagerClient.handleUndo" arguments:@[ action ]]; } - (UIView*)activeTextInputView { @@ -1244,8 +1177,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS // Discard the previous messenger and keep the new one. if (binaryMessenger != _binaryMessenger) { _binaryMessenger.parent = nil; - [_binaryMessenger release]; - _binaryMessenger = [binaryMessenger retain]; + _binaryMessenger = binaryMessenger; } } @@ -1317,7 +1249,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS #pragma mark - FlutterTextureRegistry - (int64_t)registerTexture:(NSObject*)texture { - int64_t textureId = _nextTextureId++; + int64_t textureId = self.nextTextureId++; self.iosPlatformView->RegisterExternalTexture(textureId, texture); return textureId; } @@ -1350,7 +1282,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS FlutterEngineRegistrar* result = [[FlutterEngineRegistrar alloc] initWithPlugin:pluginKey flutterEngine:self]; self.registrars[pluginKey] = result; - return [result autorelease]; + return result; } - (BOOL)hasPlugin:(NSString*)pluginKey { @@ -1406,10 +1338,10 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS - (void)onLocaleUpdated:(NSNotification*)notification { // Get and pass the user's preferred locale list to dart:ui. - NSMutableArray* localeData = [[[NSMutableArray alloc] init] autorelease]; + NSMutableArray* localeData = [[NSMutableArray alloc] init]; NSArray* preferredLocales = [NSLocale preferredLanguages]; for (NSString* localeID in preferredLocales) { - NSLocale* locale = [[[NSLocale alloc] initWithLocaleIdentifier:localeID] autorelease]; + NSLocale* locale = [[NSLocale alloc] initWithLocaleIdentifier:localeID]; NSString* languageCode = [locale objectForKey:NSLocaleLanguageCode]; NSString* countryCode = [locale objectForKey:NSLocaleCountryCode]; NSString* scriptCode = [locale objectForKey:NSLocaleScriptCode]; @@ -1446,13 +1378,13 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS initialRoute:(/*nullable*/ NSString*)initialRoute entrypointArgs:(/*nullable*/ NSArray*)entrypointArgs { NSAssert(_shell, @"Spawning from an engine without a shell (possibly not run)."); - FlutterEngine* result = [[FlutterEngine alloc] initWithName:_labelPrefix - project:_dartProject.get() - allowHeadlessExecution:_allowHeadlessExecution]; + FlutterEngine* result = [[FlutterEngine alloc] initWithName:self.labelPrefix + project:self.dartProject + allowHeadlessExecution:self.allowHeadlessExecution]; flutter::RunConfiguration configuration = - [_dartProject.get() runConfigurationForEntrypoint:entrypoint - libraryOrNil:libraryURI - entrypointArgs:entrypointArgs]; + [self.dartProject runConfigurationForEntrypoint:entrypoint + libraryOrNil:libraryURI + entrypointArgs:entrypointArgs]; fml::WeakPtr platform_view = _shell->GetPlatformView(); FML_DCHECK(platform_view); @@ -1489,7 +1421,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS result->_profiler_metrics = _profiler_metrics; result->_isGpuDisabled = _isGpuDisabled; [result setUpShell:std::move(shell) withVMServicePublication:NO]; - return [result autorelease]; + return result; } - (const flutter::ThreadHost&)threadHost { @@ -1497,7 +1429,7 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS } - (FlutterDartProject*)project { - return _dartProject.get(); + return self.dartProject; } - (BOOL)isUsingImpeller { @@ -1518,11 +1450,6 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS return self; } -- (void)dealloc { - [_pluginKey release]; - [super dealloc]; -} - - (NSObject*)messenger { return _flutterEngine.binaryMessenger; } diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h index d3252d27b2..71f79c2ba4 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h @@ -12,7 +12,7 @@ @interface FlutterPlatformPlugin : NSObject - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; -- (instancetype)initWithEngine:(fml::WeakNSObject)engine NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithEngine:(FlutterEngine*)engine NS_DESIGNATED_INITIALIZER; - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result; @end diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm index 283a2731fe..c8a0dc6fe4 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm @@ -82,7 +82,7 @@ static void SetStatusBarStyleForSharedApplication(UIStatusBarStyle style) { @implementation FlutterPlatformPlugin -- (instancetype)initWithEngine:(fml::WeakNSObject)engine { +- (instancetype)initWithEngine:(FlutterEngine*)engine { FML_DCHECK(engine) << "engine must be set"; self = [super init]; diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm index 38096e9cbf..b6259e120c 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm @@ -37,15 +37,12 @@ FLUTTER_ASSERT_ARC OCMStub([mockApplication sharedApplication]).andReturn(mockApplication); FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil]; - std::unique_ptr> _weakFactory = - std::make_unique>(engine); [engine runWithEntrypoint:nil]; XCTestExpectation* invokeExpectation = [self expectationWithDescription:@"Web search launched with escaped search term"]; - FlutterPlatformPlugin* plugin = - [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()]; + FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine]; FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin); FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"SearchWeb.invoke" @@ -71,15 +68,12 @@ FLUTTER_ASSERT_ARC OCMStub([mockApplication sharedApplication]).andReturn(mockApplication); FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil]; - std::unique_ptr> _weakFactory = - std::make_unique>(engine); [engine runWithEntrypoint:nil]; XCTestExpectation* invokeExpectation = [self expectationWithDescription:@"Web search launched with non escaped search term"]; - FlutterPlatformPlugin* plugin = - [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()]; + FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine]; FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin); FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"SearchWeb.invoke" @@ -103,8 +97,6 @@ FLUTTER_ASSERT_ARC - (void)testLookUpCallInitiated { FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil]; [engine runWithEntrypoint:nil]; - std::unique_ptr> _weakFactory = - std::make_unique>(engine); XCTestExpectation* presentExpectation = [self expectationWithDescription:@"Look Up view controller presented"]; @@ -114,8 +106,7 @@ FLUTTER_ASSERT_ARC bundle:nil]; FlutterViewController* mockEngineViewController = OCMPartialMock(engineViewController); - FlutterPlatformPlugin* plugin = - [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()]; + FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine]; FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin); FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"LookUp.invoke" @@ -134,8 +125,6 @@ FLUTTER_ASSERT_ARC - (void)testShareScreenInvoked { FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil]; [engine runWithEntrypoint:nil]; - std::unique_ptr> _weakFactory = - std::make_unique>(engine); XCTestExpectation* presentExpectation = [self expectationWithDescription:@"Share view controller presented"]; @@ -149,8 +138,7 @@ FLUTTER_ASSERT_ARC animated:YES completion:nil]); - FlutterPlatformPlugin* plugin = - [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()]; + FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine]; FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin); FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Share.invoke" @@ -169,8 +157,6 @@ FLUTTER_ASSERT_ARC - (void)testShareScreenInvokedOnIPad { FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil]; [engine runWithEntrypoint:nil]; - std::unique_ptr> _weakFactory = - std::make_unique>(engine); XCTestExpectation* presentExpectation = [self expectationWithDescription:@"Share view controller presented on iPad"]; @@ -187,8 +173,7 @@ FLUTTER_ASSERT_ARC id mockTraitCollection = OCMClassMock([UITraitCollection class]); OCMStub([mockTraitCollection userInterfaceIdiom]).andReturn(UIUserInterfaceIdiomPad); - FlutterPlatformPlugin* plugin = - [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()]; + FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine]; FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin); FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Share.invoke" @@ -207,10 +192,7 @@ FLUTTER_ASSERT_ARC - (void)testClipboardHasCorrectStrings { [UIPasteboard generalPasteboard].string = nil; FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil]; - std::unique_ptr> _weakFactory = - std::make_unique>(engine); - FlutterPlatformPlugin* plugin = - [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()]; + FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine]; XCTestExpectation* setStringExpectation = [self expectationWithDescription:@"setString"]; FlutterResult resultSet = ^(id result) { @@ -246,10 +228,7 @@ FLUTTER_ASSERT_ARC - (void)testClipboardSetDataToNullDoNotCrash { [UIPasteboard generalPasteboard].string = nil; FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil]; - std::unique_ptr> _weakFactory = - std::make_unique>(engine); - FlutterPlatformPlugin* plugin = - [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()]; + FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine]; XCTestExpectation* setStringExpectation = [self expectationWithDescription:@"setData"]; FlutterResult resultSet = ^(id result) { @@ -280,10 +259,7 @@ FLUTTER_ASSERT_ARC [[UINavigationController alloc] initWithRootViewController:flutterViewController]; UITabBarController* tabBarController = [[UITabBarController alloc] init]; tabBarController.viewControllers = @[ navigationController ]; - std::unique_ptr> _weakFactory = - std::make_unique>(engine); - FlutterPlatformPlugin* plugin = - [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()]; + FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine]; id navigationControllerMock = OCMPartialMock(navigationController); OCMStub([navigationControllerMock popViewControllerAnimated:YES]); @@ -303,12 +279,9 @@ FLUTTER_ASSERT_ARC - (void)testWhetherDeviceHasLiveTextInputInvokeCorrectly { FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil]; - std::unique_ptr> _weakFactory = - std::make_unique>(engine); XCTestExpectation* invokeExpectation = [self expectationWithDescription:@"isLiveTextInputAvailableInvoke"]; - FlutterPlatformPlugin* plugin = - [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()]; + FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:engine]; FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin); FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"LiveText.isLiveTextInputAvailable" @@ -331,8 +304,6 @@ FLUTTER_ASSERT_ARC [engine runWithEntrypoint:nil]; FlutterViewController* flutterViewController = [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil]; - std::unique_ptr> _weakFactory = - std::make_unique>(engine); XCTAssertFalse(flutterViewController.prefersStatusBarHidden); // Update to hidden. @@ -371,8 +342,6 @@ FLUTTER_ASSERT_ARC [engine runWithEntrypoint:nil]; FlutterViewController* flutterViewController = [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil]; - std::unique_ptr> _weakFactory = - std::make_unique>(engine); XCTAssertFalse(flutterViewController.prefersStatusBarHidden); // Update to hidden. @@ -420,8 +389,6 @@ FLUTTER_ASSERT_ARC [engine runWithEntrypoint:nil]; FlutterViewController* flutterViewController = [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil]; - std::unique_ptr> _weakFactory = - std::make_unique>(engine); // Update to hidden. FlutterPlatformPlugin* plugin = [engine platformPlugin]; @@ -471,8 +438,6 @@ FLUTTER_ASSERT_ARC [engine runWithEntrypoint:nil]; FlutterViewController* flutterViewController = [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil]; - std::unique_ptr> _weakFactory = - std::make_unique>(engine); XCTAssertFalse(flutterViewController.prefersStatusBarHidden); FlutterPlatformPlugin* plugin = [engine platformPlugin];