Skip to content

Commit 4e5d47e

Browse files
[webview_flutter] Endorse macOS (flutter#7457)
Updates the app-facing package to require the version of `flutter_webview_wkwebview` with macOS support, and endorses it for macOS. Fixes flutter#41725
1 parent 89154b3 commit 4e5d47e

33 files changed

+1396
-26
lines changed

packages/webview_flutter/webview_flutter/CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
## NEXT
1+
## 4.9.0
22

3-
* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3.
3+
* Adds endorsed macOS support.
4+
* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5.
45

56
## 4.8.0
67

packages/webview_flutter/webview_flutter/README.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ A Flutter plugin that provides a WebView widget.
99
On iOS the WebView widget is backed by a [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview).
1010
On Android the WebView widget is backed by a [WebView](https://developer.android.com/reference/android/webkit/WebView).
1111

12-
| | Android | iOS |
13-
|-------------|----------------|-------|
14-
| **Support** | SDK 19+ or 20+ | 12.0+ |
12+
| | Android | iOS | macOS |
13+
|-------------|----------------|-------|--------|
14+
| **Support** | SDK 19+ or 20+ | 12.0+ | 10.14+ |
1515

1616
## Usage
1717

@@ -23,7 +23,6 @@ You can now display a WebView by:
2323
```dart
2424
controller = WebViewController()
2525
..setJavaScriptMode(JavaScriptMode.unrestricted)
26-
..setBackgroundColor(const Color(0x00000000))
2726
..setNavigationDelegate(
2827
NavigationDelegate(
2928
onProgress: (int progress) {
@@ -86,15 +85,15 @@ To access platform-specific features, start by adding the platform implementatio
8685
app or package:
8786

8887
* **Android**: [webview_flutter_android](https://pub.dev/packages/webview_flutter_android/install)
89-
* **iOS**: [webview_flutter_wkwebview](https://pub.dev/packages/webview_flutter_wkwebview/install)
88+
* **iOS/macOS**: [webview_flutter_wkwebview](https://pub.dev/packages/webview_flutter_wkwebview/install)
9089

9190
Next, add the imports of the implementation packages to your app or package:
9291

9392
<?code-excerpt "main.dart (platform_imports)"?>
9493
```dart
9594
// Import for Android features.
9695
import 'package:webview_flutter_android/webview_flutter_android.dart';
97-
// Import for iOS features.
96+
// Import for iOS/macOS features.
9897
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
9998
```
10099

@@ -109,7 +108,7 @@ additional functionality provided by the platform and is followed by an example.
109108
2. Call methods on a platform implementation of a class by using the `platform` field (e.g.
110109
`WebViewController.platform`, `WebViewWidget.platform`, etc.).
111110

112-
Below is an example of setting additional iOS and Android parameters on the `WebViewController`.
111+
Below is an example of setting additional iOS/macOS and Android parameters on the `WebViewController`.
113112

114113
<?code-excerpt "main.dart (platform_features)"?>
115114
```dart
@@ -137,7 +136,7 @@ See https://pub.dev/documentation/webview_flutter_android/latest/webview_flutter
137136
for more details on Android features.
138137

139138
See https://pub.dev/documentation/webview_flutter_wkwebview/latest/webview_flutter_wkwebview/webview_flutter_wkwebview-library.html
140-
for more details on iOS features.
139+
for more details on iOS/macOS features.
141140

142141
### Enable Material Components for Android
143142

packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,10 @@ Future<void> main() async {
449449
await controller.runJavaScriptReturningResult('isPaused();') as bool;
450450
expect(isPaused, true);
451451
});
452-
});
452+
},
453+
// OGG playback is not supported on macOS, so the test data would need
454+
// to be changed to support macOS.
455+
skip: Platform.isMacOS);
453456

