Flutter Engine
The Flutter Engine
Instance Methods | Class Methods | Properties | List of all members
FlutterPlatformPlugin Class Reference

#import <FlutterPlatformPlugin.h>

Inheritance diagram for FlutterPlatformPlugin:

Instance Methods

(instancetype) - NS_UNAVAILABLE
 
(instancetype) - initWithEngine:
 
(void) - handleMethodCall:result:
 
(instancetype) - initWithEngine: [implementation]
 
(void) - showSystemContextMenu: [implementation]
 
(void) - hideSystemContextMenu [implementation]
 
(void) - showShareViewController: [implementation]
 
(void) - searchWeb: [implementation]
 
(void) - playSystemSound: [implementation]
 
(void) - vibrateHapticFeedback: [implementation]
 
(void) - setSystemChromePreferredOrientations: [implementation]
 
(void) - setSystemChromeApplicationSwitcherDescription: [implementation]
 
(void) - setSystemChromeEnabledSystemUIOverlays: [implementation]
 
(void) - setSystemChromeEnabledSystemUIMode: [implementation]
 
(void) - restoreSystemChromeSystemUIOverlays [implementation]
 
(void) - setSystemChromeSystemUIOverlayStyle: [implementation]
 
(void) - popSystemNavigator: [implementation]
 
(NSDictionary *) - getClipboardData: [implementation]
 
(void) - setClipboardData: [implementation]
 
(NSDictionary *) - clipboardHasStrings [implementation]
 
