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.25.1

* Relands update to prevent message calls when application will terminate.
* Updates minimum supported SDK version to Flutter 3.38/Dart 3.10.

## 3.25.0

* Adds support for retrieving cookies with `PlatformWebViewCookieManager.getCookies`.
Expand Down
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I just noticed that this is being added to the iOS project but not the macOS project, even though it sounds generic. Someone will almost certainly add tests here in the future thinking they will run on macOS, so the file should be added to both.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I went ahead and added all the tests files not added on macOS.

Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// 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 Flutter
import UIKit
#endif

class WebViewFlutterPluginTests: XCTestCase {
#if os(iOS)
func testInstanceManagerIsDeallocatedInApplicationWillTerminate() {
let plugin = WebViewFlutterPlugin(binaryMessenger: TestBinaryMessenger())
plugin.proxyApiRegistrar!.setUp()
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The call to plugin.proxyApiRegistrar!.setUp() is redundant because the WebViewFlutterPlugin initializer already calls setUp() on the registrar. This can be removed to avoid unnecessary re-initialization of the ProxyAPI.


let view = UIView()
_ = plugin.proxyApiRegistrar!.instanceManager.addHostCreatedInstance(view)

// Attaches an associated object to the InstanceManager to listen for when it is deallocated.
var finalizer: TestFinalizer? = TestFinalizer()

let key = malloc(1)!
defer {
free(key)
}
objc_setAssociatedObject(
plugin.proxyApiRegistrar!.instanceManager, key, finalizer, .OBJC_ASSOCIATION_RETAIN)
let expectation = self.expectation(description: "Wait for InstanceManager to be deallocated.")
TestFinalizer.onDeinit = {
expectation.fulfill()
}

// Ensure method is from `FlutterApplicationLifeCycleDelegate`.
(plugin as FlutterApplicationLifeCycleDelegate).applicationWillTerminate!(
UIApplication.shared)
XCTAssertNil(plugin.proxyApiRegistrar)

finalizer = nil
waitForExpectations(timeout: 5.0)
}

func testInstanceManagerIsDeallocatedInSceneDidDisconnect() {
let plugin = WebViewFlutterPlugin(binaryMessenger: TestBinaryMessenger())
plugin.proxyApiRegistrar!.setUp()
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The call to plugin.proxyApiRegistrar!.setUp() is redundant here as well, as the plugin's initializer already handles the setup of the registrar.


let view = UIView()
_ = plugin.proxyApiRegistrar!.instanceManager.addHostCreatedInstance(view)

// Attaches an associated object to the InstanceManager to listen for when it is deallocated.
var finalizer: TestFinalizer? = TestFinalizer()

let key = malloc(1)!
defer {
free(key)
}
objc_setAssociatedObject(
plugin.proxyApiRegistrar!.instanceManager, key, finalizer, .OBJC_ASSOCIATION_RETAIN)
let expectation = self.expectation(description: "Wait for InstanceManager to be deallocated.")
TestFinalizer.onDeinit = {
expectation.fulfill()
}

let scene = UIApplication.shared.connectedScenes.first!
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Using a forced unwrap on UIApplication.shared.connectedScenes.first can lead to a crash during test execution if the test environment does not have any active scenes. It is safer to use a guard statement or an optional binding to handle cases where no scenes are connected.

Suggested change
let scene = UIApplication.shared.connectedScenes.first!
guard let scene = UIApplication.shared.connectedScenes.first else {
XCTFail("No connected scenes found.")
return
}


// Ensure method is from `FlutterSceneLifeCycleDelegate`.
(plugin as FlutterSceneLifeCycleDelegate).sceneDidDisconnect?(scene)
XCTAssertNil(plugin.proxyApiRegistrar)

finalizer = nil
waitForExpectations(timeout: 5.0)
}
#endif
}

