FLTWKNavigationDelegate.m
4.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright 2019 The Chromium 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 "FLTWKNavigationDelegate.h"
@implementation FLTWKNavigationDelegate {
FlutterMethodChannel *_methodChannel;
}
- (instancetype)initWithChannel:(FlutterMethodChannel *)channel {
self = [super init];
if (self) {
_methodChannel = channel;
}
return self;
}
#pragma mark - WKNavigationDelegate conformance
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
[_methodChannel invokeMethod:@"onPageStarted" arguments:@{@"url" : webView.URL.absoluteString}];
}
- (void)webView:(WKWebView *)webView
decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if (!self.hasDartNavigationDelegate) {
decisionHandler(WKNavigationActionPolicyAllow);
return;
}
NSDictionary *arguments = @{
@"url" : navigationAction.request.URL.absoluteString,
@"isForMainFrame" : @(navigationAction.targetFrame.isMainFrame)
};
[_methodChannel invokeMethod:@"navigationRequest"
arguments:arguments
result:^(id _Nullable result) {
if ([result isKindOfClass:[FlutterError class]]) {
NSLog(@"navigationRequest has unexpectedly completed with an error, "
@"allowing navigation.");
decisionHandler(WKNavigationActionPolicyAllow);
return;
}
if (result == FlutterMethodNotImplemented) {
NSLog(@"navigationRequest was unexepectedly not implemented: %@, "
@"allowing navigation.",
result);
decisionHandler(WKNavigationActionPolicyAllow);
return;
}
if (![result isKindOfClass:[NSNumber class]]) {
NSLog(@"navigationRequest unexpectedly returned a non boolean value: "
@"%@, allowing navigation.",
result);
decisionHandler(WKNavigationActionPolicyAllow);
return;
}
NSNumber *typedResult = result;
decisionHandler([typedResult boolValue] ? WKNavigationActionPolicyAllow
: WKNavigationActionPolicyCancel);
}];
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
[_methodChannel invokeMethod:@"onPageFinished" arguments:@{@"url" : webView.URL.absoluteString}];
}
+ (id)errorCodeToString:(NSUInteger)code {
switch (code) {
case WKErrorUnknown:
return @"unknown";
case WKErrorWebContentProcessTerminated:
return @"webContentProcessTerminated";
case WKErrorWebViewInvalidated:
return @"webViewInvalidated";
case WKErrorJavaScriptExceptionOccurred:
return @"javaScriptExceptionOccurred";
case WKErrorJavaScriptResultTypeIsUnsupported:
return @"javaScriptResultTypeIsUnsupported";
}
return [NSNull null];
}
- (void)onWebResourceError:(NSError *)error {
[_methodChannel invokeMethod:@"onWebResourceError"
arguments:@{
@"errorCode" : @(error.code),
@"domain" : error.domain,
@"description" : error.description,
@"errorType" : [FLTWKNavigationDelegate errorCodeToString:error.code],
}];
}
- (void)webView:(WKWebView *)webView
didFailNavigation:(WKNavigation *)navigation
withError:(NSError *)error {
[self onWebResourceError:error];
}
- (void)webView:(WKWebView *)webView
didFailProvisionalNavigation:(WKNavigation *)navigation
withError:(NSError *)error {
[self onWebResourceError:error];
}
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
NSError *contentProcessTerminatedError =
[[NSError alloc] initWithDomain:WKErrorDomain
code:WKErrorWebContentProcessTerminated
userInfo:nil];
[self onWebResourceError:contentProcessTerminatedError];
}
@end