(BOOL- isLiveTextInputAvailable [implementation]
 
(void) - showLookUpViewController: [implementation]
 
(UITextField *) - textField [implementation]
 
(void) - dealloc [implementation]
 

Class Methods

(instancetype) + NS_UNAVAILABLE
 

Properties

BOOL enableViewControllerBasedStatusBarAppearance [implementation]
 Whether the status bar appearance is based on the style preferred for this ViewController. More...
 

Detailed Description

Definition at line 12 of file FlutterPlatformPlugin.h.

Method Documentation

◆ clipboardHasStrings

- (NSDictionary *) clipboardHasStrings
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

421 {
422 return @{@"value" : @([UIPasteboard generalPasteboard].hasStrings)};
423}

◆ dealloc

- (void) dealloc
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

445 {
446 [_textField release];
447 [super dealloc];
448}

◆ getClipboardData:

- (NSDictionary *) getClipboardData: (NSString*)  format
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

401 :(NSString*)format {
402 UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
403 if (!format || [format isEqualToString:@(kTextPlainFormat)]) {
404 NSString* stringInPasteboard = pasteboard.string;
405 // The pasteboard may contain an item but it may not be a string (an image for instance).
406 return stringInPasteboard == nil ? nil : @{@"text" : stringInPasteboard};
407 }
408 return nil;
409}
uint32_t uint32_t * format
constexpr char kTextPlainFormat[]
Clipboard plain text format.

◆ handleMethodCall:result:

- (void) handleMethodCall: (FlutterMethodCall*)  call
result: (FlutterResult result 

Definition at line 79 of file FlutterPlatformPlugin.mm.

104 NSString* method = call.method;
105 id args = call.arguments;
106 if ([method isEqualToString:@"SystemSound.play"]) {
107 [self playSystemSound:args];
108 result(nil);
109 } else if ([method isEqualToString:@"HapticFeedback.vibrate"]) {
110 [self vibrateHapticFeedback:args];
111 result(nil);
112 } else if ([method isEqualToString:@"SystemChrome.setPreferredOrientations"]) {
113 [self setSystemChromePreferredOrientations:args];
114 result(nil);
115 } else if ([method isEqualToString:@"SystemChrome.setApplicationSwitcherDescription"]) {
116 [self setSystemChromeApplicationSwitcherDescription:args];
117 result(nil);
118 } else if ([method isEqualToString:@"SystemChrome.setEnabledSystemUIOverlays"]) {
119 [self setSystemChromeEnabledSystemUIOverlays:args];
120 result(nil);
121 } else if ([method isEqualToString:@"SystemChrome.setEnabledSystemUIMode"]) {
122 [self setSystemChromeEnabledSystemUIMode:args];
123 result(nil);
124 } else if ([method isEqualToString:@"SystemChrome.restoreSystemUIOverlays"]) {
125 [self restoreSystemChromeSystemUIOverlays];
126 result(nil);
127 } else if ([method isEqualToString:@"SystemChrome.setSystemUIOverlayStyle"]) {
128 [self setSystemChromeSystemUIOverlayStyle:args];
129 result(nil);
130 } else if ([method isEqualToString:@"SystemNavigator.pop"]) {
131 NSNumber* isAnimated = args;
132 [self popSystemNavigator:isAnimated.boolValue];
133 result(nil);
134 } else if ([method isEqualToString:@"Clipboard.getData"]) {
135 result([self getClipboardData:args]);
136 } else if ([method isEqualToString:@"Clipboard.setData"]) {
137 [self setClipboardData:args];
138 result(nil);
139 } else if ([method isEqualToString:@"Clipboard.hasStrings"]) {
141 } else if ([method isEqualToString:@"LiveText.isLiveTextInputAvailable"]) {
143 } else if ([method isEqualToString:@"SearchWeb.invoke"]) {
144 [self searchWeb:args];
145 result(nil);
146 } else if ([method isEqualToString:@"LookUp.invoke"]) {
147 [self showLookUpViewController:args];
148 result(nil);
149 } else if ([method isEqualToString:@"Share.invoke"]) {
150 [self showShareViewController:args];
151 result(nil);
152 } else if ([method isEqualToString:@"ContextMenu.showSystemContextMenu"]) {
153 [self showSystemContextMenu:args];
154 result(nil);
155 } else if ([method isEqualToString:@"ContextMenu.hideSystemContextMenu"]) {
156 [self hideSystemContextMenu];
157 result(nil);
158 } else {
160 }
161}
void(^ FlutterResult)(id _Nullable result)
FLUTTER_DARWIN_EXPORT NSObject const * FlutterMethodNotImplemented
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
GAsyncResult * result
NSDictionary * clipboardHasStrings()
def call(args)
Definition: dom.py:159

◆ hideSystemContextMenu

- (void) hideSystemContextMenu
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

175 {
176 if (@available(iOS 16.0, *)) {
177 FlutterTextInputPlugin* textInputPlugin = [_engine.get() textInputPlugin];
178 [textInputPlugin hideEditMenu];
179 }
180}
FlutterTextInputPlugin * textInputPlugin

◆ initWithEngine: [1/2]

- (instancetype) initWithEngine: (fml::WeakNSObject<FlutterEngine>)  engine
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

83 FML_DCHECK(engine) << "engine must be set";
84 self = [super init];
85
86 if (self) {
88 NSObject* infoValue = [[NSBundle mainBundle]
89 objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"];
90#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
91 if (infoValue != nil && ![infoValue isKindOfClass:[NSNumber class]]) {
92 FML_LOG(ERROR) << "The value of UIViewControllerBasedStatusBarAppearance in info.plist must "
93 "be a Boolean type.";
94 }
95#endif
96 _enableViewControllerBasedStatusBarAppearance =
97 (infoValue == nil || [(NSNumber*)infoValue boolValue]);
98 }
99
100 return self;
101}
FlutterEngine engine
Definition: main.cc:68
#define FML_LOG(severity)
Definition: logging.h:82
#define FML_DCHECK(condition)
Definition: logging.h:103
fml::scoped_nsobject< FlutterEngine > _engine
#define ERROR(message)
Definition: elf_loader.cc:260

◆ initWithEngine: [2/2]

- (instancetype) initWithEngine: (fml::WeakNSObject< FlutterEngine >)  NS_DESIGNATED_INITIALIZER

◆ isLiveTextInputAvailable

- (BOOL) isLiveTextInputAvailable
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

425 {
426 return [[self textField] canPerformAction:@selector(captureTextFromCamera:) withSender:nil];
427}

◆ NS_UNAVAILABLE [1/2]

+ (instancetype) NS_UNAVAILABLE

◆ NS_UNAVAILABLE [2/2]

- (instancetype) NS_UNAVAILABLE

◆ playSystemSound:

- (void) playSystemSound: (NSString*)  soundType
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

234 :(NSString*)soundType {
235 if ([soundType isEqualToString:@"SystemSoundType.click"]) {
236 // All feedback types are specific to Android and are treated as equal on
237 // iOS.
238 AudioServicesPlaySystemSound(kKeyPressClickSoundId);
239 }
240}

◆ popSystemNavigator:

- (void) popSystemNavigator: (BOOL isAnimated
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

371 :(BOOL)isAnimated {
372 // Apple's human user guidelines say not to terminate iOS applications. However, if the
373 // root view of the app is a navigation controller, it is instructed to back up a level
374 // in the navigation hierarchy.
375 // It's also possible in an Add2App scenario that the FlutterViewController was presented
376 // outside the context of a UINavigationController, and still wants to be popped.
377
378 FlutterViewController* engineViewController = [_engine.get() viewController];
379 UINavigationController* navigationController = [engineViewController navigationController];
380 if (navigationController) {
381 [navigationController popViewControllerAnimated:isAnimated];
382 } else {
383 UIViewController* rootViewController = nil;
384#if APPLICATION_EXTENSION_API_ONLY
385 if (@available(iOS 15.0, *)) {
386 rootViewController =
387 [engineViewController flutterWindowSceneIfViewLoaded].keyWindow.rootViewController;
388 } else {
389 FML_LOG(WARNING)
390 << "rootViewController is not available in application extension prior to iOS 15.0.";
391 }
392#else
393 rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
394#endif
395 if (engineViewController != rootViewController) {
396 [engineViewController dismissViewControllerAnimated:isAnimated completion:nil];
397 }
398 }
399}
int BOOL
Definition: windows_types.h:37

◆ restoreSystemChromeSystemUIOverlays

- (void) restoreSystemChromeSystemUIOverlays
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

337 {
338 // Nothing to do on iOS.
339}

◆ searchWeb:

- (void) searchWeb: (NSString*)  searchTerm
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

219 :(NSString*)searchTerm {
220#if APPLICATION_EXTENSION_API_ONLY
221 FML_LOG(WARNING) << "SearchWeb.invoke is not availabe in app extension.";
222#else
223 NSString* escapedText = [searchTerm
224 stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet
225 URLHostAllowedCharacterSet]];
226 NSString* searchURL = [NSString stringWithFormat:@"%@%@", searchURLPrefix, escapedText];
227
228 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:searchURL]
229 options:@{}
230 completionHandler:nil];
231#endif
232}

