diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index 262a97a1dc2d3..c7a4836a9f50c 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -133,6 +133,26 @@ FLUTTER_EXPORT */ - (void)destroyContext; +/** + * Ensures that Flutter will generate a semantics tree. + * + * This is enabled by default if certain accessibility services are turned on by + * the user, or when using a Simulator. This method allows a user to turn + * semantics on when they would not ordinarily be generated and the performance + * overhead is not a concern, e.g. for UI testing. Note that semantics should + * never be programatically turned off, as it would potentially disable + * accessibility services an end user has requested. + * + * This method must only be called after launching the engine via + * `-runWithEntrypoint:` or `-runWithEntryPoint:libraryURI`. + * + * You can subscribe to semantics updates via `NSNotificationCenter` by adding + * an observer for the name `FlutterSemanticsUpdateNotification`. The `object` + * parameter will be the `FlutterViewController` associated with the semantics + * update. + */ +- (void)ensureSemanticsEnabled; + /** * Sets the `FlutterViewController` for this instance. The FlutterEngine must be * running (e.g. a successful call to `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI`) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h index 371a888c88394..1ac7d61c5e614 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h @@ -17,6 +17,14 @@ @class FlutterEngine; +/** + * The name used for semantic update nofications via `NSNotificationCenter`. + * + * The object passed as the sender is the `FlutterViewController` associated + * with the update. + */ +const NSNotificationName FlutterSemanticsUpdateNotification = @"FlutterSemanticsUpdate"; + /** * A `UIViewController` implementation for Flutter views. * diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 8b8bd33fdba2a..a90e49c7085fa 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -146,6 +146,10 @@ - (void)dispatchPointerDataPacket:(std::unique_ptr)pac return _shell->GetTaskRunners().GetPlatformTaskRunner(); } +- (void)ensureSemanticsEnabled { + self.iosPlatformView->SetSemanticsEnabled(true); +} + - (void)setViewController:(FlutterViewController*)viewController { FML_DCHECK(self.iosPlatformView); _viewController = [viewController getWeakPtr]; diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index a0d85a7ffd0f9..b7495b90fec51 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -40,6 +40,9 @@ class PlatformViewIOS final : public PlatformView { void SetTextInputPlugin(fml::scoped_nsprotocol plugin); + // |shell::PlatformView| + void SetSemanticsEnabled(bool enabled) override; + private: fml::WeakPtr owner_controller_; std::unique_ptr ios_surface_; @@ -57,9 +60,6 @@ class PlatformViewIOS final : public PlatformView { // |shell::PlatformView| sk_sp CreateResourceContext() const override; - // |shell::PlatformView| - void SetSemanticsEnabled(bool enabled) override; - // |shell::PlatformView| void SetAccessibilityFeatures(int32_t flags) override; diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 4bcb08d21afe6..6f138edcfdd11 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -90,8 +90,8 @@ // |shell::PlatformView| void PlatformViewIOS::SetSemanticsEnabled(bool enabled) { if (!owner_controller_) { - FML_DLOG(WARNING) << "Could not set semantics to enabled, this " - "PlatformViewIOS has no ViewController."; + FML_LOG(WARNING) << "Could not set semantics to enabled, this " + "PlatformViewIOS has no ViewController."; return; } if (enabled && !accessibility_bridge_) { @@ -111,8 +111,11 @@ // |shell::PlatformView| void PlatformViewIOS::UpdateSemantics(blink::SemanticsNodeUpdates update, blink::CustomAccessibilityActionUpdates actions) { + FML_DCHECK(owner_controller_); if (accessibility_bridge_) { accessibility_bridge_->UpdateSemantics(std::move(update), std::move(actions)); + [[NSNotificationCenter defaultCenter] postNotificationName:FlutterSemanticsUpdateNotification + object:owner_controller_.get()]; } }