Skip to content

Commit

Permalink
[webview_flutter] Endorse macOS (flutter#7457)
Browse files Browse the repository at this point in the history
Updates the app-facing package to require the version of `flutter_webview_wkwebview` with macOS support, and endorses it for macOS.

Fixes flutter/flutter#41725
  • Loading branch information
stuartmorgan authored Aug 21, 2024
1 parent 89154b3 commit 4e5d47e
Show file tree
Hide file tree
Showing 33 changed files with 1,396 additions and 26 deletions.
5 changes: 3 additions & 2 deletions packages/webview_flutter/webview_flutter/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## NEXT
## 4.9.0

* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3.
* Adds endorsed macOS support.
* Updates minimum supported SDK version to Flutter 3.24/Dart 3.5.

## 4.8.0

Expand Down
15 changes: 7 additions & 8 deletions packages/webview_flutter/webview_flutter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ A Flutter plugin that provides a WebView widget.
On iOS the WebView widget is backed by a [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview).
On Android the WebView widget is backed by a [WebView](https://developer.android.com/reference/android/webkit/WebView).

| | Android | iOS |
|-------------|----------------|-------|
| **Support** | SDK 19+ or 20+ | 12.0+ |
| | Android | iOS | macOS |
|-------------|----------------|-------|--------|
| **Support** | SDK 19+ or 20+ | 12.0+ | 10.14+ |

## Usage

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

* **Android**: [webview_flutter_android](https://pub.dev/packages/webview_flutter_android/install)
* **iOS**: [webview_flutter_wkwebview](https://pub.dev/packages/webview_flutter_wkwebview/install)
* **iOS/macOS**: [webview_flutter_wkwebview](https://pub.dev/packages/webview_flutter_wkwebview/install)

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

<?code-excerpt "main.dart (platform_imports)"?>
```dart
// Import for Android features.
import 'package:webview_flutter_android/webview_flutter_android.dart';
// Import for iOS features.
// Import for iOS/macOS features.
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
```

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

Below is an example of setting additional iOS and Android parameters on the `WebViewController`.
Below is an example of setting additional iOS/macOS and Android parameters on the `WebViewController`.

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

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

### Enable Material Components for Android

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,10 @@ Future<void> main() async {
await controller.runJavaScriptReturningResult('isPaused();') as bool;
expect(isPaused, true);
});
});
},
// OGG playback is not supported on macOS, so the test data would need
// to be changed to support macOS.
skip: Platform.isMacOS);

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

group('NavigationDelegate', () {
const String blankPage = '<!DOCTYPE html><head></head><body></body></html>';
Expand Down Expand Up @@ -943,7 +948,7 @@ Future<void> main() async {
'localStorage.getItem("myCat");',
) as String;
} catch (exception) {
if (defaultTargetPlatform == TargetPlatform.iOS &&
if (_isWKWebView() &&
exception is ArgumentError &&
(exception.message as String).contains(
'Result of JavaScript execution returned a `null` value.')) {
Expand All @@ -955,24 +960,29 @@ Future<void> main() async {
);
}

// JavaScript `null` evaluate to different string values on Android and iOS.
// JavaScript `null` evaluate to different string values per platform.
// This utility method returns the string boolean value of the current platform.
String _webViewNull() {
if (defaultTargetPlatform == TargetPlatform.iOS) {
if (_isWKWebView()) {
return '<null>';
}
return 'null';
}

// JavaScript String evaluate to different string values on Android and iOS.
// JavaScript String evaluates to different strings depending on the platform.
// This utility method returns the string boolean value of the current platform.
String _webViewString(String value) {
if (defaultTargetPlatform == TargetPlatform.iOS) {
if (_isWKWebView()) {
return value;
}
return '"$value"';
}

bool _isWKWebView() {
return defaultTargetPlatform == TargetPlatform.iOS ||
defaultTargetPlatform == TargetPlatform.macOS;
}

class ResizableWebView extends StatefulWidget {
const ResizableWebView({
super.key,
Expand Down
10 changes: 7 additions & 3 deletions packages/webview_flutter/webview_flutter/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:webview_flutter/webview_flutter.dart';
// #docregion platform_imports
// Import for Android features.
import 'package:webview_flutter_android/webview_flutter_android.dart';
// Import for iOS features.
// Import for iOS/macOS features.
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
// #enddocregion platform_imports

Expand Down Expand Up @@ -141,7 +141,6 @@ class _WebViewExampleState extends State<WebViewExample> {

controller
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0x00000000))
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
Expand Down Expand Up @@ -191,6 +190,11 @@ Page resource error:
)
..loadRequest(Uri.parse('https://flutter.dev'));

// setBackgroundColor is not currently supported on macOS.
if (kIsWeb || !Platform.isMacOS) {
controller.setBackgroundColor(const Color(0x80000000));
}

// #docregion platform_features
if (controller.platform is AndroidWebViewController) {
AndroidWebViewController.enableDebugging(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ class _WebViewExampleState extends State<WebViewExample> {
// #docregion webview_controller
controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0x00000000))
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Flutter-related
**/Flutter/ephemeral/
**/Pods/

# Xcode-related
**/dgph
**/xcuserdata/
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig"
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig"
40 changes: 40 additions & 0 deletions packages/webview_flutter/webview_flutter/example/macos/Podfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
platform :osx, '10.14'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}

def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
end

File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_macos_podfile_setup

target 'Runner' do
use_frameworks!
use_modular_headers!

flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
end

post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_macos_build_settings(target)
end
end
Loading

0 comments on commit 4e5d47e

Please sign in to comment.