◆ setClipboardData:

- (void) setClipboardData: (NSDictionary*)  data
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

411 :(NSDictionary*)data {
412 UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
413 id copyText = data[@"text"];
414 if ([copyText isKindOfClass:[NSString class]]) {
415 pasteboard.string = copyText;
416 } else {
417 pasteboard.string = @"null";
418 }
419}
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63

◆ setSystemChromeApplicationSwitcherDescription:

- (void) setSystemChromeApplicationSwitcherDescription: (NSDictionary*)  object
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

290 :(NSDictionary*)object {
291 // No counterpart on iOS but is a benign operation. So no asserts.
292}

◆ setSystemChromeEnabledSystemUIMode:

- (void) setSystemChromeEnabledSystemUIMode: (NSString*)  mode
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

318 :(NSString*)mode {
319 BOOL edgeToEdge = [mode isEqualToString:@"SystemUiMode.edgeToEdge"];
321 [_engine.get() viewController].prefersStatusBarHidden = !edgeToEdge;
322 } else {
323 // Checks if the top status bar should be visible, reflected by edge to edge setting. This
324 // platform ignores all other system ui modes.
325
326 // We opt out of view controller based status bar visibility since we want
327 // to be able to modify this on the fly. The key used is
328 // UIViewControllerBasedStatusBarAppearance.
330 }
331 [[NSNotificationCenter defaultCenter]
332 postNotificationName:edgeToEdge ? FlutterViewControllerShowHomeIndicator
333 : FlutterViewControllerHideHomeIndicator
334 object:nil];
335}
static void SetStatusBarHiddenForSharedApplication(BOOL hidden)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228

◆ setSystemChromeEnabledSystemUIOverlays:

- (void) setSystemChromeEnabledSystemUIOverlays: (NSArray*)  overlays
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

