mirror of
https://github.com/flutter/packages.git
synced 2025-07-01 23:51:55 +08:00
[webview_flutter] Adds support for receiving a url with WebResourceError (#3884)
Fixes https://github.com/flutter/flutter/issues/125682
This commit is contained in:
@ -1,3 +1,7 @@
|
|||||||
|
## 3.9.0
|
||||||
|
|
||||||
|
* Adds support for `WebResouceError.url`.
|
||||||
|
|
||||||
## 3.8.2
|
## 3.8.2
|
||||||
|
|
||||||
* Fixes unawaited_futures violations.
|
* Fixes unawaited_futures violations.
|
||||||
|
@ -826,9 +826,7 @@ Future<void> main() async {
|
|||||||
|
|
||||||
expect(error.errorType, isNotNull);
|
expect(error.errorType, isNotNull);
|
||||||
expect(
|
expect(
|
||||||
(error as AndroidWebResourceError)
|
error.url?.startsWith('https://www.notawebsite..com'),
|
||||||
.failingUrl
|
|
||||||
?.startsWith('https://www.notawebsite..com'),
|
|
||||||
isTrue,
|
isTrue,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -114,6 +114,7 @@ Page resource error:
|
|||||||
description: ${error.description}
|
description: ${error.description}
|
||||||
errorType: ${error.errorType}
|
errorType: ${error.errorType}
|
||||||
isForMainFrame: ${error.isForMainFrame}
|
isForMainFrame: ${error.isForMainFrame}
|
||||||
|
url: ${error.url}
|
||||||
''');
|
''');
|
||||||
})
|
})
|
||||||
..setOnNavigationRequest((NavigationRequest request) {
|
..setOnNavigationRequest((NavigationRequest request) {
|
||||||
|
@ -17,7 +17,7 @@ dependencies:
|
|||||||
# The example app is bundled with the plugin so we use a path dependency on
|
# The example app is bundled with the plugin so we use a path dependency on
|
||||||
# the parent directory to use the current plugin's version.
|
# the parent directory to use the current plugin's version.
|
||||||
path: ../
|
path: ../
|
||||||
webview_flutter_platform_interface: ^2.3.0
|
webview_flutter_platform_interface: ^2.4.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
espresso: ^0.2.0
|
espresso: ^0.2.0
|
||||||
|
@ -825,12 +825,14 @@ class AndroidWebResourceError extends WebResourceError {
|
|||||||
required super.errorCode,
|
required super.errorCode,
|
||||||
required super.description,
|
required super.description,
|
||||||
super.isForMainFrame,
|
super.isForMainFrame,
|
||||||
this.failingUrl,
|
super.url,
|
||||||
}) : super(
|
}) : failingUrl = url,
|
||||||
|
super(
|
||||||
errorType: _errorCodeToErrorType(errorCode),
|
errorType: _errorCodeToErrorType(errorCode),
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Gets the URL for which the failing resource request was made.
|
/// Gets the URL for which the failing resource request was made.
|
||||||
|
@Deprecated('Please use `url`.')
|
||||||
final String? failingUrl;
|
final String? failingUrl;
|
||||||
|
|
||||||
static WebResourceErrorType? _errorCodeToErrorType(int errorCode) {
|
static WebResourceErrorType? _errorCodeToErrorType(int errorCode) {
|
||||||
@ -954,7 +956,7 @@ class AndroidNavigationDelegate extends PlatformNavigationDelegate {
|
|||||||
callback(AndroidWebResourceError._(
|
callback(AndroidWebResourceError._(
|
||||||
errorCode: error.errorCode,
|
errorCode: error.errorCode,
|
||||||
description: error.description,
|
description: error.description,
|
||||||
failingUrl: request.url,
|
url: request.url,
|
||||||
isForMainFrame: request.isForMainFrame,
|
isForMainFrame: request.isForMainFrame,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -971,7 +973,7 @@ class AndroidNavigationDelegate extends PlatformNavigationDelegate {
|
|||||||
callback(AndroidWebResourceError._(
|
callback(AndroidWebResourceError._(
|
||||||
errorCode: errorCode,
|
errorCode: errorCode,
|
||||||
description: description,
|
description: description,
|
||||||
failingUrl: failingUrl,
|
url: failingUrl,
|
||||||
isForMainFrame: true,
|
isForMainFrame: true,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ name: webview_flutter_android
|
|||||||
description: A Flutter plugin that provides a WebView widget on Android.
|
description: A Flutter plugin that provides a WebView widget on Android.
|
||||||
repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_android
|
repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_android
|
||||||
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
|
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
|
||||||
version: 3.8.2
|
version: 3.9.0
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.18.0 <4.0.0"
|
sdk: ">=2.18.0 <4.0.0"
|
||||||
@ -20,7 +20,7 @@ flutter:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
webview_flutter_platform_interface: ^2.3.0
|
webview_flutter_platform_interface: ^2.4.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^2.1.4
|
build_runner: ^2.1.4
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
## 3.7.0
|
||||||
|
|
||||||
|
* Adds support for `WebResouceError.url`.
|
||||||
|
|
||||||
## 3.6.3
|
## 3.6.3
|
||||||
|
|
||||||
* Introduces `NSError.toString` for better diagnostics.
|
* Introduces `NSError.toString` for better diagnostics.
|
||||||
|
@ -834,6 +834,10 @@ Future<void> main() async {
|
|||||||
|
|
||||||
final WebResourceError error = await errorCompleter.future;
|
final WebResourceError error = await errorCompleter.future;
|
||||||
expect(error, isNotNull);
|
expect(error, isNotNull);
|
||||||
|
expect(
|
||||||
|
error.url?.startsWith('https://www.notawebsite..com'),
|
||||||
|
isTrue,
|
||||||
|
);
|
||||||
|
|
||||||
expect((error as WebKitWebResourceError).domain, isNotNull);
|
expect((error as WebKitWebResourceError).domain, isNotNull);
|
||||||
});
|
});
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||||
8F4FF949299ADC2D000A6586 /* FWFWebViewFlutterWKWebViewExternalAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F4FF948299ADC2D000A6586 /* FWFWebViewFlutterWKWebViewExternalAPITests.m */; };
|
8F4FF949299ADC2D000A6586 /* FWFWebViewFlutterWKWebViewExternalAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F4FF948299ADC2D000A6586 /* FWFWebViewFlutterWKWebViewExternalAPITests.m */; };
|
||||||
8F4FF94B29AC223F000A6586 /* FWFURLTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F4FF94A29AC223F000A6586 /* FWFURLTests.m */; };
|
8F4FF94B29AC223F000A6586 /* FWFURLTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F4FF94A29AC223F000A6586 /* FWFURLTests.m */; };
|
||||||
|
8F78EAAA2A02CB9100C2E520 /* FWFErrorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F78EAA92A02CB9100C2E520 /* FWFErrorTests.m */; };
|
||||||
8FA6A87928062CD000A4B183 /* FWFInstanceManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FA6A87828062CD000A4B183 /* FWFInstanceManagerTests.m */; };
|
8FA6A87928062CD000A4B183 /* FWFInstanceManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FA6A87828062CD000A4B183 /* FWFInstanceManagerTests.m */; };
|
||||||
8FB79B5328134C3100C101D3 /* FWFWebViewHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FB79B5228134C3100C101D3 /* FWFWebViewHostApiTests.m */; };
|
8FB79B5328134C3100C101D3 /* FWFWebViewHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FB79B5228134C3100C101D3 /* FWFWebViewHostApiTests.m */; };
|
||||||
8FB79B55281B24F600C101D3 /* FWFDataConvertersTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FB79B54281B24F600C101D3 /* FWFDataConvertersTests.m */; };
|
8FB79B55281B24F600C101D3 /* FWFDataConvertersTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FB79B54281B24F600C101D3 /* FWFDataConvertersTests.m */; };
|
||||||
@ -80,6 +81,7 @@
|
|||||||
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||||
8F4FF948299ADC2D000A6586 /* FWFWebViewFlutterWKWebViewExternalAPITests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FWFWebViewFlutterWKWebViewExternalAPITests.m; sourceTree = "<group>"; };
|
8F4FF948299ADC2D000A6586 /* FWFWebViewFlutterWKWebViewExternalAPITests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FWFWebViewFlutterWKWebViewExternalAPITests.m; sourceTree = "<group>"; };
|
||||||
8F4FF94A29AC223F000A6586 /* FWFURLTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFURLTests.m; sourceTree = "<group>"; };
|
8F4FF94A29AC223F000A6586 /* FWFURLTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFURLTests.m; sourceTree = "<group>"; };
|
||||||
|
8F78EAA92A02CB9100C2E520 /* FWFErrorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFErrorTests.m; sourceTree = "<group>"; };
|
||||||
8FA6A87828062CD000A4B183 /* FWFInstanceManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFInstanceManagerTests.m; sourceTree = "<group>"; };
|
8FA6A87828062CD000A4B183 /* FWFInstanceManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFInstanceManagerTests.m; sourceTree = "<group>"; };
|
||||||
8FB79B5228134C3100C101D3 /* FWFWebViewHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFWebViewHostApiTests.m; sourceTree = "<group>"; };
|
8FB79B5228134C3100C101D3 /* FWFWebViewHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFWebViewHostApiTests.m; sourceTree = "<group>"; };
|
||||||
8FB79B54281B24F600C101D3 /* FWFDataConvertersTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFDataConvertersTests.m; sourceTree = "<group>"; };
|
8FB79B54281B24F600C101D3 /* FWFDataConvertersTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFDataConvertersTests.m; sourceTree = "<group>"; };
|
||||||
@ -165,6 +167,7 @@
|
|||||||
8FB79B902820BAC700C101D3 /* FWFUIViewHostApiTests.m */,
|
8FB79B902820BAC700C101D3 /* FWFUIViewHostApiTests.m */,
|
||||||
8FB79B962821985200C101D3 /* FWFObjectHostApiTests.m */,
|
8FB79B962821985200C101D3 /* FWFObjectHostApiTests.m */,
|
||||||
8F4FF94A29AC223F000A6586 /* FWFURLTests.m */,
|
8F4FF94A29AC223F000A6586 /* FWFURLTests.m */,
|
||||||
|
8F78EAA92A02CB9100C2E520 /* FWFErrorTests.m */,
|
||||||
);
|
);
|
||||||
path = RunnerTests;
|
path = RunnerTests;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -466,6 +469,7 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
8FA6A87928062CD000A4B183 /* FWFInstanceManagerTests.m in Sources */,
|
8FA6A87928062CD000A4B183 /* FWFInstanceManagerTests.m in Sources */,
|
||||||
|
8F78EAAA2A02CB9100C2E520 /* FWFErrorTests.m in Sources */,
|
||||||
8F4FF94B29AC223F000A6586 /* FWFURLTests.m in Sources */,
|
8F4FF94B29AC223F000A6586 /* FWFURLTests.m in Sources */,
|
||||||
8FB79B852820A3A400C101D3 /* FWFUIDelegateHostApiTests.m in Sources */,
|
8FB79B852820A3A400C101D3 /* FWFUIDelegateHostApiTests.m in Sources */,
|
||||||
8FB79B972821985200C101D3 /* FWFObjectHostApiTests.m in Sources */,
|
8FB79B972821985200C101D3 /* FWFObjectHostApiTests.m in Sources */,
|
||||||
|
@ -98,14 +98,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)testFWFNSErrorDataFromNSError {
|
- (void)testFWFNSErrorDataFromNSError {
|
||||||
|
NSObject *unsupportedType = [[NSObject alloc] init];
|
||||||
NSError *error = [NSError errorWithDomain:@"domain"
|
NSError *error = [NSError errorWithDomain:@"domain"
|
||||||
code:23
|
code:23
|
||||||
userInfo:@{NSLocalizedDescriptionKey : @"description"}];
|
userInfo:@{@"a" : @"b", @"c" : unsupportedType}];
|
||||||
|
|
||||||
FWFNSErrorData *data = FWFNSErrorDataFromNativeNSError(error);
|
FWFNSErrorData *data = FWFNSErrorDataFromNativeNSError(error);
|
||||||
XCTAssertEqualObjects(data.code, @23);
|
XCTAssertEqualObjects(data.code, @23);
|
||||||
XCTAssertEqualObjects(data.domain, @"domain");
|
XCTAssertEqualObjects(data.domain, @"domain");
|
||||||
XCTAssertEqualObjects(data.localizedDescription, @"description");
|
|
||||||
|
NSDictionary *userInfo = @{
|
||||||
|
@"a" : @"b",
|
||||||
|
@"c" : [NSString stringWithFormat:@"Unsupported Type: %@", unsupportedType.description]
|
||||||
|
};
|
||||||
|
XCTAssertEqualObjects(data.userInfo, userInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testFWFWKScriptMessageDataFromWKScriptMessage {
|
- (void)testFWFWKScriptMessageDataFromWKScriptMessage {
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
@import XCTest;
|
||||||
|
|
||||||
|
#import <XCTest/XCTest.h>
|
||||||
|
|
||||||
|
@interface FWFErrorTests : XCTestCase
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation FWFErrorTests
|
||||||
|
- (void)testNSErrorUserInfoKey {
|
||||||
|
// These MUST match the String values in the Dart class NSErrorUserInfoKey.
|
||||||
|
XCTAssertEqualObjects(NSLocalizedDescriptionKey, @"NSLocalizedDescription");
|
||||||
|
XCTAssertEqualObjects(NSURLErrorFailingURLStringErrorKey, @"NSErrorFailingURLStringKey");
|
||||||
|
}
|
||||||
|
@end
|
@ -408,7 +408,7 @@ static bool feq(CGFloat a, CGFloat b) { return fabs(b - a) < FLT_EPSILON; }
|
|||||||
XCTAssertTrue([errorData isKindOfClass:[FWFNSErrorData class]]);
|
XCTAssertTrue([errorData isKindOfClass:[FWFNSErrorData class]]);
|
||||||
XCTAssertEqualObjects(errorData.code, @0);
|
XCTAssertEqualObjects(errorData.code, @0);
|
||||||
XCTAssertEqualObjects(errorData.domain, @"errorDomain");
|
XCTAssertEqualObjects(errorData.domain, @"errorDomain");
|
||||||
XCTAssertEqualObjects(errorData.localizedDescription, @"description");
|
XCTAssertEqualObjects(errorData.userInfo, @{NSLocalizedDescriptionKey : @"description"});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testWebViewContentInsetBehaviorShouldBeNever {
|
- (void)testWebViewContentInsetBehaviorShouldBeNever {
|
||||||
|
@ -115,6 +115,7 @@ Page resource error:
|
|||||||
description: ${error.description}
|
description: ${error.description}
|
||||||
errorType: ${error.errorType}
|
errorType: ${error.errorType}
|
||||||
isForMainFrame: ${error.isForMainFrame}
|
isForMainFrame: ${error.isForMainFrame}
|
||||||
|
url: ${error.url}
|
||||||
''');
|
''');
|
||||||
})
|
})
|
||||||
..setOnNavigationRequest((NavigationRequest request) {
|
..setOnNavigationRequest((NavigationRequest request) {
|
||||||
|
@ -10,7 +10,7 @@ dependencies:
|
|||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
path_provider: ^2.0.6
|
path_provider: ^2.0.6
|
||||||
webview_flutter_platform_interface: ^2.3.0
|
webview_flutter_platform_interface: ^2.4.0
|
||||||
webview_flutter_wkwebview:
|
webview_flutter_wkwebview:
|
||||||
# When depending on this package from a real application you should use:
|
# When depending on this package from a real application you should use:
|
||||||
# webview_flutter: ^x.y.z
|
# webview_flutter: ^x.y.z
|
||||||
|
@ -192,9 +192,19 @@ WKNavigationActionPolicy FWFNativeWKNavigationActionPolicyFromEnumData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
FWFNSErrorData *FWFNSErrorDataFromNativeNSError(NSError *error) {
|
FWFNSErrorData *FWFNSErrorDataFromNativeNSError(NSError *error) {
|
||||||
return [FWFNSErrorData makeWithCode:@(error.code)
|
NSMutableDictionary *userInfo;
|
||||||
domain:error.domain
|
if (error.userInfo) {
|
||||||
localizedDescription:error.localizedDescription];
|
userInfo = [NSMutableDictionary dictionary];
|
||||||
|
for (NSErrorUserInfoKey key in error.userInfo.allKeys) {
|
||||||
|
NSObject *value = error.userInfo[key];
|
||||||
|
if ([value isKindOfClass:[NSString class]]) {
|
||||||
|
userInfo[key] = value;
|
||||||
|
} else {
|
||||||
|
userInfo[key] = [NSString stringWithFormat:@"Unsupported Type: %@", value.description];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [FWFNSErrorData makeWithCode:@(error.code) domain:error.domain userInfo:userInfo];
|
||||||
}
|
}
|
||||||
|
|
||||||
FWFNSKeyValueChangeKeyEnumData *FWFNSKeyValueChangeKeyEnumDataFromNativeNSKeyValueChangeKey(
|
FWFNSKeyValueChangeKeyEnumData *FWFNSKeyValueChangeKeyEnumDataFromNativeNSKeyValueChangeKey(
|
||||||
|
@ -342,10 +342,10 @@ typedef NS_ENUM(NSUInteger, FWFWKMediaCaptureType) {
|
|||||||
- (instancetype)init NS_UNAVAILABLE;
|
- (instancetype)init NS_UNAVAILABLE;
|
||||||
+ (instancetype)makeWithCode:(NSNumber *)code
|
+ (instancetype)makeWithCode:(NSNumber *)code
|
||||||
domain:(NSString *)domain
|
domain:(NSString *)domain
|
||||||
localizedDescription:(NSString *)localizedDescription;
|
userInfo:(nullable NSDictionary<NSString *, id> *)userInfo;
|
||||||
@property(nonatomic, strong) NSNumber *code;
|
@property(nonatomic, strong) NSNumber *code;
|
||||||
@property(nonatomic, copy) NSString *domain;
|
@property(nonatomic, copy) NSString *domain;
|
||||||
@property(nonatomic, copy) NSString *localizedDescription;
|
@property(nonatomic, strong, nullable) NSDictionary<NSString *, id> *userInfo;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
/// Mirror of WKScriptMessage.
|
/// Mirror of WKScriptMessage.
|
||||||
|
@ -455,11 +455,11 @@ static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) {
|
|||||||
@implementation FWFNSErrorData
|
@implementation FWFNSErrorData
|
||||||
+ (instancetype)makeWithCode:(NSNumber *)code
|
+ (instancetype)makeWithCode:(NSNumber *)code
|
||||||
domain:(NSString *)domain
|
domain:(NSString *)domain
|
||||||
localizedDescription:(NSString *)localizedDescription {
|
userInfo:(nullable NSDictionary<NSString *, id> *)userInfo {
|
||||||
FWFNSErrorData *pigeonResult = [[FWFNSErrorData alloc] init];
|
FWFNSErrorData *pigeonResult = [[FWFNSErrorData alloc] init];
|
||||||
pigeonResult.code = code;
|
pigeonResult.code = code;
|
||||||
pigeonResult.domain = domain;
|
pigeonResult.domain = domain;
|
||||||
pigeonResult.localizedDescription = localizedDescription;
|
pigeonResult.userInfo = userInfo;
|
||||||
return pigeonResult;
|
return pigeonResult;
|
||||||
}
|
}
|
||||||
+ (FWFNSErrorData *)fromList:(NSArray *)list {
|
+ (FWFNSErrorData *)fromList:(NSArray *)list {
|
||||||
@ -468,8 +468,7 @@ static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) {
|
|||||||
NSAssert(pigeonResult.code != nil, @"");
|
NSAssert(pigeonResult.code != nil, @"");
|
||||||
pigeonResult.domain = GetNullableObjectAtIndex(list, 1);
|
pigeonResult.domain = GetNullableObjectAtIndex(list, 1);
|
||||||
NSAssert(pigeonResult.domain != nil, @"");
|
NSAssert(pigeonResult.domain != nil, @"");
|
||||||
pigeonResult.localizedDescription = GetNullableObjectAtIndex(list, 2);
|
pigeonResult.userInfo = GetNullableObjectAtIndex(list, 2);
|
||||||
NSAssert(pigeonResult.localizedDescription != nil, @"");
|
|
||||||
return pigeonResult;
|
return pigeonResult;
|
||||||
}
|
}
|
||||||
+ (nullable FWFNSErrorData *)nullableFromList:(NSArray *)list {
|
+ (nullable FWFNSErrorData *)nullableFromList:(NSArray *)list {
|
||||||
@ -479,7 +478,7 @@ static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) {
|
|||||||
return @[
|
return @[
|
||||||
(self.code ?: [NSNull null]),
|
(self.code ?: [NSNull null]),
|
||||||
(self.domain ?: [NSNull null]),
|
(self.domain ?: [NSNull null]),
|
||||||
(self.localizedDescription ?: [NSNull null]),
|
(self.userInfo ?: [NSNull null]),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
@ -522,20 +522,20 @@ class NSErrorData {
|
|||||||
NSErrorData({
|
NSErrorData({
|
||||||
required this.code,
|
required this.code,
|
||||||
required this.domain,
|
required this.domain,
|
||||||
required this.localizedDescription,
|
this.userInfo,
|
||||||
});
|
});
|
||||||
|
|
||||||
int code;
|
int code;
|
||||||
|
|
||||||
String domain;
|
String domain;
|
||||||
|
|
||||||
String localizedDescription;
|
Map<String?, Object?>? userInfo;
|
||||||
|
|
||||||
Object encode() {
|
Object encode() {
|
||||||
return <Object?>[
|
return <Object?>[
|
||||||
code,
|
code,
|
||||||
domain,
|
domain,
|
||||||
localizedDescription,
|
userInfo,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,7 +544,7 @@ class NSErrorData {
|
|||||||
return NSErrorData(
|
return NSErrorData(
|
||||||
code: result[0]! as int,
|
code: result[0]! as int,
|
||||||
domain: result[1]! as String,
|
domain: result[1]! as String,
|
||||||
localizedDescription: result[2]! as String,
|
userInfo: (result[2] as Map<Object?, Object?>?)?.cast<String?, Object?>(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,6 +201,23 @@ class NSUrlRequest {
|
|||||||
final Map<String, String> allHttpHeaderFields;
|
final Map<String, String> allHttpHeaderFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Keys that may exist in the user info map of `NSError`.
|
||||||
|
class NSErrorUserInfoKey {
|
||||||
|
NSErrorUserInfoKey._();
|
||||||
|
|
||||||
|
/// The corresponding value is a localized string representation of the error
|
||||||
|
/// that, if present, will be returned by [NSError.localizedDescription].
|
||||||
|
///
|
||||||
|
/// See https://developer.apple.com/documentation/foundation/nslocalizeddescriptionkey.
|
||||||
|
static const String NSLocalizedDescription = 'NSLocalizedDescription';
|
||||||
|
|
||||||
|
/// The URL which caused a load to fail.
|
||||||
|
///
|
||||||
|
/// See https://developer.apple.com/documentation/foundation/nsurlerrorfailingurlstringerrorkey?language=objc.
|
||||||
|
static const String NSURLErrorFailingURLStringError =
|
||||||
|
'NSErrorFailingURLStringKey';
|
||||||
|
}
|
||||||
|
|
||||||
/// Information about an error condition.
|
/// Information about an error condition.
|
||||||
///
|
///
|
||||||
/// Wraps [NSError](https://developer.apple.com/documentation/foundation/nserror?language=objc).
|
/// Wraps [NSError](https://developer.apple.com/documentation/foundation/nserror?language=objc).
|
||||||
@ -210,7 +227,7 @@ class NSError {
|
|||||||
const NSError({
|
const NSError({
|
||||||
required this.code,
|
required this.code,
|
||||||
required this.domain,
|
required this.domain,
|
||||||
required this.localizedDescription,
|
this.userInfo = const <String, Object?>{},
|
||||||
});
|
});
|
||||||
|
|
||||||
/// The error code.
|
/// The error code.
|
||||||
@ -221,15 +238,23 @@ class NSError {
|
|||||||
/// A string containing the error domain.
|
/// A string containing the error domain.
|
||||||
final String domain;
|
final String domain;
|
||||||
|
|
||||||
|
/// Map of arbitrary data.
|
||||||
|
///
|
||||||
|
/// See [NSErrorUserInfoKey] for possible keys (non-exhaustive).
|
||||||
|
///
|
||||||
|
/// This currently only supports values that are a String.
|
||||||
|
final Map<String, Object?> userInfo;
|
||||||
|
|
||||||
/// A string containing the localized description of the error.
|
/// A string containing the localized description of the error.
|
||||||
final String localizedDescription;
|
String? get localizedDescription =>
|
||||||
|
userInfo[NSErrorUserInfoKey.NSLocalizedDescription] as String?;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
if (localizedDescription.isEmpty) {
|
if (localizedDescription?.isEmpty ?? true) {
|
||||||
return 'Error $domain:$code';
|
return 'Error $domain:$code:$userInfo';
|
||||||
}
|
}
|
||||||
return '$localizedDescription ($domain:$code)';
|
return '$localizedDescription ($domain:$code:$userInfo)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,7 +596,7 @@ class WebKitWebViewPlatformController extends WebViewPlatformController {
|
|||||||
return WebResourceError(
|
return WebResourceError(
|
||||||
errorCode: error.code,
|
errorCode: error.code,
|
||||||
domain: error.domain,
|
domain: error.domain,
|
||||||
description: error.localizedDescription,
|
description: error.localizedDescription ?? '',
|
||||||
errorType: errorType,
|
errorType: errorType,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ extension _WKNSErrorDataConverter on NSErrorData {
|
|||||||
return NSError(
|
return NSError(
|
||||||
domain: domain,
|
domain: domain,
|
||||||
code: code,
|
code: code,
|
||||||
localizedDescription: localizedDescription,
|
userInfo: userInfo?.cast<String, Object?>() ?? <String, Object?>{},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -665,10 +665,13 @@ class WebKitWebViewWidget extends PlatformWebViewWidget {
|
|||||||
|
|
||||||
/// An implementation of [WebResourceError] with the WebKit API.
|
/// An implementation of [WebResourceError] with the WebKit API.
|
||||||
class WebKitWebResourceError extends WebResourceError {
|
class WebKitWebResourceError extends WebResourceError {
|
||||||
WebKitWebResourceError._(this._nsError, {required bool isForMainFrame})
|
WebKitWebResourceError._(
|
||||||
: super(
|
this._nsError, {
|
||||||
|
required bool isForMainFrame,
|
||||||
|
required super.url,
|
||||||
|
}) : super(
|
||||||
errorCode: _nsError.code,
|
errorCode: _nsError.code,
|
||||||
description: _nsError.localizedDescription,
|
description: _nsError.localizedDescription ?? '',
|
||||||
errorType: _toWebResourceErrorType(_nsError.code),
|
errorType: _toWebResourceErrorType(_nsError.code),
|
||||||
isForMainFrame: isForMainFrame,
|
isForMainFrame: isForMainFrame,
|
||||||
);
|
);
|
||||||
@ -766,14 +769,24 @@ class WebKitNavigationDelegate extends PlatformNavigationDelegate {
|
|||||||
didFailNavigation: (WKWebView webView, NSError error) {
|
didFailNavigation: (WKWebView webView, NSError error) {
|
||||||
if (weakThis.target?._onWebResourceError != null) {
|
if (weakThis.target?._onWebResourceError != null) {
|
||||||
weakThis.target!._onWebResourceError!(
|
weakThis.target!._onWebResourceError!(
|
||||||
WebKitWebResourceError._(error, isForMainFrame: true),
|
WebKitWebResourceError._(
|
||||||
|
error,
|
||||||
|
isForMainFrame: true,
|
||||||
|
url: error.userInfo[NSErrorUserInfoKey
|
||||||
|
.NSURLErrorFailingURLStringError] as String?,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
didFailProvisionalNavigation: (WKWebView webView, NSError error) {
|
didFailProvisionalNavigation: (WKWebView webView, NSError error) {
|
||||||
if (weakThis.target?._onWebResourceError != null) {
|
if (weakThis.target?._onWebResourceError != null) {
|
||||||
weakThis.target!._onWebResourceError!(
|
weakThis.target!._onWebResourceError!(
|
||||||
WebKitWebResourceError._(error, isForMainFrame: true),
|
WebKitWebResourceError._(
|
||||||
|
error,
|
||||||
|
isForMainFrame: true,
|
||||||
|
url: error.userInfo[NSErrorUserInfoKey
|
||||||
|
.NSURLErrorFailingURLStringError] as String?,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -785,9 +798,9 @@ class WebKitNavigationDelegate extends PlatformNavigationDelegate {
|
|||||||
code: WKErrorCode.webContentProcessTerminated,
|
code: WKErrorCode.webContentProcessTerminated,
|
||||||
// Value from https://developer.apple.com/documentation/webkit/wkerrordomain?language=objc.
|
// Value from https://developer.apple.com/documentation/webkit/wkerrordomain?language=objc.
|
||||||
domain: 'WKErrorDomain',
|
domain: 'WKErrorDomain',
|
||||||
localizedDescription: '',
|
|
||||||
),
|
),
|
||||||
isForMainFrame: true,
|
isForMainFrame: true,
|
||||||
|
url: null,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -299,7 +299,7 @@ class WKFrameInfoData {
|
|||||||
class NSErrorData {
|
class NSErrorData {
|
||||||
late int code;
|
late int code;
|
||||||
late String domain;
|
late String domain;
|
||||||
late String localizedDescription;
|
late Map<String?, Object?>? userInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mirror of WKScriptMessage.
|
/// Mirror of WKScriptMessage.
|
||||||
|
@ -2,7 +2,7 @@ name: webview_flutter_wkwebview
|
|||||||
description: A Flutter plugin that provides a WebView widget based on Apple's WKWebView control.
|
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
|
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
|
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
|
||||||
version: 3.6.3
|
version: 3.7.0
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.18.0 <4.0.0"
|
sdk: ">=2.18.0 <4.0.0"
|
||||||
@ -20,7 +20,7 @@ dependencies:
|
|||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
path: ^1.8.0
|
path: ^1.8.0
|
||||||
webview_flutter_platform_interface: ^2.3.0
|
webview_flutter_platform_interface: ^2.4.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^2.1.5
|
build_runner: ^2.1.5
|
||||||
|
@ -777,7 +777,6 @@ void main() {
|
|||||||
details: const NSError(
|
details: const NSError(
|
||||||
code: WKErrorCode.javaScriptResultTypeIsUnsupported,
|
code: WKErrorCode.javaScriptResultTypeIsUnsupported,
|
||||||
domain: '',
|
domain: '',
|
||||||
localizedDescription: '',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
expect(
|
expect(
|
||||||
@ -1049,7 +1048,9 @@ void main() {
|
|||||||
const NSError(
|
const NSError(
|
||||||
code: WKErrorCode.webViewInvalidated,
|
code: WKErrorCode.webViewInvalidated,
|
||||||
domain: 'domain',
|
domain: 'domain',
|
||||||
localizedDescription: 'my desc',
|
userInfo: <String, Object?>{
|
||||||
|
NSErrorUserInfoKey.NSLocalizedDescription: 'my desc',
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1086,7 +1087,9 @@ void main() {
|
|||||||
const NSError(
|
const NSError(
|
||||||
code: WKErrorCode.webContentProcessTerminated,
|
code: WKErrorCode.webContentProcessTerminated,
|
||||||
domain: 'domain',
|
domain: 'domain',
|
||||||
localizedDescription: 'my desc',
|
userInfo: <String, Object?>{
|
||||||
|
NSErrorUserInfoKey.NSLocalizedDescription: 'my desc',
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -252,33 +252,41 @@ void main() {
|
|||||||
const NSError(
|
const NSError(
|
||||||
code: 0,
|
code: 0,
|
||||||
domain: 'domain',
|
domain: 'domain',
|
||||||
localizedDescription: 'desc',
|
userInfo: <String, Object?>{
|
||||||
|
NSErrorUserInfoKey.NSLocalizedDescription: 'desc',
|
||||||
|
},
|
||||||
).toString(),
|
).toString(),
|
||||||
'desc (domain:0)',
|
'desc (domain:0:{NSLocalizedDescription: desc})',
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
const NSError(
|
const NSError(
|
||||||
code: 0,
|
code: 0,
|
||||||
domain: 'domain',
|
domain: 'domain',
|
||||||
localizedDescription: '',
|
userInfo: <String, Object?>{
|
||||||
|
NSErrorUserInfoKey.NSLocalizedDescription: '',
|
||||||
|
},
|
||||||
).toString(),
|
).toString(),
|
||||||
'Error domain:0',
|
'Error domain:0:{NSLocalizedDescription: }',
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
const NSError(
|
const NSError(
|
||||||
code: 255,
|
code: 255,
|
||||||
domain: 'bar',
|
domain: 'bar',
|
||||||
localizedDescription: 'baz',
|
userInfo: <String, Object?>{
|
||||||
|
NSErrorUserInfoKey.NSLocalizedDescription: 'baz',
|
||||||
|
},
|
||||||
).toString(),
|
).toString(),
|
||||||
'baz (bar:255)',
|
'baz (bar:255:{NSLocalizedDescription: baz})',
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
const NSError(
|
const NSError(
|
||||||
code: 255,
|
code: 255,
|
||||||
domain: 'bar',
|
domain: 'bar',
|
||||||
localizedDescription: '',
|
userInfo: <String, Object?>{
|
||||||
|
NSErrorUserInfoKey.NSLocalizedDescription: '',
|
||||||
|
},
|
||||||
).toString(),
|
).toString(),
|
||||||
'Error bar:255',
|
'Error bar:255:{NSLocalizedDescription: }',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -614,7 +614,9 @@ void main() {
|
|||||||
NSErrorData(
|
NSErrorData(
|
||||||
code: 23,
|
code: 23,
|
||||||
domain: 'Hello',
|
domain: 'Hello',
|
||||||
localizedDescription: 'localiziedDescription',
|
userInfo: <String, Object?>{
|
||||||
|
NSErrorUserInfoKey.NSLocalizedDescription: 'my desc',
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -646,7 +648,9 @@ void main() {
|
|||||||
NSErrorData(
|
NSErrorData(
|
||||||
code: 23,
|
code: 23,
|
||||||
domain: 'Hello',
|
domain: 'Hello',
|
||||||
localizedDescription: 'localiziedDescription',
|
userInfo: <String, Object?>{
|
||||||
|
NSErrorUserInfoKey.NSLocalizedDescription: 'my desc',
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -851,7 +855,9 @@ void main() {
|
|||||||
details: NSErrorData(
|
details: NSErrorData(
|
||||||
code: 0,
|
code: 0,
|
||||||
domain: 'domain',
|
domain: 'domain',
|
||||||
localizedDescription: 'desc',
|
userInfo: <String, Object?>{
|
||||||
|
NSErrorUserInfoKey.NSLocalizedDescription: 'desc',
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -92,12 +92,17 @@ void main() {
|
|||||||
const NSError(
|
const NSError(
|
||||||
code: WKErrorCode.webViewInvalidated,
|
code: WKErrorCode.webViewInvalidated,
|
||||||
domain: 'domain',
|
domain: 'domain',
|
||||||
localizedDescription: 'my desc',
|
userInfo: <String, Object?>{
|
||||||
|
NSErrorUserInfoKey.NSURLErrorFailingURLStringError:
|
||||||
|
'www.flutter.dev',
|
||||||
|
NSErrorUserInfoKey.NSLocalizedDescription: 'my desc',
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(callbackError.description, 'my desc');
|
expect(callbackError.description, 'my desc');
|
||||||
expect(callbackError.errorCode, WKErrorCode.webViewInvalidated);
|
expect(callbackError.errorCode, WKErrorCode.webViewInvalidated);
|
||||||
|
expect(callbackError.url, 'www.flutter.dev');
|
||||||
expect(callbackError.domain, 'domain');
|
expect(callbackError.domain, 'domain');
|
||||||
expect(callbackError.errorType, WebResourceErrorType.webViewInvalidated);
|
expect(callbackError.errorType, WebResourceErrorType.webViewInvalidated);
|
||||||
expect(callbackError.isForMainFrame, true);
|
expect(callbackError.isForMainFrame, true);
|
||||||
@ -126,11 +131,16 @@ void main() {
|
|||||||
const NSError(
|
const NSError(
|
||||||
code: WKErrorCode.webViewInvalidated,
|
code: WKErrorCode.webViewInvalidated,
|
||||||
domain: 'domain',
|
domain: 'domain',
|
||||||
localizedDescription: 'my desc',
|
userInfo: <String, Object?>{
|
||||||
|
NSErrorUserInfoKey.NSURLErrorFailingURLStringError:
|
||||||
|
'www.flutter.dev',
|
||||||
|
NSErrorUserInfoKey.NSLocalizedDescription: 'my desc',
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(callbackError.description, 'my desc');
|
expect(callbackError.description, 'my desc');
|
||||||
|
expect(callbackError.url, 'www.flutter.dev');
|
||||||
expect(callbackError.errorCode, WKErrorCode.webViewInvalidated);
|
expect(callbackError.errorCode, WKErrorCode.webViewInvalidated);
|
||||||
expect(callbackError.domain, 'domain');
|
expect(callbackError.domain, 'domain');
|
||||||
expect(callbackError.errorType, WebResourceErrorType.webViewInvalidated);
|
expect(callbackError.errorType, WebResourceErrorType.webViewInvalidated);
|
||||||
|
@ -502,7 +502,6 @@ void main() {
|
|||||||
details: const NSError(
|
details: const NSError(
|
||||||
code: WKErrorCode.javaScriptResultTypeIsUnsupported,
|
code: WKErrorCode.javaScriptResultTypeIsUnsupported,
|
||||||
domain: '',
|
domain: '',
|
||||||
localizedDescription: '',
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
expect(
|
expect(
|
||||||
|
Reference in New Issue
Block a user