454457
testWidgets('getTitle', (WidgetTester tester) async {
455458
const String getTitleTest = '''
@@ -563,7 +566,9 @@ Future<void> main() async {
563566
expect(recordedPosition?.x, X_SCROLL * 2);
564567
expect(recordedPosition?.y, Y_SCROLL * 2);
565568
});
566-
});
569+
},
570+
// Scroll position is currently not implemented for macOS.
571+
skip: Platform.isMacOS);
567572

568573
group('NavigationDelegate', () {
569574
const String blankPage = '<!DOCTYPE html><head></head><body></body></html>';
@@ -943,7 +948,7 @@ Future<void> main() async {
943948
'localStorage.getItem("myCat");',
944949
) as String;
945950
} catch (exception) {
946-
if (defaultTargetPlatform == TargetPlatform.iOS &&
951+
if (_isWKWebView() &&
947952
exception is ArgumentError &&
948953
(exception.message as String).contains(
949954
'Result of JavaScript execution returned a `null` value.')) {
@@ -955,24 +960,29 @@ Future<void> main() async {
955960
);
956961
}
957962

958-
// JavaScript `null` evaluate to different string values on Android and iOS.
963+
// JavaScript `null` evaluate to different string values per platform.
959964
// This utility method returns the string boolean value of the current platform.
960965
String _webViewNull() {
961-
if (defaultTargetPlatform == TargetPlatform.iOS) {
966+
if (_isWKWebView()) {
962967
return '<null>';
963968
}
964969
return 'null';
965970
}
966971

967-
// JavaScript String evaluate to different string values on Android and iOS.
972+
// JavaScript String evaluates to different strings depending on the platform.
968973
// This utility method returns the string boolean value of the current platform.
969974
String _webViewString(String value) {
970-
if (defaultTargetPlatform == TargetPlatform.iOS) {
975+
if (_isWKWebView()) {
971976
return value;
972977
}
973978
return '"$value"';
974979
}
975980

981+
bool _isWKWebView() {
982+
return defaultTargetPlatform == TargetPlatform.iOS ||
983+
defaultTargetPlatform == TargetPlatform.macOS;
984+
}
985+
976986
class ResizableWebView extends StatefulWidget {
977987
const ResizableWebView({
978988
super.key,

packages/webview_flutter/webview_flutter/example/lib/main.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
import 'dart:async';
88
import 'dart:convert';
99
import 'dart:io';
10-
import 'dart:typed_data';
1110

11+
import 'package:flutter/foundation.dart';
1212
import 'package:flutter/material.dart';
1313
import 'package:path_provider/path_provider.dart';
1414
import 'package:webview_flutter/webview_flutter.dart';
1515
// #docregion platform_imports
1616
// Import for Android features.
1717
import 'package:webview_flutter_android/webview_flutter_android.dart';
18-
// Import for iOS features.
18+
// Import for iOS/macOS features.
1919
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
2020
// #enddocregion platform_imports
2121

@@ -141,7 +141,6 @@ class _WebViewExampleState extends State<WebViewExample> {
141141

142142
controller
143143
..setJavaScriptMode(JavaScriptMode.unrestricted)
144-
..setBackgroundColor(const Color(0x00000000))
145144
..setNavigationDelegate(
146145
NavigationDelegate(
147146
onProgress: (int progress) {
@@ -191,6 +190,11 @@ Page resource error:
191190
)
192191
..loadRequest(Uri.parse('https://flutter.dev'));
193192

193+
// setBackgroundColor is not currently supported on macOS.
194+
if (kIsWeb || !Platform.isMacOS) {
195+
controller.setBackgroundColor(const Color(0x80000000));
196+
}
197+
194198
// #docregion platform_features
195199
if (controller.platform is AndroidWebViewController) {
196200
AndroidWebViewController.enableDebugging(true);

packages/webview_flutter/webview_flutter/example/lib/simple_example.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ class _WebViewExampleState extends State<WebViewExample> {
2626
// #docregion webview_controller
2727
controller = WebViewController()
2828
..setJavaScriptMode(JavaScriptMode.unrestricted)
29-
..setBackgroundColor(const Color(0x00000000))
3029
..setNavigationDelegate(
3130
NavigationDelegate(
3231
onProgress: (int progress) {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Flutter-related
2+
**/Flutter/ephemeral/
3+
**/Pods/
4+
5+
# Xcode-related
6+
**/dgph
7+
**/xcuserdata/
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2+
#include "ephemeral/Flutter-Generated.xcconfig"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2+
#include "ephemeral/Flutter-Generated.xcconfig"
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
platform :osx, '10.14'
2+
3+
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
4+
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
5+
6+
project 'Runner', {
7+
'Debug' => :debug,
8+
'Profile' => :release,
9+
'Release' => :release,
10+
}
11+
12+
def flutter_root
13+
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
14+
unless File.exist?(generated_xcode_build_settings_path)
15+
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
16+
end
17+
18+
File.foreach(generated_xcode_build_settings_path) do |line|
19+
matches = line.match(/FLUTTER_ROOT\=(.*)/)
20+
return matches[1].strip if matches
21+
end
22+
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
23+
end
24+
25+
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
26+
27+
flutter_macos_podfile_setup
28+
29+
target 'Runner' do
30+
use_frameworks!
31+
use_modular_headers!
32+
33+
flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
34+
end
35+
36+
post_install do |installer|
37+
installer.pods_project.targets.each do |target|
38+
flutter_additional_macos_build_settings(target)
39+
end
40+
end

0 commit comments

Comments
 (0)