294 :(NSArray*)overlays {
295 BOOL statusBarShouldBeHidden = ![overlays containsObject:@"SystemUiOverlay.top"];
296 if ([overlays containsObject:@"SystemUiOverlay.bottom"]) {
297 [[NSNotificationCenter defaultCenter]
298 postNotificationName:FlutterViewControllerShowHomeIndicator
299 object:nil];
300 } else {
301 [[NSNotificationCenter defaultCenter]
302 postNotificationName:FlutterViewControllerHideHomeIndicator
303 object:nil];
304 }
306 [_engine.get() viewController].prefersStatusBarHidden = statusBarShouldBeHidden;
307 } else {
308 // Checks if the top status bar should be visible. This platform ignores all
309 // other overlays
310
311 // We opt out of view controller based status bar visibility since we want
312 // to be able to modify this on the fly. The key used is
313 // UIViewControllerBasedStatusBarAppearance.
314 SetStatusBarHiddenForSharedApplication(statusBarShouldBeHidden);
315 }
316}

◆ setSystemChromePreferredOrientations:

- (void) setSystemChromePreferredOrientations: (NSArray*)  orientations
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

262 :(NSArray*)orientations {
263 UIInterfaceOrientationMask mask = 0;
264
265 if (orientations.count == 0) {
266 mask |= UIInterfaceOrientationMaskAll;
267 } else {
268 for (NSString* orientation in orientations) {
269 if ([orientation isEqualToString:@"DeviceOrientation.portraitUp"]) {
270 mask |= UIInterfaceOrientationMaskPortrait;
271 } else if ([orientation isEqualToString:@"DeviceOrientation.portraitDown"]) {
272 mask |= UIInterfaceOrientationMaskPortraitUpsideDown;
273 } else if ([orientation isEqualToString:@"DeviceOrientation.landscapeLeft"]) {
274 mask |= UIInterfaceOrientationMaskLandscapeLeft;
275 } else if ([orientation isEqualToString:@"DeviceOrientation.landscapeRight"]) {
276 mask |= UIInterfaceOrientationMaskLandscapeRight;
277 }
278 }
279 }
280
281 if (!mask) {
282 return;
283 }
284 [[NSNotificationCenter defaultCenter]
285 postNotificationName:@(kOrientationUpdateNotificationName)
286 object:nil
287 userInfo:@{@(kOrientationUpdateNotificationKey) : @(mask)}];
288}

◆ setSystemChromeSystemUIOverlayStyle:

- (void) setSystemChromeSystemUIOverlayStyle: (NSDictionary*)  message
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

341 :(NSDictionary*)message {
342 NSString* brightness = message[@"statusBarBrightness"];
343 if (brightness == (id)[NSNull null]) {
344 return;
345 }
346
347 UIStatusBarStyle statusBarStyle;
348 if ([brightness isEqualToString:@"Brightness.dark"]) {
349 statusBarStyle = UIStatusBarStyleLightContent;
350 } else if ([brightness isEqualToString:@"Brightness.light"]) {
351 if (@available(iOS 13, *)) {
352 statusBarStyle = UIStatusBarStyleDarkContent;
353 } else {
354 statusBarStyle = UIStatusBarStyleDefault;
355 }
356 } else {
357 return;
358 }
359
361 // This notification is respected by the iOS embedder.
362 [[NSNotificationCenter defaultCenter]
363 postNotificationName:@(kOverlayStyleUpdateNotificationName)
364 object:nil
365 userInfo:@{@(kOverlayStyleUpdateNotificationKey) : @(statusBarStyle)}];
366 } else {
368 }
369}
static void SetStatusBarStyleForSharedApplication(UIStatusBarStyle style)
Win32Message message

◆ showLookUpViewController:

- (void) showLookUpViewController: (NSString*)  term
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

429 :(NSString*)term {
430 UIViewController* engineViewController = [_engine.get() viewController];
431 UIReferenceLibraryViewController* referenceLibraryViewController =
432 [[[UIReferenceLibraryViewController alloc] initWithTerm:term] autorelease];
433 [engineViewController presentViewController:referenceLibraryViewController
434 animated:YES
435 completion:nil];
436}

◆ showShareViewController:

- (void) showShareViewController: (NSString*)  content
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

