Skip to content

Commit

Permalink
Allow specifying a navigation delegate (iOS implementation). (flutter…
Browse files Browse the repository at this point in the history
…#1323)

This is the iOS implementation of the navigation delegate method channel.

The Dart and Android implementations are in flutter#1236

Splitting off the iOS to keep a reasonable change size.
This PR will be merged first.

flutter/flutter#25329
  • Loading branch information
amirh authored Mar 9, 2019
1 parent 7951279 commit 45cc819
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string>Original</string>
</dict>
</plist>
21 changes: 21 additions & 0 deletions packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// 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 <Flutter/Flutter.h>
#import <WebKit/WebKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface FLTWKNavigationDelegate : NSObject <WKNavigationDelegate>

- (instancetype)initWithChannel:(FlutterMethodChannel*)channel;

/**
* Whether to delegate navigation decisions over the method channel.
*/
@property(nonatomic, assign) BOOL hasDartNavigationDelegate;

@end

NS_ASSUME_NONNULL_END
59 changes: 59 additions & 0 deletions packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// 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;
}

- (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);
}];
}

@end
7 changes: 7 additions & 0 deletions packages/webview_flutter/ios/Classes/FlutterWebView.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

#import "FlutterWebView.h"
#import "FLTWKNavigationDelegate.h"
#import "JavaScriptChannelHandler.h"

@implementation FLTWebViewFactory {
Expand Down Expand Up @@ -40,6 +41,7 @@ @implementation FLTWebViewController {
NSString* _currentUrl;
// The set of registered JavaScript channel names.
NSMutableSet* _javaScriptChannelNames;
FLTWKNavigationDelegate* _navigationDelegate;
}

- (instancetype)initWithFrame:(CGRect)frame
Expand All @@ -64,6 +66,8 @@ - (instancetype)initWithFrame:(CGRect)frame
configuration.userContentController = userContentController;

_webView = [[WKWebView alloc] initWithFrame:frame configuration:configuration];
_navigationDelegate = [[FLTWKNavigationDelegate alloc] initWithChannel:_channel];
_webView.navigationDelegate = _navigationDelegate;
__weak __typeof__(self) weakSelf = self;
[_channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
[weakSelf onMethodCall:call result:result];
Expand Down Expand Up @@ -229,6 +233,9 @@ - (void)applySettings:(NSDictionary<NSString*, id>*)settings {
if ([key isEqualToString:@"jsMode"]) {
NSNumber* mode = settings[key];
[self updateJsMode:mode];
} else if ([key isEqualToString:@"hasNavigationDelegate"]) {
NSNumber* hasDartNavigationDelegate = settings[key];
_navigationDelegate.hasDartNavigationDelegate = [hasDartNavigationDelegate boolValue];
} else {
NSLog(@"webview_flutter: unknown setting key: %@", key);
}
Expand Down

0 comments on commit 45cc819

Please sign in to comment.