class TestFinalizer {
static var onDeinit: (() -> Void)?

deinit {
Self.onDeinit?()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,37 @@ public class WebViewFlutterPlugin: NSObject, FlutterPlugin {
let plugin = WebViewFlutterPlugin(binaryMessenger: binaryMessenger)

let viewFactory = FlutterViewFactory(instanceManager: plugin.proxyApiRegistrar!.instanceManager)

#if os(iOS)
registrar.addApplicationDelegate(plugin)
registrar.addSceneDelegate(plugin)
#endif

registrar.register(viewFactory, withId: "plugins.flutter.io/webview")
registrar.publish(plugin)
}

public func detachFromEngine(for registrar: FlutterPluginRegistrar) {
proxyApiRegistrar!.ignoreCallsToDart = true
proxyApiRegistrar!.tearDown()
tearDownProxyAPIRegistrar()
}

private func tearDownProxyAPIRegistrar() {
proxyApiRegistrar?.ignoreCallsToDart = true
proxyApiRegistrar?.tearDown()
try? proxyApiRegistrar?.instanceManager.removeAllObjects()
proxyApiRegistrar = nil
}
}

#if os(iOS)
extension WebViewFlutterPlugin: FlutterApplicationLifeCycleDelegate, FlutterSceneLifeCycleDelegate
{
public func applicationWillTerminate(_ application: UIApplication) {
tearDownProxyAPIRegistrar()
}

public func sceneDidDisconnect(_ scene: UIScene) {
tearDownProxyAPIRegistrar()
}
Comment on lines +60 to +62
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Tearing down the ProxyAPIRegistrar in sceneDidDisconnect may be problematic for applications that support multiple scenes (e.g., on iPad). If one scene is disconnected while others remain active and share the same Flutter engine, the plugin's state will be destroyed for all scenes, potentially breaking the remaining webviews. Since applicationWillTerminate and detachFromEngine already handle cleanup for the app and engine respectively, consider if sceneDidDisconnect is necessary or if it should be removed to avoid side effects in multi-window scenarios.

}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
8F1488FE2D2DE27000191744 /* HTTPCookieProxyAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F1488C82D2DE27000191744 /* HTTPCookieProxyAPITests.swift */; };
8F1488FF2D2DE27000191744 /* NavigationActionProxyAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F1488CB2D2DE27000191744 /* NavigationActionProxyAPITests.swift */; };
8F1489012D2DE91C00191744 /* AuthenticationChallengeResponseProxyAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F1489002D2DE91C00191744 /* AuthenticationChallengeResponseProxyAPITests.swift */; };
8F63D06B2F8812E400EC5076 /* WebViewFlutterPluginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F63D06A2F8812E400EC5076 /* WebViewFlutterPluginTests.swift */; };
8F63D06C2F8812E400EC5076 /* PlatformViewImplTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F63D0692F8812E400EC5076 /* PlatformViewImplTests.swift */; };
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

The project file has been updated to include PlatformViewImplTests.swift, but this file is missing from the pull request patches. This will result in a build error in Xcode due to a missing file reference. Please ensure all new test files are included in the commit.