182 :(NSString*)content {
183 UIViewController* engineViewController = [_engine.get() viewController];
184
185 NSArray* itemsToShare = @[ content ?: [NSNull null] ];
186 UIActivityViewController* activityViewController =
187 [[[UIActivityViewController alloc] initWithActivityItems:itemsToShare
188 applicationActivities:nil] autorelease];
189
190 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
191 // On iPad, the share screen is presented in a popover view, and requires a
192 // sourceView and sourceRect
193 FlutterTextInputPlugin* _textInputPlugin = [_engine.get() textInputPlugin];
194 UITextRange* range = _textInputPlugin.textInputView.selectedTextRange;
195
196 // firstRectForRange cannot be used here as it's current implementation does
197 // not always return the full rect of the range.
198 CGRect firstRect = [(FlutterTextInputView*)_textInputPlugin.textInputView
199 caretRectForPosition:(FlutterTextPosition*)range.start];
200 CGRect transformedFirstRect = [(FlutterTextInputView*)_textInputPlugin.textInputView
201 localRectFromFrameworkTransform:firstRect];
202 CGRect lastRect = [(FlutterTextInputView*)_textInputPlugin.textInputView
203 caretRectForPosition:(FlutterTextPosition*)range.end];
204 CGRect transformedLastRect = [(FlutterTextInputView*)_textInputPlugin.textInputView
205 localRectFromFrameworkTransform:lastRect];
206
207 activityViewController.popoverPresentationController.sourceView = engineViewController.view;
208 // In case of RTL Language, get the minimum x coordinate
209 activityViewController.popoverPresentationController.sourceRect =
210 CGRectMake(fmin(transformedFirstRect.origin.x, transformedLastRect.origin.x),
211 transformedFirstRect.origin.y,
212 abs(transformedLastRect.origin.x - transformedFirstRect.origin.x),
213 transformedFirstRect.size.height);
214 }
215
216 [engineViewController presentViewController:activityViewController animated:YES completion:nil];
217}
fml::scoped_nsobject< FlutterTextInputPlugin > _textInputPlugin
union flutter::testing::@2836::KeyboardChange::@76 content
SIN Vec< N, float > abs(const Vec< N, float > &x)
Definition: SkVx.h:707

◆ showSystemContextMenu:

- (void) showSystemContextMenu: (NSDictionary*)  args
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

163 :(NSDictionary*)args {
164 if (@available(iOS 16.0, *)) {
165 FlutterTextInputPlugin* textInputPlugin = [_engine.get() textInputPlugin];
166 BOOL shownEditMenu = [textInputPlugin showEditMenu:args];
167 if (!shownEditMenu) {
168 FML_LOG(ERROR) << "Only text input supports system context menu for now. Ensure the system "
169 "context menu is shown with an active text input connection. See "
170 "https://github.com/flutter/flutter/issues/143033.";
171 }
172 }
173}
BOOL showEditMenu:(ios(16.0) API_AVAILABLE)

◆ textField

- (UITextField *) textField
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

438 {
439 if (_textField == nil) {
440 _textField = [[UITextField alloc] init];
441 }
442 return _textField;
443}
UITextField * _textField

◆ vibrateHapticFeedback:

- (void) vibrateHapticFeedback: (NSString*)  feedbackType
implementation

Definition at line 79 of file FlutterPlatformPlugin.mm.

242 :(NSString*)feedbackType {
243 if (!feedbackType) {
244 AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
245 return;
246 }
247
248 if ([@"HapticFeedbackType.lightImpact" isEqualToString:feedbackType]) {
249 [[[[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight] autorelease]
250 impactOccurred];
251 } else if ([@"HapticFeedbackType.mediumImpact" isEqualToString:feedbackType]) {
252 [[[[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium] autorelease]
253 impactOccurred];
254 } else if ([@"HapticFeedbackType.heavyImpact" isEqualToString:feedbackType]) {
255 [[[[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleHeavy] autorelease]
256 impactOccurred];
257 } else if ([@"HapticFeedbackType.selectionClick" isEqualToString:feedbackType]) {
258 [[[[UISelectionFeedbackGenerator alloc] init] autorelease] selectionChanged];
259 }
260}

Property Documentation

◆ enableViewControllerBasedStatusBarAppearance

- (BOOL) enableViewControllerBasedStatusBarAppearance
readwritenonatomicassignimplementation

Whether the status bar appearance is based on the style preferred for this ViewController.

   The default value is YES.
   Explicitly add `UIViewControllerBasedStatusBarAppearance` as `false` in
   info.plist makes this value to be false.

Definition at line 72 of file FlutterPlatformPlugin.mm.


The documentation for this class was generated from the following files: