Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 3.24.1

* Updates platform views on iOS to only have a weak reference to the native view. This is a
potential workaround to prevent a crash during the Flutter engine shutdown. See https://github.com/flutter/flutter/issues/168535

## 3.24.0

* Adds support for `WebKitWebViewControllerCreationParams.javaScriptCanOpenWindowsAutomatically` to allow JavaScript's
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2013 The Flutter Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import XCTest

@testable import webview_flutter_wkwebview

#if os(iOS)
import UIKit
#endif

class PlatformViewImplTests: XCTestCase {
#if os(iOS)
func testPlatformViewImplStoresViewWithAWeakReference() {
var view: UIView? = UIView()
let platformView = PlatformViewImpl(uiView: view!)

XCTAssertNotNil(platformView.uiView)

view = nil
XCTAssertNil(platformView.uiView)
}
#endif
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,36 @@ import Foundation
#error("Unsupported platform.")
#endif

/// Implementation of `FlutterPlatformViewFactory` that retrieves the view from the `WebKitLibraryPigeonInstanceManager`.
class FlutterViewFactory: NSObject, FlutterPlatformViewFactory {
unowned let instanceManager: WebKitLibraryPigeonInstanceManager

#if os(iOS)
class PlatformViewImpl: NSObject, FlutterPlatformView {
let uiView: UIView
#if os(iOS)
class PlatformViewImpl: NSObject, FlutterPlatformView {
// TODO(bparrishMines): Change to strong reference once this issue is fixed in the engine and
// makes it to stable. See https://github.com/flutter/flutter/issues/168535.
// The InstanceManager used by pigeon adds an associated object to added instances that makes a message call when
// they are deallocated. This sets a weak reference to the underlying UIView to prevent a crash where the UIView is
// no longer referenced by the plugin, but the FlutterViewController still maintains a transitive reference to it
// when the BinaryMessenger becomes invalid.
weak var uiView: UIView?

init(uiView: UIView) {
self.uiView = uiView
}
init(uiView: UIView) {
self.uiView = uiView
}

func view() -> UIView {
func view() -> UIView {
if let uiView = uiView {
return uiView
}

NSLog(
"WebViewFlutterPluginError: UIView has been deallocated, but is still being requested as a PlatformView."
)
return UIView()
}
Comment on lines +30 to 39
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Returning a new, empty UIView when uiView is nil could lead to subtle bugs and unexpected behavior. For instance, the Flutter engine might add this empty view to the view hierarchy, resulting in a blank space where the webview should be, without any clear error indicating what went wrong.

Given the assumption that view() should not be called after the underlying native view is deallocated, it would be more robust to enforce this with a fatalError. This will help catch incorrect usage during development and provide a clear error message.

    func view() -> UIView {
      guard let uiView = uiView else {
        fatalError("The platform view is being accessed after it has been released.")
      }
      return uiView
    }

#endif
}
#endif

/// Implementation of `FlutterPlatformViewFactory` that retrieves the view from the `WebKitLibraryPigeonInstanceManager`.
class FlutterViewFactory: NSObject, FlutterPlatformViewFactory {
unowned let instanceManager: WebKitLibraryPigeonInstanceManager

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

if let instance = instance as? FlutterPlatformView {
instance.view().frame = frame
return instance
} else {
let view = instance as! UIView
view.frame = frame
return PlatformViewImpl(uiView: view)
}
let view = instance as! UIView
view.frame = frame
return PlatformViewImpl(uiView: view)
}
#elseif os(macOS)
func create(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: webview_flutter_wkwebview
description: A Flutter plugin that provides a WebView widget based on Apple's WKWebView control.
repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_wkwebview
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
version: 3.24.0
version: 3.24.1

environment:
sdk: ^3.9.0
Expand Down
Loading