Skip to content

Commit ca60bd0

Browse files
[webview_flutter_wkwebview] Updates platform views on iOS to only have a weak reference to the native view (#11175)
Updates `PlatformViewImpl` to only store a weak reference to the native view. This [issue](flutter/flutter#168535) seems to indicate the `PlatformViewsController` is keeping a reference to the native view even after it is removed from the `InstanceManager` in `webview_flutter_wkwebview`. This change should allow the pigeon call to happen when the reference to the Dart instance is deallocated. This should be safe because if the Dart instance is deallocated, then the Widget tree should no longer contain the PlatformView. And therefore the native UIView should no longer need to be used. Nor any callbacks that need the `UIView` since it is not on screen. Potential fix for flutter/flutter#168535, but should still update engine to notify plugins that they are detached before setting `PlatformViewsController` to nil. ## Pre-Review Checklist **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent 09ddfca commit ca60bd0

4 files changed

Lines changed: 59 additions & 21 deletions

File tree

packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 3.24.1
2+
3+
* Updates platform views on iOS to only have a weak reference to the native view. This is a
4+
potential workaround to prevent a crash during the Flutter engine shutdown. See https://github.com/flutter/flutter/issues/168535
5+
16
## 3.24.0
27

38
* Adds support for `WebKitWebViewControllerCreationParams.javaScriptCanOpenWindowsAutomatically` to allow JavaScript's
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2013 The Flutter Authors
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import XCTest
6+
7+
@testable import webview_flutter_wkwebview
8+
9+
#if os(iOS)
10+
import UIKit
11+
#endif
12+
13+
class PlatformViewImplTests: XCTestCase {
14+
#if os(iOS)
15+
func testPlatformViewImplStoresViewWithAWeakReference() {
16+
var view: UIView? = UIView()
17+
let platformView = PlatformViewImpl(uiView: view!)
18+
19+
XCTAssertNotNil(platformView.uiView)
20+
21+
view = nil
22+
XCTAssertNil(platformView.uiView)
23+
}
24+
#endif
25+
}

packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FlutterViewFactory.swift

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,36 @@ import Foundation
1313
#error("Unsupported platform.")
1414
#endif
1515

16-
/// Implementation of `FlutterPlatformViewFactory` that retrieves the view from the `WebKitLibraryPigeonInstanceManager`.
17-
class FlutterViewFactory: NSObject, FlutterPlatformViewFactory {
18-
unowned let instanceManager: WebKitLibraryPigeonInstanceManager
19-
20-
#if os(iOS)
21-
class PlatformViewImpl: NSObject, FlutterPlatformView {
22-
let uiView: UIView
16+
#if os(iOS)
17+
class PlatformViewImpl: NSObject, FlutterPlatformView {
18+
// TODO(bparrishMines): Change to strong reference once this issue is fixed in the engine and
19+
// makes it to stable. See https://github.com/flutter/flutter/issues/168535.
20+
// The InstanceManager used by pigeon adds an associated object to added instances that makes a message call when
21+
// they are deallocated. This sets a weak reference to the underlying UIView to prevent a crash where the UIView is
22+
// no longer referenced by the plugin, but the FlutterViewController still maintains a transitive reference to it
23+
// when the BinaryMessenger becomes invalid.
24+
weak var uiView: UIView?
2325

24-
init(uiView: UIView) {
25-
self.uiView = uiView
26-
}
26+
init(uiView: UIView) {
27+
self.uiView = uiView
28+
}
2729

28-
func view() -> UIView {
30+
func view() -> UIView {
31+
if let uiView = uiView {
2932
return uiView
3033
}
34+
35+
NSLog(
36+
"WebViewFlutterPluginError: UIView has been deallocated, but is still being requested as a PlatformView."
37+
)
38+
return UIView()
3139
}
32-
#endif
40+
}
41+
#endif
42+
43+
/// Implementation of `FlutterPlatformViewFactory` that retrieves the view from the `WebKitLibraryPigeonInstanceManager`.
44+
class FlutterViewFactory: NSObject, FlutterPlatformViewFactory {
45+
unowned let instanceManager: WebKitLibraryPigeonInstanceManager
3346

3447
init(instanceManager: WebKitLibraryPigeonInstanceManager) {
3548
self.instanceManager = instanceManager
@@ -42,14 +55,9 @@ class FlutterViewFactory: NSObject, FlutterPlatformViewFactory {
4255
let identifier: Int64 = args is Int64 ? args as! Int64 : Int64(args as! Int32)
4356
let instance: AnyObject? = instanceManager.instance(forIdentifier: identifier)
4457

45-
if let instance = instance as? FlutterPlatformView {
46-
instance.view().frame = frame
47-
return instance
48-
} else {
49-
let view = instance as! UIView
50-
view.frame = frame
51-
return PlatformViewImpl(uiView: view)
52-
}
58+
let view = instance as! UIView
59+
view.frame = frame
60+
return PlatformViewImpl(uiView: view)
5361
}
5462
#elseif os(macOS)
5563
func create(

packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: webview_flutter_wkwebview
22
description: A Flutter plugin that provides a WebView widget based on Apple's WKWebView control.
33
repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_wkwebview
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
5-
version: 3.24.0
5+
version: 3.24.1
66

77
environment:
88
sdk: ^3.9.0

0 commit comments

Comments
 (0)