From 50a8e73615dac55703f29f4294144691ef757390 Mon Sep 17 00:00:00 2001 From: gaaclarke <30870216+gaaclarke@users.noreply.github.com> Date: Thu, 27 Jun 2019 17:25:32 -0700 Subject: [PATCH] Has a binary messenger (#9419) Made the engine and the view controllers have BinaryMessengers, not be BinaryMessengers. This allows us to break retain cycles and makes the leaking channels we have not less dire. --- ci/licenses_golden/licenses_flutter | 3 + shell/platform/darwin/ios/BUILD.gn | 1 + .../ios/framework/Headers/FlutterEngine.h | 9 ++- .../framework/Headers/FlutterViewController.h | 13 ++++- .../Source/FlutterBinaryMessengerRelay.h | 14 +++++ .../Source/FlutterBinaryMessengerRelay.mm | 47 +++++++++++++++ .../Source/FlutterBinaryMessengerRelayTest.mm | 58 +++++++++++++++++++ .../ios/framework/Source/FlutterEngine.mm | 47 +++++++++------ .../framework/Source/FlutterViewController.mm | 33 +++++++---- .../framework/Source/accessibility_bridge.mm | 3 +- .../framework/Headers/FLEViewController.h | 12 ++-- .../framework/Source/FLETextInputPlugin.mm | 2 +- .../framework/Source/FLEViewController.mm | 7 ++- .../IosUnitTests.xcodeproj/project.pbxproj | 4 ++ 14 files changed, 212 insertions(+), 41 deletions(-) create mode 100644 shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h create mode 100644 shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.mm create mode 100644 shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelayTest.mm diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 7ed9a70ba..fcec10922 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -681,6 +681,9 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewCo FILE: ../../../flutter/shell/platform/darwin/ios/framework/Info.plist FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate_Internal.h +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.mm +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelayTest.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterCallbackCache.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterCallbackCache_Internal.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm diff --git a/shell/platform/darwin/ios/BUILD.gn b/shell/platform/darwin/ios/BUILD.gn index 902358fad..4627c26b3 100644 --- a/shell/platform/darwin/ios/BUILD.gn +++ b/shell/platform/darwin/ios/BUILD.gn @@ -44,6 +44,7 @@ shared_library("create_flutter_framework_dylib") { sources = [ "framework/Source/FlutterAppDelegate.mm", "framework/Source/FlutterAppDelegate_Internal.h", + "framework/Source/FlutterBinaryMessengerRelay.mm", "framework/Source/FlutterCallbackCache.mm", "framework/Source/FlutterCallbackCache_Internal.h", "framework/Source/FlutterDartProject.mm", diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index 992a1c830..08f1058c2 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -38,8 +38,7 @@ * One of these methods must be invoked before calling `-setViewController:`. */ FLUTTER_EXPORT -@interface FlutterEngine - : NSObject +@interface FlutterEngine : NSObject /** * Initialize this FlutterEngine with a `FlutterDartProject`. * @@ -237,6 +236,12 @@ FLUTTER_EXPORT */ @property(nonatomic, readonly) NSURL* observatoryUrl; +/** + * The `FlutterBinaryMessenger` associated with this FlutterEngine (used for communicating with + * channels). + */ +@property(nonatomic, readonly) NSObject* binaryMessenger; + @end #endif // FLUTTER_FLUTTERENGINE_H_ diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h index de6fcc2aa..1d3f16dcc 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h @@ -41,8 +41,7 @@ extern NSNotificationName const FlutterSemanticsUpdateNotification; * forth between a FlutterViewController and other `UIViewController`s. */ FLUTTER_EXPORT -@interface FlutterViewController - : UIViewController +@interface FlutterViewController : UIViewController /** * Initializes this FlutterViewController with the specified `FlutterEngine`. @@ -165,6 +164,16 @@ FLUTTER_EXPORT */ @property(weak, nonatomic, readonly) FlutterEngine* engine; +/** + * The `FlutterBinaryMessenger` associated with this FlutterViewController (used for communicating + * with channels). + * + * @deprecated Since |FlutterViewController| just forwards binary messenger calls to the + * |FlutterEngine|, just use the FlutterEngine.binaryMessenger. + */ +@property(nonatomic, readonly) NSObject* binaryMessenger + __attribute__((deprecated)); + @end #endif // FLUTTER_FLUTTERVIEWCONTROLLER_H_ diff --git a/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h b/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h new file mode 100644 index 000000000..df668dd2a --- /dev/null +++ b/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h @@ -0,0 +1,14 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h" +#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" + +#ifndef NDEBUG +FLUTTER_EXPORT +#endif +@interface FlutterBinaryMessengerRelay : NSObject +@property(nonatomic, assign) NSObject* parent; +- (instancetype)initWithParent:(NSObject*)parent; +@end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.mm b/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.mm new file mode 100644 index 000000000..f21dce800 --- /dev/null +++ b/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.mm @@ -0,0 +1,47 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h" + +#include "flutter/fml/logging.h" + +@implementation FlutterBinaryMessengerRelay +#pragma mark - FlutterBinaryMessenger + +- (instancetype)initWithParent:(NSObject*)parent { + self = [super init]; + if (self != nil) { + self.parent = parent; + } + return self; +} + +- (void)sendOnChannel:(NSString*)channel message:(NSData*)message { + if (self.parent) { + [self.parent sendOnChannel:channel message:message binaryReply:nil]; + } else { + FML_LOG(WARNING) << "Communicating on a dead channel."; + } +} + +- (void)sendOnChannel:(NSString*)channel + message:(NSData*)message + binaryReply:(FlutterBinaryReply)callback { + if (self.parent) { + [self.parent sendOnChannel:channel message:message binaryReply:callback]; + } else { + FML_LOG(WARNING) << "Communicating on a dead channel."; + } +} + +- (void)setMessageHandlerOnChannel:(NSString*)channel + binaryMessageHandler:(FlutterBinaryMessageHandler)handler { + if (self.parent) { + [self.parent setMessageHandlerOnChannel:channel binaryMessageHandler:handler]; + } else { + FML_LOG(WARNING) << "Communicating on a dead channel."; + } +} + +@end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelayTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelayTest.mm new file mode 100644 index 000000000..08e07069c --- /dev/null +++ b/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelayTest.mm @@ -0,0 +1,58 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import +#import +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h" + +#ifndef __has_feature +#define __has_feature(x) 0 /* for non-clang compilers */ +#endif + +#if !__has_feature(objc_arc) +#error ARC must be enabled! +#endif + +@interface FlutterBinaryMessengerRelayTest : XCTestCase +@end + +@implementation FlutterBinaryMessengerRelayTest + +- (void)setUp { +} + +- (void)tearDown { +} + +- (void)testCreate { + id messenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); + FlutterBinaryMessengerRelay* relay = + [[FlutterBinaryMessengerRelay alloc] initWithParent:messenger]; + XCTAssertNotNil(relay); + XCTAssertEqual(messenger, relay.parent); +} + +- (void)testPassesCallOn { + id messenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); + FlutterBinaryMessengerRelay* relay = + [[FlutterBinaryMessengerRelay alloc] initWithParent:messenger]; + char messageData[] = {'a', 'a', 'r', 'o', 'n'}; + NSData* message = [NSData dataWithBytes:messageData length:sizeof(messageData)]; + NSString* channel = @"foobar"; + [relay sendOnChannel:channel message:message binaryReply:nil]; + OCMVerify([messenger sendOnChannel:channel message:message binaryReply:nil]); +} + +- (void)testDoesntPassCallOn { + id messenger = OCMStrictProtocolMock(@protocol(FlutterBinaryMessenger)); + FlutterBinaryMessengerRelay* relay = + [[FlutterBinaryMessengerRelay alloc] initWithParent:messenger]; + char messageData[] = {'a', 'a', 'r', 'o', 'n'}; + NSData* message = [NSData dataWithBytes:messageData length:sizeof(messageData)]; + NSString* channel = @"foobar"; + relay.parent = nil; + [relay sendOnChannel:channel message:message binaryReply:nil]; +} + +@end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 2d8ebc53e..b4b0a54a0 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -17,16 +17,17 @@ #include "flutter/shell/common/switches.h" #include "flutter/shell/common/thread_host.h" #include "flutter/shell/platform/darwin/common/command_line.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterObservatoryPublisher.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h" -#include "flutter/shell/platform/darwin/ios/ios_surface.h" -#include "flutter/shell/platform/darwin/ios/platform_view_ios.h" - -@interface FlutterEngine () +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterObservatoryPublisher.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h" +#import "flutter/shell/platform/darwin/ios/ios_surface.h" +#import "flutter/shell/platform/darwin/ios/platform_view_ios.h" + +@interface FlutterEngine () // Maintains a dictionary of plugin names that have registered with the engine. Used by // FlutterEngineRegistrar to implement a FlutterPluginRegistrar. @property(nonatomic, readonly) NSMutableDictionary* pluginPublications; @@ -65,6 +66,7 @@ uint64_t _nextPointerFlowId; BOOL _allowHeadlessExecution; + FlutterBinaryMessengerRelay* _binaryMessenger; } - (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)projectOrNil { @@ -92,6 +94,7 @@ _platformViewsController.reset(new flutter::FlutterPlatformViewsController()); [self setupChannels]; + _binaryMessenger = [[FlutterBinaryMessengerRelay alloc] initWithParent:self]; NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; [center addObserver:self @@ -104,6 +107,8 @@ - (void)dealloc { [_pluginPublications release]; + _binaryMessenger.parent = nil; + [_binaryMessenger release]; NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; [center removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; @@ -238,42 +243,42 @@ - (void)setupChannels { _localizationChannel.reset([[FlutterMethodChannel alloc] initWithName:@"flutter/localization" - binaryMessenger:self + binaryMessenger:self.binaryMessenger codec:[FlutterJSONMethodCodec sharedInstance]]); _navigationChannel.reset([[FlutterMethodChannel alloc] initWithName:@"flutter/navigation" - binaryMessenger:self + binaryMessenger:self.binaryMessenger codec:[FlutterJSONMethodCodec sharedInstance]]); _platformChannel.reset([[FlutterMethodChannel alloc] initWithName:@"flutter/platform" - binaryMessenger:self + binaryMessenger:self.binaryMessenger codec:[FlutterJSONMethodCodec sharedInstance]]); _platformViewsChannel.reset([[FlutterMethodChannel alloc] initWithName:@"flutter/platform_views" - binaryMessenger:self + binaryMessenger:self.binaryMessenger codec:[FlutterStandardMethodCodec sharedInstance]]); _textInputChannel.reset([[FlutterMethodChannel alloc] initWithName:@"flutter/textinput" - binaryMessenger:self + binaryMessenger:self.binaryMessenger codec:[FlutterJSONMethodCodec sharedInstance]]); _lifecycleChannel.reset([[FlutterBasicMessageChannel alloc] initWithName:@"flutter/lifecycle" - binaryMessenger:self + binaryMessenger:self.binaryMessenger codec:[FlutterStringCodec sharedInstance]]); _systemChannel.reset([[FlutterBasicMessageChannel alloc] initWithName:@"flutter/system" - binaryMessenger:self + binaryMessenger:self.binaryMessenger codec:[FlutterJSONMessageCodec sharedInstance]]); _settingsChannel.reset([[FlutterBasicMessageChannel alloc] initWithName:@"flutter/settings" - binaryMessenger:self + binaryMessenger:self.binaryMessenger codec:[FlutterJSONMessageCodec sharedInstance]]); _textInputPlugin.reset([[FlutterTextInputPlugin alloc] init]); @@ -508,6 +513,10 @@ return _shell->Screenshot(type, base64Encode); } +- (NSObject*)binaryMessenger { + return _binaryMessenger; +} + #pragma mark - FlutterBinaryMessenger - (void)sendOnChannel:(NSString*)channel message:(NSData*)message { @@ -615,7 +624,7 @@ } - (NSObject*)messenger { - return _flutterEngine; + return _flutterEngine.binaryMessenger; } - (NSObject*)textures { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 89b6db71b..2d3f4f215 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -14,16 +14,20 @@ #include "flutter/fml/platform/darwin/platform_version.h" #include "flutter/fml/platform/darwin/scoped_nsobject.h" #include "flutter/shell/common/thread_host.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h" -#include "flutter/shell/platform/darwin/ios/platform_view_ios.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h" +#import "flutter/shell/platform/darwin/ios/platform_view_ios.h" NSNotificationName const FlutterSemanticsUpdateNotification = @"FlutterSemanticsUpdate"; +@interface FlutterViewController () +@end + @implementation FlutterViewController { std::unique_ptr> _weakFactory; fml::scoped_nsobject _engine; @@ -40,6 +44,7 @@ NSNotificationName const FlutterSemanticsUpdateNotification = @"FlutterSemantics BOOL _viewOpaque; BOOL _engineNeedsLaunch; NSMutableSet* _ongoingTouches; + FlutterBinaryMessengerRelay* _binaryMessenger; } #pragma mark - Manage and override all designated initializers @@ -50,6 +55,7 @@ NSNotificationName const FlutterSemanticsUpdateNotification = @"FlutterSemantics NSAssert(engine != nil, @"Engine is required"); self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { + _binaryMessenger = [[FlutterBinaryMessengerRelay alloc] initWithParent:self]; _viewOpaque = YES; _engine.reset([engine retain]); _engineNeedsLaunch = NO; @@ -69,6 +75,7 @@ NSNotificationName const FlutterSemanticsUpdateNotification = @"FlutterSemantics bundle:(NSBundle*)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { + _binaryMessenger = [[FlutterBinaryMessengerRelay alloc] initWithParent:self]; _viewOpaque = YES; _weakFactory = std::make_unique>(self); _engine.reset([[FlutterEngine alloc] initWithName:@"io.flutter" @@ -466,6 +473,8 @@ NSNotificationName const FlutterSemanticsUpdateNotification = @"FlutterSemantics } - (void)dealloc { + _binaryMessenger.parent = nil; + [_binaryMessenger release]; [_engine.get() notifyViewControllerDeallocated]; [[NSNotificationCenter defaultCenter] removeObserver:self]; [super dealloc]; @@ -978,23 +987,27 @@ constexpr CGFloat kStandardStatusBarHeight = 20.0; return [_engine.get() platformViewsController]; } +- (NSObject*)binaryMessenger { + return _binaryMessenger; +} + #pragma mark - FlutterBinaryMessenger - (void)sendOnChannel:(NSString*)channel message:(NSData*)message { - [_engine.get() sendOnChannel:channel message:message]; + [_engine.get().binaryMessenger sendOnChannel:channel message:message]; } - (void)sendOnChannel:(NSString*)channel message:(NSData*)message binaryReply:(FlutterBinaryReply)callback { NSAssert(channel, @"The channel must not be null"); - [_engine.get() sendOnChannel:channel message:message binaryReply:callback]; + [_engine.get().binaryMessenger sendOnChannel:channel message:message binaryReply:callback]; } - (void)setMessageHandlerOnChannel:(NSString*)channel binaryMessageHandler:(FlutterBinaryMessageHandler)handler { NSAssert(channel, @"The channel must not be null"); - [_engine.get() setMessageHandlerOnChannel:channel binaryMessageHandler:handler]; + [_engine.get().binaryMessenger setMessageHandlerOnChannel:channel binaryMessageHandler:handler]; } #pragma mark - FlutterTextureRegistry diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm index 25c53d2a9..cc1646d95 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm @@ -572,7 +572,7 @@ AccessibilityBridge::AccessibilityBridge(UIView* view, previous_routes_({}) { accessibility_channel_.reset([[FlutterBasicMessageChannel alloc] initWithName:@"flutter/accessibility" - binaryMessenger:platform_view->GetOwnerViewController().get() + binaryMessenger:platform_view->GetOwnerViewController().get().engine.binaryMessenger codec:[FlutterStandardMessageCodec sharedInstance]]); [accessibility_channel_.get() setMessageHandler:^(id message, FlutterReply reply) { HandleEvent((NSDictionary*)message); @@ -582,7 +582,6 @@ AccessibilityBridge::AccessibilityBridge(UIView* view, AccessibilityBridge::~AccessibilityBridge() { clearState(); view_.accessibilityElements = nil; - [accessibility_channel_.get() setMessageHandler:nil]; } UIView* AccessibilityBridge::textInputView() { diff --git a/shell/platform/darwin/macos/framework/Headers/FLEViewController.h b/shell/platform/darwin/macos/framework/Headers/FLEViewController.h index d6330bfc0..54d05dc3d 100644 --- a/shell/platform/darwin/macos/framework/Headers/FLEViewController.h +++ b/shell/platform/darwin/macos/framework/Headers/FLEViewController.h @@ -29,10 +29,8 @@ typedef NS_ENUM(NSInteger, FlutterMouseTrackingMode) { * Flutter engine in non-interactive mode, or with a drawable Flutter canvas. */ FLUTTER_EXPORT -@interface FLEViewController : NSViewController +@interface FLEViewController + : NSViewController /** * The view this controller manages when launched in interactive mode (headless set to false). Must @@ -69,4 +67,10 @@ FLUTTER_EXPORT - (BOOL)launchHeadlessEngineWithAssetsPath:(nonnull NSURL*)assets commandLineArguments:(nullable NSArray*)arguments; +/** + * The `FlutterBinaryMessenger` associated with this FLEViewController (used for communicating + * with channels). + */ +@property(nonatomic, readonly) NSObject* _Nonnull binaryMessenger; + @end diff --git a/shell/platform/darwin/macos/framework/Source/FLETextInputPlugin.mm b/shell/platform/darwin/macos/framework/Source/FLETextInputPlugin.mm index 0f9d587c2..eeb1ebd9d 100644 --- a/shell/platform/darwin/macos/framework/Source/FLETextInputPlugin.mm +++ b/shell/platform/darwin/macos/framework/Source/FLETextInputPlugin.mm @@ -72,7 +72,7 @@ static NSString* const kMultilineInputType = @"TextInputType.multiline"; if (self != nil) { _flutterViewController = viewController; _channel = [FlutterMethodChannel methodChannelWithName:kTextInputChannel - binaryMessenger:viewController + binaryMessenger:viewController.binaryMessenger codec:[FlutterJSONMethodCodec sharedInstance]]; __weak FLETextInputPlugin* weakSelf = self; [_channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { diff --git a/shell/platform/darwin/macos/framework/Source/FLEViewController.mm b/shell/platform/darwin/macos/framework/Source/FLEViewController.mm index 1bfb242e4..e0cdeaa4b 100644 --- a/shell/platform/darwin/macos/framework/Source/FLEViewController.mm +++ b/shell/platform/darwin/macos/framework/Source/FLEViewController.mm @@ -70,7 +70,7 @@ struct MouseState { /** * Private interface declaration for FLEViewController. */ -@interface FLEViewController () +@interface FLEViewController () /** * A list of additional responders to keyboard events. Keybord events are forwarded to all of them. @@ -671,6 +671,11 @@ static void CommonInit(FLEViewController* controller) { FlutterEngineSendWindowMetricsEvent(_engine, &event); } +#pragma mark - FlutterBinaryMessengerContainer +- (NSObject*)binaryMessenger { + return self; +} + #pragma mark - FlutterBinaryMessenger - (void)sendOnChannel:(nonnull NSString*)channel message:(nullable NSData*)message { diff --git a/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/project.pbxproj b/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/project.pbxproj index 213a48b39..189ce8549 100644 --- a/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/project.pbxproj +++ b/testing/ios/IosUnitTests/IosUnitTests.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 0D52D3BD22C566D50011DEBD /* FlutterBinaryMessengerRelayTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0D52D3B622C566D50011DEBD /* FlutterBinaryMessengerRelayTest.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 0D6AB6B622BB05E100EEE540 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D6AB6B522BB05E100EEE540 /* AppDelegate.m */; }; 0D6AB6B922BB05E100EEE540 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D6AB6B822BB05E100EEE540 /* ViewController.m */; }; 0D6AB6BC22BB05E100EEE540 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0D6AB6BA22BB05E100EEE540 /* Main.storyboard */; }; @@ -71,6 +72,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 0D52D3B622C566D50011DEBD /* FlutterBinaryMessengerRelayTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FlutterBinaryMessengerRelayTest.mm; sourceTree = ""; }; 0D6AB6B122BB05E100EEE540 /* IosUnitTests.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IosUnitTests.app; sourceTree = BUILT_PRODUCTS_DIR; }; 0D6AB6B422BB05E100EEE540 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 0D6AB6B522BB05E100EEE540 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -156,6 +158,7 @@ 0D6AB6E622BB409F00EEE540 /* Source */ = { isa = PBXGroup; children = ( + 0D52D3B622C566D50011DEBD /* FlutterBinaryMessengerRelayTest.mm */, 0D6AB6E722BB40CF00EEE540 /* FlutterEngineTest.mm */, ); name = Source; @@ -366,6 +369,7 @@ buildActionMask = 2147483647; files = ( 0D6AB6EB22BB40E700EEE540 /* FlutterEngineTest.mm in Sources */, + 0D52D3BD22C566D50011DEBD /* FlutterBinaryMessengerRelayTest.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; -- GitLab