From ab0a04d3a7daede8e3ffac98a2b4482fedb56d46 Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Sun, 17 Nov 2024 16:29:24 -0800 Subject: [PATCH] iOS: Clean up @synthesize directives / ivars (flutter/engine#56665) In modern Objective-C, `@property` directives automatically generate a backing ivar (property name prefixed with an underscore), the getter, and (for readwrite properties) the setter. `@synthesize` directives are generally only required if the backing ivar has a different name from the property. Also updates the FlutterMetalLayer API to match CAMetalLayer: * Adds API_AVAILABLE declaration to match that on CAMetalLayer. * Eliminates wantsExtendedDynamicRangeContent property as it's also part of CALayer's interface and unused in our implementation. Also eliminates unnecessary ivars where they're being synthesized by `@property` declarations. Previously, we were overriding the behaviour of UIViewController.prefersStatusBarHidden by synthesizing _flutterPrefersStatusBarHidden as a backing ivar. Since we're explicitly overriding the behaviour of a superclass, it's more idiomatic to synthesize a private property or explicitly declare an ivar then explicitly override the getter instead. Further, this adds documentation to cases where `@synthesize` directives are required, such as: * Creating a backing ivar for a readonly property. * Creating a backing ivar for a property with a custom getter/setter. * Synthesising the ivar, getter, and setter for a property declared in a protocol being implemented. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style --- .../ios/framework/Source/FlutterMetalLayer.h | 8 ++++++-- .../ios/framework/Source/FlutterMetalLayer.mm | 18 +----------------- .../framework/Source/FlutterTextInputPlugin.mm | 1 + .../framework/Source/FlutterViewController.mm | 15 +++++++++++---- .../Source/FlutterViewControllerTest.mm | 7 ++++++- .../Source/TextInputSemanticsObject.mm | 1 + .../Source/FlutterChannelKeyResponder.mm | 1 + .../Source/FlutterEmbedderKeyResponder.mm | 1 + .../framework/Source/FlutterMenuPluginTest.mm | 2 ++ .../Source/FlutterThreadSynchronizerTest.mm | 2 -- .../framework/Source/FlutterVSyncWaiterTest.mm | 10 ++++------ .../framework/Source/FlutterViewController.mm | 2 ++ 12 files changed, 36 insertions(+), 32 deletions(-) diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterMetalLayer.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterMetalLayer.h index 21b63b4a04..7aab78db94 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterMetalLayer.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterMetalLayer.h @@ -9,16 +9,20 @@ /// Drop-in replacement (as far as Flutter is concerned) for CAMetalLayer /// that can present with transaction from a background thread. +/// +/// Properties and method declarations must exactly match those in the +/// CAMetalLayer interface declaration. @interface FlutterMetalLayer : CALayer @property(nullable, retain) id device; -@property(nullable, readonly) id preferredDevice; +@property(nullable, readonly) + id preferredDevice API_AVAILABLE(macos(10.15), ios(13.0), tvos(13.0)) + API_UNAVAILABLE(watchos); @property MTLPixelFormat pixelFormat; @property BOOL framebufferOnly; @property CGSize drawableSize; @property BOOL presentsWithTransaction; @property(nullable) CGColorSpaceRef colorspace; -@property BOOL wantsExtendedDynamicRangeContent; - (nullable id)nextDrawable; diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterMetalLayer.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterMetalLayer.mm index a4abff98d5..f31eda904b 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterMetalLayer.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterMetalLayer.mm @@ -57,11 +57,7 @@ extern CFTimeInterval display_link_target; @end -@interface FlutterTexture : NSObject { - id _texture; - IOSurface* _surface; - CFTimeInterval _presentedTime; -} +@interface FlutterTexture : NSObject @property(readonly, nonatomic) id texture; @property(readonly, nonatomic) IOSurface* surface; @@ -72,11 +68,6 @@ extern CFTimeInterval display_link_target; @implementation FlutterTexture -@synthesize texture = _texture; -@synthesize surface = _surface; -@synthesize presentedTime = _presentedTime; -@synthesize waitingForCompletion; - - (instancetype)initWithTexture:(id)texture surface:(IOSurface*)surface { if (self = [super init]) { _texture = texture; @@ -187,13 +178,6 @@ extern CFTimeInterval display_link_target; @implementation FlutterMetalLayer -@synthesize preferredDevice = _preferredDevice; -@synthesize device = _device; -@synthesize pixelFormat = _pixelFormat; -@synthesize framebufferOnly = _framebufferOnly; -@synthesize colorspace = _colorspace; -@synthesize wantsExtendedDynamicRangeContent = _wantsExtendedDynamicRangeContent; - - (instancetype)init { if (self = [super init]) { _preferredDevice = MTLCreateSystemDefaultDevice(); diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm index b8a3f64de0..9358431cf5 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm @@ -662,6 +662,7 @@ static BOOL IsSelectionRectBoundaryCloserToPoint(CGPoint point, @implementation FlutterTextSelectionRect +// Synthesize properties declared readonly in UITextSelectionRect. @synthesize rect = _rect; @synthesize writingDirection = _writingDirection; @synthesize containsStart = _containsStart; diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index d6e4c59f3c..319f423d84 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -79,6 +79,9 @@ typedef struct MouseState { @property(nonatomic, assign) BOOL isHomeIndicatorHidden; @property(nonatomic, assign) BOOL isPresentingViewControllerAnimating; +// Internal state backing override of UIView.prefersStatusBarHidden. +@property(nonatomic, assign) BOOL flutterPrefersStatusBarHidden; + @property(nonatomic, strong) NSMutableSet* ongoingTouches; // This scroll view is a workaround to accommodate iOS 13 and higher. There isn't a way to get // touches on the status bar to trigger scrolling to the top of a scroll view. We place a @@ -157,9 +160,13 @@ typedef struct MouseState { MouseState _mouseState; } +// Synthesize properties with an overridden getter/setter. @synthesize viewOpaque = _viewOpaque; @synthesize displayingFlutterUI = _displayingFlutterUI; -@synthesize prefersStatusBarHidden = _flutterPrefersStatusBarHidden; + +// TODO(dkwingsmt): https://github.com/flutter/flutter/issues/138168 +// No backing ivar is currently required; when multiple views are supported, we'll need to +// synthesize the ivar and store the view identifier. @dynamic viewIdentifier; #pragma mark - Manage and override all designated initializers @@ -2302,14 +2309,14 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch) } - (void)setPrefersStatusBarHidden:(BOOL)hidden { - if (hidden != _flutterPrefersStatusBarHidden) { - _flutterPrefersStatusBarHidden = hidden; + if (hidden != self.flutterPrefersStatusBarHidden) { + self.flutterPrefersStatusBarHidden = hidden; [self setNeedsStatusBarAppearanceUpdate]; } } - (BOOL)prefersStatusBarHidden { - return _flutterPrefersStatusBarHidden; + return self.flutterPrefersStatusBarHidden; } #pragma mark - Platform views diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm index 3bfaca823e..97d6a55548 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm @@ -38,21 +38,26 @@ using namespace flutter::testing; /// Sometimes we have to use a custom mock to avoid retain cycles in OCMock. /// Used for testing low memory notification. @interface FlutterEnginePartialMock : FlutterEngine + @property(nonatomic, strong) FlutterBasicMessageChannel* lifecycleChannel; @property(nonatomic, strong) FlutterBasicMessageChannel* keyEventChannel; @property(nonatomic, weak) FlutterViewController* viewController; @property(nonatomic, strong) FlutterTextInputPlugin* textInputPlugin; @property(nonatomic, assign) BOOL didCallNotifyLowMemory; + - (FlutterTextInputPlugin*)textInputPlugin; + - (void)sendKeyEvent:(const FlutterKeyEvent&)event callback:(nullable FlutterKeyEventCallback)callback userData:(nullable void*)userData; @end @implementation FlutterEnginePartialMock -@synthesize viewController; + +// Synthesize properties declared readonly in FlutterEngine. @synthesize lifecycleChannel; @synthesize keyEventChannel; +@synthesize viewController; @synthesize textInputPlugin; - (void)notifyLowMemory { diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/TextInputSemanticsObject.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/TextInputSemanticsObject.mm index 3695947b3c..f258367ae7 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/TextInputSemanticsObject.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/TextInputSemanticsObject.mm @@ -22,6 +22,7 @@ static const UIAccessibilityTraits kUIAccessibilityTraitUndocumentedEmptyLine = @implementation FlutterInactiveTextInput +// Synthesize properties declared in UITextInput protocol. @synthesize beginningOfDocument = _beginningOfDocument; @synthesize endOfDocument = _endOfDocument; @synthesize inputDelegate = _inputDelegate; diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponder.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponder.mm index d3f1551533..5505b460d4 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponder.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterChannelKeyResponder.mm @@ -29,6 +29,7 @@ @implementation FlutterChannelKeyResponder +// Synthesize properties declared in FlutterKeyPrimaryResponder protocol. @synthesize layoutMap; - (nonnull instancetype)initWithChannel:(nonnull FlutterBasicMessageChannel*)channel { diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterEmbedderKeyResponder.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterEmbedderKeyResponder.mm index 5feacb1d65..f3c0106e24 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterEmbedderKeyResponder.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterEmbedderKeyResponder.mm @@ -473,6 +473,7 @@ struct FlutterKeyPendingResponse { @implementation FlutterEmbedderKeyResponder +// Synthesize properties declared in FlutterKeyPrimaryResponder protocol. @synthesize layoutMap; - (nonnull instancetype)initWithSendEvent:(FlutterSendEmbedderKeyEvent)sendEvent { diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuPluginTest.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuPluginTest.mm index 7d32208d93..127bc5d5f2 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuPluginTest.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuPluginTest.mm @@ -25,6 +25,8 @@ @end @implementation FakePluginRegistrar + +// Synthesize properties declared in FlutterPluginRegistrar protocol. @synthesize messenger; @synthesize textures; @synthesize view; diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm index a9fafe947f..efa5fce563 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm @@ -28,8 +28,6 @@ FlutterThreadSynchronizer* _synchronizer; } -@synthesize synchronizer = _synchronizer; - - (nullable instancetype)init { self = [super init]; if (self != nil) { diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterVSyncWaiterTest.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterVSyncWaiterTest.mm index 0244854962..b7637104aa 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterVSyncWaiterTest.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterVSyncWaiterTest.mm @@ -7,8 +7,7 @@ #import "flutter/testing/testing.h" -@interface TestDisplayLink : FlutterDisplayLink { -} +@interface TestDisplayLink : FlutterDisplayLink @property(nonatomic) CFTimeInterval nominalOutputRefreshPeriod; @@ -16,20 +15,19 @@ @implementation TestDisplayLink +// Synthesize properties declared readonly in FlutterDisplayLink. @synthesize nominalOutputRefreshPeriod = _nominalOutputRefreshPeriod; -@synthesize delegate = _delegate; -@synthesize paused = _paused; - (instancetype)init { if (self = [super init]) { - _paused = YES; + self.paused = YES; } return self; } - (void)tickWithTimestamp:(CFTimeInterval)timestamp targetTimestamp:(CFTimeInterval)targetTimestamp { - [_delegate onDisplayLink:timestamp targetTimestamp:targetTimestamp]; + [self.delegate onDisplayLink:timestamp targetTimestamp:targetTimestamp]; } - (void)invalidate { diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm index 9f16f26d31..305b64fd39 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm @@ -341,7 +341,9 @@ static void OnKeyboardLayoutChanged(CFNotificationCenterRef center, FlutterThreadSynchronizer* _threadSynchronizer; } +// Synthesize properties declared readonly. @synthesize viewIdentifier = _viewIdentifier; + @dynamic accessibilityBridge; /**