8FEC64852DA2C6DC00C48569 /* GetTrustResultResponseProxyAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FEC64812DA2C6DC00C48569 /* GetTrustResultResponseProxyAPITests.swift */; };
8FEC64862DA2C6DC00C48569 /* WebpagePreferencesProxyAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FEC64842DA2C6DC00C48569 /* WebpagePreferencesProxyAPITests.swift */; };
8FEC64872DA2C6DC00C48569 /* SecCertificateProxyAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FEC64822DA2C6DC00C48569 /* SecCertificateProxyAPITests.swift */; };
Expand Down Expand Up @@ -128,6 +130,8 @@
8F1488E02D2DE27000191744 /* WebViewConfigurationProxyAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WebViewConfigurationProxyAPITests.swift; path = ../../darwin/Tests/WebViewConfigurationProxyAPITests.swift; sourceTree = SOURCE_ROOT; };
8F1488E12D2DE27000191744 /* WebViewProxyAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WebViewProxyAPITests.swift; path = ../../darwin/Tests/WebViewProxyAPITests.swift; sourceTree = SOURCE_ROOT; };
8F1489002D2DE91C00191744 /* AuthenticationChallengeResponseProxyAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AuthenticationChallengeResponseProxyAPITests.swift; path = ../../darwin/Tests/AuthenticationChallengeResponseProxyAPITests.swift; sourceTree = SOURCE_ROOT; };
8F63D0692F8812E400EC5076 /* PlatformViewImplTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PlatformViewImplTests.swift; path = ../../darwin/Tests/PlatformViewImplTests.swift; sourceTree = SOURCE_ROOT; };
8F63D06A2F8812E400EC5076 /* WebViewFlutterPluginTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WebViewFlutterPluginTests.swift; path = ../../darwin/Tests/WebViewFlutterPluginTests.swift; sourceTree = SOURCE_ROOT; };
8FEC64812DA2C6DC00C48569 /* GetTrustResultResponseProxyAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = GetTrustResultResponseProxyAPITests.swift; path = ../../darwin/Tests/GetTrustResultResponseProxyAPITests.swift; sourceTree = SOURCE_ROOT; };
8FEC64822DA2C6DC00C48569 /* SecCertificateProxyAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SecCertificateProxyAPITests.swift; path = ../../darwin/Tests/SecCertificateProxyAPITests.swift; sourceTree = SOURCE_ROOT; };
8FEC64832DA2C6DC00C48569 /* SecTrustProxyAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SecTrustProxyAPITests.swift; path = ../../darwin/Tests/SecTrustProxyAPITests.swift; sourceTree = SOURCE_ROOT; };
Expand Down Expand Up @@ -174,6 +178,8 @@
68BDCAEA23C3F7CB00D9C032 /* RunnerTests */ = {
isa = PBXGroup;
children = (
8F63D0692F8812E400EC5076 /* PlatformViewImplTests.swift */,
8F63D06A2F8812E400EC5076 /* WebViewFlutterPluginTests.swift */,
8F0E23512EEB5D6B002AB342 /* ColorProxyAPITests.swift */,
8F0EDFD22E1F4967001938E6 /* ProxyAPIRegistrarTests.swift */,
8FEC64812DA2C6DC00C48569 /* GetTrustResultResponseProxyAPITests.swift */,
Expand Down Expand Up @@ -498,6 +504,8 @@
8F1488F42D2DE27000191744 /* URLCredentialProxyAPITests.swift in Sources */,
8F1488F52D2DE27000191744 /* URLAuthenticationChallengeProxyAPITests.swift in Sources */,
8F1488F62D2DE27000191744 /* NavigationDelegateProxyAPITests.swift in Sources */,
8F63D06B2F8812E400EC5076 /* WebViewFlutterPluginTests.swift in Sources */,
8F63D06C2F8812E400EC5076 /* PlatformViewImplTests.swift in Sources */,
8F1488F72D2DE27000191744 /* UIDelegateProxyAPITests.swift in Sources */,
8F1488F82D2DE27000191744 /* ScrollViewDelegateProxyAPITests.swift in Sources */,
8F1488FA2D2DE27000191744 /* FWFWebViewFlutterWKWebViewExternalAPITests.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
8FF1FEBD2D37201300A5E400 /* ScriptMessageProxyAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FF1FE912D37201300A5E400 /* ScriptMessageProxyAPITests.swift */; };
8FF1FEBE2D37201300A5E400 /* FrameInfoProxyAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FF1FE862D37201300A5E400 /* FrameInfoProxyAPITests.swift */; };
8FF1FEBF2D37201300A5E400 /* HTTPCookieProxyAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FF1FE882D37201300A5E400 /* HTTPCookieProxyAPITests.swift */; };
8FFBB0682FA1019E00F6659D /* PlatformViewImplTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FFBB0652FA1019E00F6659D /* PlatformViewImplTests.swift */; };
8FFBB0692FA1019E00F6659D /* ColorProxyAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FFBB0642FA1019E00F6659D /* ColorProxyAPITests.swift */; };
8FFBB06A2FA1019E00F6659D /* ProxyAPIRegistrarTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FFBB0662FA1019E00F6659D /* ProxyAPIRegistrarTests.swift */; };
8FFBB06B2FA1019E00F6659D /* WebViewFlutterPluginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FFBB0672FA1019E00F6659D /* WebViewFlutterPluginTests.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -148,6 +152,10 @@
8FF1FEA02D37201300A5E400 /* WebViewConfigurationProxyAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WebViewConfigurationProxyAPITests.swift; path = ../../darwin/Tests/WebViewConfigurationProxyAPITests.swift; sourceTree = SOURCE_ROOT; };
8FF1FEA12D37201300A5E400 /* WebViewProxyAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WebViewProxyAPITests.swift; path = ../../darwin/Tests/WebViewProxyAPITests.swift; sourceTree = SOURCE_ROOT; };
8FF1FEC02D37201500A5E400 /* RunnerTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RunnerTests-Bridging-Header.h"; sourceTree = "<group>"; };
8FFBB0642FA1019E00F6659D /* ColorProxyAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ColorProxyAPITests.swift; path = ../../darwin/Tests/ColorProxyAPITests.swift; sourceTree = SOURCE_ROOT; };
8FFBB0652FA1019E00F6659D /* PlatformViewImplTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PlatformViewImplTests.swift; path = ../../darwin/Tests/PlatformViewImplTests.swift; sourceTree = SOURCE_ROOT; };
8FFBB0662FA1019E00F6659D /* ProxyAPIRegistrarTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ProxyAPIRegistrarTests.swift; path = ../../darwin/Tests/ProxyAPIRegistrarTests.swift; sourceTree = SOURCE_ROOT; };
8FFBB0672FA1019E00F6659D /* WebViewFlutterPluginTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WebViewFlutterPluginTests.swift; path = ../../darwin/Tests/WebViewFlutterPluginTests.swift; sourceTree = SOURCE_ROOT; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand All @@ -173,6 +181,10 @@
331C80D6294CF71000263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
8FFBB0642FA1019E00F6659D /* ColorProxyAPITests.swift */,
8FFBB0652FA1019E00F6659D /* PlatformViewImplTests.swift */,
8FFBB0662FA1019E00F6659D /* ProxyAPIRegistrarTests.swift */,
8FFBB0672FA1019E00F6659D /* WebViewFlutterPluginTests.swift */,
8FEC64912DA303E200C48569 /* GetTrustResultResponseProxyAPITests.swift */,
8FEC64922DA303E200C48569 /* SecCertificateProxyAPITests.swift */,
8FEC64932DA303E200C48569 /* SecTrustProxyAPITests.swift */,
Expand Down Expand Up @@ -373,7 +385,7 @@
);
mainGroup = 33CC10E42044A3C60003C045;
packageReferences = (
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */,
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */,
);
productRefGroup = 33CC10EE2044A3C60003C045 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -477,6 +489,10 @@
8FF1FEB52D37201300A5E400 /* WebsiteDataStoreProxyAPITests.swift in Sources */,
8FF1FEB62D37201300A5E400 /* PreferencesProxyAPITests.swift in Sources */,
8FF1FEB72D37201300A5E400 /* URLCredentialProxyAPITests.swift in Sources */,
8FFBB0682FA1019E00F6659D /* PlatformViewImplTests.swift in Sources */,
8FFBB0692FA1019E00F6659D /* ColorProxyAPITests.swift in Sources */,
8FFBB06A2FA1019E00F6659D /* ProxyAPIRegistrarTests.swift in Sources */,
8FFBB06B2FA1019E00F6659D /* WebViewFlutterPluginTests.swift in Sources */,
8FF1FEB82D37201300A5E400 /* URLRequestProxyAPITests.swift in Sources */,
8FF1FEB92D37201300A5E400 /* UserScriptProxyAPITests.swift in Sources */,
8FF1FEBA2D37201300A5E400 /* ScriptMessageHandlerProxyAPITests.swift in Sources */,
Expand Down Expand Up @@ -848,7 +864,7 @@
/* End XCConfigurationList section */

/* Begin XCLocalSwiftPackageReference section */
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = {
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ description: Demonstrates how to use the webview_flutter_wkwebview plugin.
publish_to: none

environment:
sdk: ^3.9.0
flutter: ">=3.35.0"
sdk: ^3.10.0
flutter: ">=3.38.0"

dependencies:
flutter:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ 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.25.0
version: 3.25.1

environment:
sdk: ^3.9.0
flutter: ">=3.35.0"
sdk: ^3.10.0
flutter: ">=3.38.0"
Comment thread
stuartmorgan-g marked this conversation as resolved.

flutter:
plugin:
Expand Down
Loading