[webview_flutter] Add setCookie to CookieManager and support initial cookies in creation params. (#4561)
This PR adds a function for setting cookies to the CookieManager, as well support for setting initial cookies through the `CreationParams` object.
Fixes flutter/flutter#27597
diff --git a/packages/webview_flutter/webview_flutter/CHANGELOG.md b/packages/webview_flutter/webview_flutter/CHANGELOG.md
index a9e133d..1df7e53 100644
--- a/packages/webview_flutter/webview_flutter/CHANGELOG.md
+++ b/packages/webview_flutter/webview_flutter/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 2.7.0
+
+* Adds `setCookie` to CookieManager.
+* CreationParams now supports setting `initialCookies`.
+
## 2.6.0
* Adds support for the `loadRequest` method.
diff --git a/packages/webview_flutter/webview_flutter/example/lib/main.dart b/packages/webview_flutter/webview_flutter/example/lib/main.dart
index 02e6ef8..65786de 100644
--- a/packages/webview_flutter/webview_flutter/example/lib/main.dart
+++ b/packages/webview_flutter/webview_flutter/example/lib/main.dart
@@ -181,6 +181,7 @@
loadLocalFile,
loadHtmlString,
transparentBackground,
+ setCookie,
}
class SampleMenu extends StatelessWidget {
@@ -232,6 +233,9 @@
case MenuOptions.transparentBackground:
_onTransparentBackground(controller.data!, context);
break;
+ case MenuOptions.setCookie:
+ _onSetCookie(controller.data!, context);
+ break;
}
},
itemBuilder: (BuildContext context) => <PopupMenuItem<MenuOptions>>[
@@ -281,6 +285,10 @@
value: MenuOptions.transparentBackground,
child: Text('Transparent background example'),
),
+ const PopupMenuItem<MenuOptions>(
+ value: MenuOptions.setCookie,
+ child: Text('Set cookie'),
+ ),
],
);
},
@@ -357,6 +365,15 @@
await controller.loadUrl('data:text/html;base64,$contentBase64');
}
+ Future<void> _onSetCookie(
+ WebViewController controller, BuildContext context) async {
+ await CookieManager().setCookie(
+ const WebViewCookie(
+ name: 'foo', value: 'bar', domain: 'httpbin.org', path: '/anything'),
+ );
+ await controller.loadUrl('https://httpbin.org/anything');
+ }
+
Future<void> _onDoPostRequest(
WebViewController controller, BuildContext context) async {
final WebViewRequest request = WebViewRequest(
diff --git a/packages/webview_flutter/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/webview_flutter/lib/platform_interface.dart
index ab1cbb1..48f7434 100644
--- a/packages/webview_flutter/webview_flutter/lib/platform_interface.dart
+++ b/packages/webview_flutter/webview_flutter/lib/platform_interface.dart
@@ -22,5 +22,6 @@
WebSettings,
WebResourceError,
WebResourceErrorType,
+ WebViewCookie,
WebViewRequest,
WebViewRequestMethod;
diff --git a/packages/webview_flutter/webview_flutter/lib/src/webview.dart b/packages/webview_flutter/webview_flutter/lib/src/webview.dart
index d76f7b3..8fe4f41 100644
--- a/packages/webview_flutter/webview_flutter/lib/src/webview.dart
+++ b/packages/webview_flutter/webview_flutter/lib/src/webview.dart
@@ -3,12 +3,15 @@
// found in the LICENSE file.
import 'dart:async';
+import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:webview_flutter_android/webview_android.dart';
+import 'package:webview_flutter_android/webview_android_cookie_manager.dart';
+import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
import '../platform_interface.dart';
@@ -79,6 +82,7 @@
Key? key,
this.onWebViewCreated,
this.initialUrl,
+ this.initialCookies = const <WebViewCookie>[],
this.javascriptMode = JavascriptMode.disabled,
this.javascriptChannels,
this.navigationDelegate,
@@ -150,6 +154,9 @@
/// The initial URL to load.
final String? initialUrl;
+ /// The initial cookies to set.
+ final List<WebViewCookie> initialCookies;
+
/// Whether JavaScript execution is enabled.
final JavascriptMode javascriptMode;
@@ -365,6 +372,7 @@
userAgent: widget.userAgent,
autoMediaPlaybackPolicy: widget.initialMediaPlaybackPolicy,
backgroundColor: widget.backgroundColor,
+ cookies: widget.initialCookies,
);
}
@@ -779,16 +787,32 @@
return _instance ??= CookieManager._();
}
- CookieManager._();
+ CookieManager._() {
+ if (WebViewCookieManagerPlatform.instance == null) {
+ if (Platform.isAndroid) {
+ WebViewCookieManagerPlatform.instance = WebViewAndroidCookieManager();
+ } else if (Platform.isIOS) {
+ WebViewCookieManagerPlatform.instance = WKWebViewCookieManager();
+ } else {
+ throw AssertionError(
+ 'This platform is currently unsupported by webview_flutter.');
+ }
+ }
+ }
static CookieManager? _instance;
/// Clears all cookies for all [WebView] instances.
///
- /// This is a no op on iOS version smaller than 9.
- ///
/// Returns true if cookies were present before clearing, else false.
- Future<bool> clearCookies() => WebView.platform.clearCookies();
+ Future<bool> clearCookies() =>
+ WebViewCookieManagerPlatform.instance!.clearCookies();
+
+ /// Sets a cookie for all [WebView] instances.
+ ///
+ /// This is a no op on iOS versions below 11.
+ Future<void> setCookie(WebViewCookie cookie) =>
+ WebViewCookieManagerPlatform.instance!.setCookie(cookie);
}
// Throws an ArgumentError if `url` is not a valid URL string.
diff --git a/packages/webview_flutter/webview_flutter/pubspec.yaml b/packages/webview_flutter/webview_flutter/pubspec.yaml
index 1bc6bab..cd6c618 100644
--- a/packages/webview_flutter/webview_flutter/pubspec.yaml
+++ b/packages/webview_flutter/webview_flutter/pubspec.yaml
@@ -2,7 +2,7 @@
description: A Flutter plugin that provides a WebView widget on Android and iOS.
repository: https://github.com/flutter/plugins/tree/master/packages/webview_flutter/webview_flutter
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
-version: 2.6.0
+version: 2.7.0
environment:
sdk: ">=2.14.0 <3.0.0"
@@ -19,9 +19,9 @@
dependencies:
flutter:
sdk: flutter
- webview_flutter_android: ^2.7.0
+ webview_flutter_android: ^2.8.0
webview_flutter_platform_interface: ^1.8.0
- webview_flutter_wkwebview: ^2.5.0
+ webview_flutter_wkwebview: ^2.6.0
dev_dependencies:
build_runner: ^2.1.5
diff --git a/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart
index d422402..40baef7 100644
--- a/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart
+++ b/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart
@@ -23,10 +23,12 @@
late MockWebViewPlatform mockWebViewPlatform;
late MockWebViewPlatformController mockWebViewPlatformController;
+ late MockWebViewCookieManagerPlatform mockWebViewCookieManagerPlatform;
setUp(() {
mockWebViewPlatformController = MockWebViewPlatformController();
mockWebViewPlatform = MockWebViewPlatform();
+ mockWebViewCookieManagerPlatform = MockWebViewCookieManagerPlatform();
when(mockWebViewPlatform.build(
context: anyNamed('context'),
creationParams: anyNamed('creationParams'),
@@ -46,6 +48,11 @@
});
WebView.platform = mockWebViewPlatform;
+ WebViewCookieManagerPlatform.instance = mockWebViewCookieManagerPlatform;
+ });
+
+ tearDown(() {
+ mockWebViewCookieManagerPlatform.reset();
});
testWidgets('Create WebView', (WidgetTester tester) async {
@@ -499,9 +506,6 @@
});
testWidgets('Cookies can be cleared once', (WidgetTester tester) async {
- when(mockWebViewPlatform.clearCookies())
- .thenAnswer((_) => Future<bool>.value(true));
-
await tester.pumpWidget(
const WebView(
initialUrl: 'https://flutter.io',
@@ -512,6 +516,21 @@
expect(hasCookies, true);
});
+ testWidgets('Cookies can be set', (WidgetTester tester) async {
+ const WebViewCookie cookie =
+ WebViewCookie(name: 'foo', value: 'bar', domain: 'flutter.dev');
+
+ await tester.pumpWidget(
+ const WebView(
+ initialUrl: 'https://flutter.io',
+ ),
+ );
+ final CookieManager cookieManager = CookieManager();
+ await cookieManager.setCookie(cookie);
+ expect(mockWebViewCookieManagerPlatform.setCookieCalls,
+ <WebViewCookie>[cookie]);
+ });
+
testWidgets('Initial JavaScript channels', (WidgetTester tester) async {
await tester.pumpWidget(
WebView(
@@ -1308,3 +1327,19 @@
.matches(creationParams.javascriptChannelNames, matchState);
}
}
+
+class MockWebViewCookieManagerPlatform extends WebViewCookieManagerPlatform {
+ List<WebViewCookie> setCookieCalls = <WebViewCookie>[];
+
+ @override
+ Future<bool> clearCookies() async => true;
+
+ @override
+ Future<void> setCookie(WebViewCookie cookie) async {
+ setCookieCalls.add(cookie);
+ }
+
+ void reset() {
+ setCookieCalls = <WebViewCookie>[];
+ }
+}