diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Flutter/AppFrameworkInfo.plist b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Flutter/AppFrameworkInfo.plist
index 8d4492f977ad..9625e105df39 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Flutter/AppFrameworkInfo.plist
+++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Flutter/AppFrameworkInfo.plist
@@ -21,6 +21,6 @@
CFBundleVersion
1.0
MinimumOSVersion
- 9.0
+ 11.0
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Podfile b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Podfile
index 66509fcae284..d01e899e347b 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Podfile
+++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Podfile
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
-# platform :ios, '9.0'
+# platform :ios, '11.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj
index e7519af18e7c..4ed8769ea518 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj
@@ -614,7 +614,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -664,7 +664,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner/Info.plist b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner/Info.plist
index a810c5a172c0..bea41604e8aa 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner/Info.plist
+++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner/Info.plist
@@ -41,5 +41,7 @@
UIViewControllerBasedStatusBarAppearance
+ CADisableMinimumFrameDurationOnPhone
+
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFDataConvertersTests.m b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFDataConvertersTests.m
index 57d90f6c6814..1fc5a95398bd 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFDataConvertersTests.m
+++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFDataConvertersTests.m
@@ -6,6 +6,8 @@
@import XCTest;
@import webview_flutter_wkwebview;
+#import
+
@interface FWFDataConvertersTests : XCTestCase
@end
@@ -43,4 +45,63 @@ - (void)testFWFWKUserScriptFromScriptData {
XCTAssertEqual(userScript.injectionTime, WKUserScriptInjectionTimeAtDocumentStart);
XCTAssertEqual(userScript.isForMainFrameOnly, NO);
}
+
+- (void)testFWFWKNavigationActionDataFromNavigationAction {
+ WKNavigationAction *mockNavigationAction = OCMClassMock([WKNavigationAction class]);
+
+ NSURLRequest *request =
+ [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.flutter.dev/"]];
+ OCMStub([mockNavigationAction request]).andReturn(request);
+
+ WKFrameInfo *mockFrameInfo = OCMClassMock([WKFrameInfo class]);
+ OCMStub([mockFrameInfo isMainFrame]).andReturn(YES);
+ OCMStub([mockNavigationAction targetFrame]).andReturn(mockFrameInfo);
+
+ FWFWKNavigationActionData *data =
+ FWFWKNavigationActionDataFromNavigationAction(mockNavigationAction);
+ XCTAssertNotNil(data);
+}
+
+- (void)testFWFNSUrlRequestDataFromNSURLRequest {
+ NSMutableURLRequest *request =
+ [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://www.flutter.dev/"]];
+ request.HTTPMethod = @"POST";
+ request.HTTPBody = [@"aString" dataUsingEncoding:NSUTF8StringEncoding];
+ request.allHTTPHeaderFields = @{@"a" : @"field"};
+
+ FWFNSUrlRequestData *data = FWFNSUrlRequestDataFromNSURLRequest(request);
+ XCTAssertEqualObjects(data.url, @"https://www.flutter.dev/");
+ XCTAssertEqualObjects(data.httpMethod, @"POST");
+ XCTAssertEqualObjects(data.httpBody.data, [@"aString" dataUsingEncoding:NSUTF8StringEncoding]);
+ XCTAssertEqualObjects(data.allHttpHeaderFields, @{@"a" : @"field"});
+}
+
+- (void)testFWFWKFrameInfoDataFromWKFrameInfo {
+ WKFrameInfo *mockFrameInfo = OCMClassMock([WKFrameInfo class]);
+ OCMStub([mockFrameInfo isMainFrame]).andReturn(YES);
+
+ FWFWKFrameInfoData *targetFrameData = FWFWKFrameInfoDataFromWKFrameInfo(mockFrameInfo);
+ XCTAssertEqualObjects(targetFrameData.isMainFrame, @YES);
+}
+
+- (void)testFWFNSErrorDataFromNSError {
+ NSError *error = [NSError errorWithDomain:@"domain"
+ code:23
+ userInfo:@{NSLocalizedDescriptionKey : @"description"}];
+
+ FWFNSErrorData *data = FWFNSErrorDataFromNSError(error);
+ XCTAssertEqualObjects(data.code, @23);
+ XCTAssertEqualObjects(data.domain, @"domain");
+ XCTAssertEqualObjects(data.localizedDescription, @"description");
+}
+
+- (void)testFWFWKScriptMessageDataFromWKScriptMessage {
+ WKScriptMessage *mockScriptMessage = OCMClassMock([WKScriptMessage class]);
+ OCMStub([mockScriptMessage name]).andReturn(@"name");
+ OCMStub([mockScriptMessage body]).andReturn(@"message");
+
+ FWFWKScriptMessageData *data = FWFWKScriptMessageDataFromWKScriptMessage(mockScriptMessage);
+ XCTAssertEqualObjects(data.name, @"name");
+ XCTAssertEqualObjects(data.body, @"message");
+}
@end
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFNavigationDelegateHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFNavigationDelegateHostApiTests.m
index 206137e301f5..570a1f73ad9b 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFNavigationDelegateHostApiTests.m
+++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFNavigationDelegateHostApiTests.m
@@ -12,6 +12,38 @@ @interface FWFNavigationDelegateHostApiTests : XCTestCase
@end
@implementation FWFNavigationDelegateHostApiTests
+/**
+ * Creates a partially mocked FWFNavigationDelegate and adds it to instanceManager.
+ *
+ * @param instanceManager Instance manager to add the delegate to.
+ * @param identifier Identifier for the delegate added to the instanceManager.
+ *
+ * @return A mock FWFNavigationDelegate.
+ */
+- (id)mockNavigationDelegateWithManager:(FWFInstanceManager *)instanceManager
+ identifier:(long)identifier {
+ FWFNavigationDelegate *navigationDelegate = [[FWFNavigationDelegate alloc]
+ initWithBinaryMessenger:OCMProtocolMock(@protocol(FlutterBinaryMessenger))
+ instanceManager:instanceManager];
+
+ [instanceManager addDartCreatedInstance:navigationDelegate withIdentifier:0];
+ return OCMPartialMock(navigationDelegate);
+}
+
+/**
+ * Creates a mock FWFNavigationDelegateFlutterApiImpl with instanceManager.
+ *
+ * @param instanceManager Instance manager passed to the Flutter API.
+ *
+ * @return A mock FWFNavigationDelegateFlutterApiImpl.
+ */
+- (id)mockFlutterApiWithManager:(FWFInstanceManager *)instanceManager {
+ FWFNavigationDelegateFlutterApiImpl *flutterAPI = [[FWFNavigationDelegateFlutterApiImpl alloc]
+ initWithBinaryMessenger:OCMProtocolMock(@protocol(FlutterBinaryMessenger))
+ instanceManager:instanceManager];
+ return OCMPartialMock(flutterAPI);
+}
+
- (void)testCreateWithIdentifier {
FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init];
FWFNavigationDelegateHostApiImpl *hostAPI = [[FWFNavigationDelegateHostApiImpl alloc]
@@ -29,31 +61,156 @@ - (void)testCreateWithIdentifier {
- (void)testDidFinishNavigation {
FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init];
- FWFNavigationDelegateHostApiImpl *hostAPI = [[FWFNavigationDelegateHostApiImpl alloc]
- initWithBinaryMessenger:OCMProtocolMock(@protocol(FlutterBinaryMessenger))
- instanceManager:instanceManager];
- FlutterError *error;
- [hostAPI createWithIdentifier:@0 error:&error];
- FWFNavigationDelegate *navigationDelegate =
- (FWFNavigationDelegate *)[instanceManager instanceForIdentifier:0];
- id mockDelegate = OCMPartialMock(navigationDelegate);
+ FWFNavigationDelegate *mockDelegate = [self mockNavigationDelegateWithManager:instanceManager
+ identifier:0];
+ FWFNavigationDelegateFlutterApiImpl *mockFlutterAPI =
+ [self mockFlutterApiWithManager:instanceManager];
- FWFNavigationDelegateFlutterApiImpl *flutterAPI = [[FWFNavigationDelegateFlutterApiImpl alloc]
- initWithBinaryMessenger:OCMProtocolMock(@protocol(FlutterBinaryMessenger))
- instanceManager:instanceManager];
- id mockFlutterApi = OCMPartialMock(flutterAPI);
-
- OCMStub([mockDelegate navigationDelegateAPI]).andReturn(mockFlutterApi);
+ OCMStub([mockDelegate navigationDelegateAPI]).andReturn(mockFlutterAPI);
WKWebView *mockWebView = OCMClassMock([WKWebView class]);
OCMStub([mockWebView URL]).andReturn([NSURL URLWithString:@"https://flutter.dev/"]);
[instanceManager addDartCreatedInstance:mockWebView withIdentifier:1];
[mockDelegate webView:mockWebView didFinishNavigation:OCMClassMock([WKNavigation class])];
- OCMVerify([mockFlutterApi didFinishNavigationForDelegateWithIdentifier:@0
+ OCMVerify([mockFlutterAPI didFinishNavigationForDelegateWithIdentifier:@0
webViewIdentifier:@1
URL:@"https://flutter.dev/"
completion:OCMOCK_ANY]);
}
+
+- (void)testDidStartProvisionalNavigation {
+ FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init];
+
+ FWFNavigationDelegate *mockDelegate = [self mockNavigationDelegateWithManager:instanceManager
+ identifier:0];
+ FWFNavigationDelegateFlutterApiImpl *mockFlutterAPI =
+ [self mockFlutterApiWithManager:instanceManager];
+
+ OCMStub([mockDelegate navigationDelegateAPI]).andReturn(mockFlutterAPI);
+
+ WKWebView *mockWebView = OCMClassMock([WKWebView class]);
+ OCMStub([mockWebView URL]).andReturn([NSURL URLWithString:@"https://flutter.dev/"]);
+ [instanceManager addDartCreatedInstance:mockWebView withIdentifier:1];
+
+ [mockDelegate webView:mockWebView
+ didStartProvisionalNavigation:OCMClassMock([WKNavigation class])];
+ OCMVerify([mockFlutterAPI
+ didStartProvisionalNavigationForDelegateWithIdentifier:@0
+ webViewIdentifier:@1
+ URL:@"https://flutter.dev/"
+ completion:OCMOCK_ANY]);
+}
+
+- (void)testDecidePolicyForNavigationAction {
+ FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init];
+
+ FWFNavigationDelegate *mockDelegate = [self mockNavigationDelegateWithManager:instanceManager
+ identifier:0];
+ FWFNavigationDelegateFlutterApiImpl *mockFlutterAPI =
+ [self mockFlutterApiWithManager:instanceManager];
+
+ OCMStub([mockDelegate navigationDelegateAPI]).andReturn(mockFlutterAPI);
+
+ WKWebView *mockWebView = OCMClassMock([WKWebView class]);
+ [instanceManager addDartCreatedInstance:mockWebView withIdentifier:1];
+
+ WKNavigationAction *mockNavigationAction = OCMClassMock([WKNavigationAction class]);
+ OCMStub([mockNavigationAction request])
+ .andReturn([NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.flutter.dev"]]);
+
+ WKFrameInfo *mockFrameInfo = OCMClassMock([WKFrameInfo class]);
+ OCMStub([mockFrameInfo isMainFrame]).andReturn(YES);
+ OCMStub([mockNavigationAction targetFrame]).andReturn(mockFrameInfo);
+
+ OCMStub([mockFlutterAPI
+ decidePolicyForNavigationActionForDelegateWithIdentifier:@0
+ webViewIdentifier:@1
+ navigationAction:
+ [OCMArg isKindOfClass:[FWFWKNavigationActionData
+ class]]
+ completion:
+ ([OCMArg
+ invokeBlockWithArgs:
+ [FWFWKNavigationActionPolicyEnumData
+ makeWithValue:
+ FWFWKNavigationActionPolicyEnumCancel],
+ [NSNull null], nil])]);
+
+ WKNavigationActionPolicy __block callbackPolicy = -1;
+ [mockDelegate webView:mockWebView
+ decidePolicyForNavigationAction:mockNavigationAction
+ decisionHandler:^(WKNavigationActionPolicy policy) {
+ callbackPolicy = policy;
+ }];
+ XCTAssertEqual(callbackPolicy, WKNavigationActionPolicyCancel);
+}
+
+- (void)testDidFailNavigation {
+ FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init];
+
+ FWFNavigationDelegate *mockDelegate = [self mockNavigationDelegateWithManager:instanceManager
+ identifier:0];
+ FWFNavigationDelegateFlutterApiImpl *mockFlutterAPI =
+ [self mockFlutterApiWithManager:instanceManager];
+
+ OCMStub([mockDelegate navigationDelegateAPI]).andReturn(mockFlutterAPI);
+
+ WKWebView *mockWebView = OCMClassMock([WKWebView class]);
+ [instanceManager addDartCreatedInstance:mockWebView withIdentifier:1];
+
+ [mockDelegate webView:mockWebView
+ didFailNavigation:OCMClassMock([WKNavigation class])
+ withError:[NSError errorWithDomain:@"domain" code:0 userInfo:nil]];
+ OCMVerify([mockFlutterAPI
+ didFailNavigationForDelegateWithIdentifier:@0
+ webViewIdentifier:@1
+ error:[OCMArg isKindOfClass:[FWFNSErrorData class]]
+ completion:OCMOCK_ANY]);
+}
+
+- (void)testDidFailProvisionalNavigation {
+ FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init];
+
+ FWFNavigationDelegate *mockDelegate = [self mockNavigationDelegateWithManager:instanceManager
+ identifier:0];
+ FWFNavigationDelegateFlutterApiImpl *mockFlutterAPI =
+ [self mockFlutterApiWithManager:instanceManager];
+
+ OCMStub([mockDelegate navigationDelegateAPI]).andReturn(mockFlutterAPI);
+
+ WKWebView *mockWebView = OCMClassMock([WKWebView class]);
+ [instanceManager addDartCreatedInstance:mockWebView withIdentifier:1];
+
+ [mockDelegate webView:mockWebView
+ didFailProvisionalNavigation:OCMClassMock([WKNavigation class])
+ withError:[NSError errorWithDomain:@"domain" code:0 userInfo:nil]];
+ OCMVerify([mockFlutterAPI
+ didFailProvisionalNavigationForDelegateWithIdentifier:@0
+ webViewIdentifier:@1
+ error:[OCMArg isKindOfClass:[FWFNSErrorData
+ class]]
+ completion:OCMOCK_ANY]);
+}
+
+- (void)testWebViewWebContentProcessDidTerminate {
+ FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init];
+
+ FWFNavigationDelegate *mockDelegate = [self mockNavigationDelegateWithManager:instanceManager
+ identifier:0];
+ FWFNavigationDelegateFlutterApiImpl *mockFlutterAPI =
+ [self mockFlutterApiWithManager:instanceManager];
+
+ OCMStub([mockDelegate navigationDelegateAPI]).andReturn(mockFlutterAPI);
+
+ WKWebView *mockWebView = OCMClassMock([WKWebView class]);
+ [instanceManager addDartCreatedInstance:mockWebView withIdentifier:1];
+
+ [mockDelegate webViewWebContentProcessDidTerminate:mockWebView];
+ OCMVerify([mockFlutterAPI
+ webViewWebContentProcessDidTerminateForDelegateWithIdentifier:@0
+ webViewIdentifier:@1
+ completion:OCMOCK_ANY]);
+}
@end
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFObjectHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFObjectHostApiTests.m
index bdaeae4c09dc..b8e41d142331 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFObjectHostApiTests.m
+++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFObjectHostApiTests.m
@@ -12,6 +12,37 @@ @interface FWFObjectHostApiTests : XCTestCase
@end
@implementation FWFObjectHostApiTests
+/**
+ * Creates a partially mocked FWFObject and adds it to instanceManager.
+ *
+ * @param instanceManager Instance manager to add the delegate to.
+ * @param identifier Identifier for the delegate added to the instanceManager.
+ *
+ * @return A mock FWFObject.
+ */
+- (id)mockObjectWithManager:(FWFInstanceManager *)instanceManager identifier:(long)identifier {
+ FWFObject *object =
+ [[FWFObject alloc] initWithBinaryMessenger:OCMProtocolMock(@protocol(FlutterBinaryMessenger))
+ instanceManager:instanceManager];
+
+ [instanceManager addDartCreatedInstance:object withIdentifier:0];
+ return OCMPartialMock(object);
+}
+
+/**
+ * Creates a mock FWFObjectFlutterApiImpl with instanceManager.
+ *
+ * @param instanceManager Instance manager passed to the Flutter API.
+ *
+ * @return A mock FWFObjectFlutterApiImpl.
+ */
+- (id)mockFlutterApiWithManager:(FWFInstanceManager *)instanceManager {
+ FWFObjectFlutterApiImpl *flutterAPI = [[FWFObjectFlutterApiImpl alloc]
+ initWithBinaryMessenger:OCMProtocolMock(@protocol(FlutterBinaryMessenger))
+ instanceManager:instanceManager];
+ return OCMPartialMock(flutterAPI);
+}
+
- (void)testAddObserver {
NSObject *mockObject = OCMClassMock([NSObject class]);
@@ -82,4 +113,34 @@ - (void)testDispose {
XCTAssertFalse([instanceManager containsInstance:object]);
XCTAssertNil(error);
}
+
+- (void)testObserveValueForKeyPath {
+ FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init];
+
+ FWFObject *mockObject = [self mockObjectWithManager:instanceManager identifier:0];
+ FWFObjectFlutterApiImpl *mockFlutterAPI = [self mockFlutterApiWithManager:instanceManager];
+
+ OCMStub([mockObject objectApi]).andReturn(mockFlutterAPI);
+
+ NSObject *object = [[NSObject alloc] init];
+ [instanceManager addDartCreatedInstance:object withIdentifier:1];
+
+ [mockObject observeValueForKeyPath:@"keyPath"
+ ofObject:object
+ change:@{NSKeyValueChangeOldKey : @"key"}
+ context:nil];
+ OCMVerify([mockFlutterAPI
+ observeValueForObjectWithIdentifier:@0
+ keyPath:@"keyPath"
+ objectIdentifier:@1
+ changeKeys:[OCMArg checkWithBlock:^BOOL(
+ NSArray
+ *value) {
+ return value[0].value == FWFNSKeyValueChangeKeyEnumOldValue;
+ }]
+ changeValues:[OCMArg checkWithBlock:^BOOL(id value) {
+ return [@"key" isEqual:value[0]];
+ }]
+ completion:OCMOCK_ANY]);
+}
@end
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFScriptMessageHandlerHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFScriptMessageHandlerHostApiTests.m
index b74d21114cc4..5a51e7b980f8 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFScriptMessageHandlerHostApiTests.m
+++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFScriptMessageHandlerHostApiTests.m
@@ -12,6 +12,37 @@ @interface FWFScriptMessageHandlerHostApiTests : XCTestCase
@end
@implementation FWFScriptMessageHandlerHostApiTests
+/**
+ * Creates a partially mocked FWFScriptMessageHandler and adds it to instanceManager.
+ *
+ * @param instanceManager Instance manager to add the delegate to.
+ * @param identifier Identifier for the delegate added to the instanceManager.
+ *
+ * @return A mock FWFScriptMessageHandler.
+ */
+- (id)mockHandlerWithManager:(FWFInstanceManager *)instanceManager identifier:(long)identifier {
+ FWFScriptMessageHandler *handler = [[FWFScriptMessageHandler alloc]
+ initWithBinaryMessenger:OCMProtocolMock(@protocol(FlutterBinaryMessenger))
+ instanceManager:instanceManager];
+
+ [instanceManager addDartCreatedInstance:handler withIdentifier:0];
+ return OCMPartialMock(handler);
+}
+
+/**
+ * Creates a mock FWFScriptMessageHandlerFlutterApiImpl with instanceManager.
+ *
+ * @param instanceManager Instance manager passed to the Flutter API.
+ *
+ * @return A mock FWFScriptMessageHandlerFlutterApiImpl.
+ */
+- (id)mockFlutterApiWithManager:(FWFInstanceManager *)instanceManager {
+ FWFScriptMessageHandlerFlutterApiImpl *flutterAPI = [[FWFScriptMessageHandlerFlutterApiImpl alloc]
+ initWithBinaryMessenger:OCMProtocolMock(@protocol(FlutterBinaryMessenger))
+ instanceManager:instanceManager];
+ return OCMPartialMock(flutterAPI);
+}
+
- (void)testCreateWithIdentifier {
FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init];
FWFScriptMessageHandlerHostApiImpl *hostAPI =
@@ -26,4 +57,30 @@ - (void)testCreateWithIdentifier {
XCTAssertTrue([scriptMessageHandler conformsToProtocol:@protocol(WKScriptMessageHandler)]);
XCTAssertNil(error);
}
+
+- (void)testDidReceiveScriptMessageForHandler {
+ FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init];
+
+ FWFScriptMessageHandler *mockHandler = [self mockHandlerWithManager:instanceManager identifier:0];
+ FWFScriptMessageHandlerFlutterApiImpl *mockFlutterAPI =
+ [self mockFlutterApiWithManager:instanceManager];
+
+ OCMStub([mockHandler scriptMessageHandlerAPI]).andReturn(mockFlutterAPI);
+
+ WKUserContentController *userContentController = [[WKUserContentController alloc] init];
+ [instanceManager addDartCreatedInstance:userContentController withIdentifier:1];
+
+ WKScriptMessage *mockScriptMessage = OCMClassMock([WKScriptMessage class]);
+ OCMStub([mockScriptMessage name]).andReturn(@"name");
+ OCMStub([mockScriptMessage body]).andReturn(@"message");
+
+ [mockHandler userContentController:userContentController
+ didReceiveScriptMessage:mockScriptMessage];
+ OCMVerify([mockFlutterAPI
+ didReceiveScriptMessageForHandlerWithIdentifier:@0
+ userContentControllerIdentifier:@1
+ message:[OCMArg isKindOfClass:[FWFWKScriptMessageData
+ class]]
+ completion:OCMOCK_ANY]);
+}
@end
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFUIDelegateHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFUIDelegateHostApiTests.m
index 4ee36ae7c492..17cb4367b3aa 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFUIDelegateHostApiTests.m
+++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFUIDelegateHostApiTests.m
@@ -12,6 +12,37 @@ @interface FWFUIDelegateHostApiTests : XCTestCase
@end
@implementation FWFUIDelegateHostApiTests
+/**
+ * Creates a partially mocked FWFUIDelegate and adds it to instanceManager.
+ *
+ * @param instanceManager Instance manager to add the delegate to.
+ * @param identifier Identifier for the delegate added to the instanceManager.
+ *
+ * @return A mock FWFUIDelegate.
+ */
+- (id)mockDelegateWithManager:(FWFInstanceManager *)instanceManager identifier:(long)identifier {
+ FWFUIDelegate *delegate = [[FWFUIDelegate alloc]
+ initWithBinaryMessenger:OCMProtocolMock(@protocol(FlutterBinaryMessenger))
+ instanceManager:instanceManager];
+
+ [instanceManager addDartCreatedInstance:delegate withIdentifier:0];
+ return OCMPartialMock(delegate);
+}
+
+/**
+ * Creates a mock FWFUIDelegateFlutterApiImpl with instanceManager.
+ *
+ * @param instanceManager Instance manager passed to the Flutter API.
+ *
+ * @return A mock FWFUIDelegateFlutterApiImpl.
+ */
+- (id)mockFlutterApiWithManager:(FWFInstanceManager *)instanceManager {
+ FWFUIDelegateFlutterApiImpl *flutterAPI = [[FWFUIDelegateFlutterApiImpl alloc]
+ initWithBinaryMessenger:OCMProtocolMock(@protocol(FlutterBinaryMessenger))
+ instanceManager:instanceManager];
+ return OCMPartialMock(flutterAPI);
+}
+
- (void)testCreateWithIdentifier {
FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init];
FWFUIDelegateHostApiImpl *hostAPI =
@@ -24,4 +55,39 @@ - (void)testCreateWithIdentifier {
XCTAssertTrue([delegate conformsToProtocol:@protocol(WKUIDelegate)]);
XCTAssertNil(error);
}
+
+- (void)testOnCreateWebViewForDelegateWithIdentifier {
+ FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init];
+
+ FWFUIDelegate *mockDelegate = [self mockDelegateWithManager:instanceManager identifier:0];
+ FWFUIDelegateFlutterApiImpl *mockFlutterAPI = [self mockFlutterApiWithManager:instanceManager];
+
+ OCMStub([mockDelegate UIDelegateAPI]).andReturn(mockFlutterAPI);
+
+ WKWebView *mockWebView = OCMClassMock([WKWebView class]);
+ [instanceManager addDartCreatedInstance:mockWebView withIdentifier:1];
+
+ WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
+ [instanceManager addDartCreatedInstance:configuration withIdentifier:2];
+
+ WKNavigationAction *mockNavigationAction = OCMClassMock([WKNavigationAction class]);
+ OCMStub([mockNavigationAction request])
+ .andReturn([NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.flutter.dev"]]);
+
+ WKFrameInfo *mockFrameInfo = OCMClassMock([WKFrameInfo class]);
+ OCMStub([mockFrameInfo isMainFrame]).andReturn(YES);
+ OCMStub([mockNavigationAction targetFrame]).andReturn(mockFrameInfo);
+
+ [mockDelegate webView:mockWebView
+ createWebViewWithConfiguration:configuration
+ forNavigationAction:mockNavigationAction
+ windowFeatures:OCMClassMock([WKWindowFeatures class])];
+ OCMVerify([mockFlutterAPI
+ onCreateWebViewForDelegateWithIdentifier:@0
+ webViewIdentifier:@1
+ configurationIdentifier:@2
+ navigationAction:[OCMArg
+ isKindOfClass:[FWFWKNavigationActionData class]]
+ completion:OCMOCK_ANY]);
+}
@end
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFDataConverters.h b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFDataConverters.h
index 4cf24c67ac95..2863048726a9 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFDataConverters.h
+++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFDataConverters.h
@@ -85,4 +85,70 @@ extern WKAudiovisualMediaTypes FWFWKAudiovisualMediaTypeFromEnumData(
*/
extern NSString *_Nullable FWFWKWebsiteDataTypeFromEnumData(FWFWKWebsiteDataTypeEnumData *data);
+/**
+ * Converts a WKNavigationAction to an FWFWKNavigationActionData.
+ *
+ * @param action The object containing information to create a WKNavigationActionData.
+ *
+ * @return A FWFWKNavigationActionData.
+ */
+extern FWFWKNavigationActionData *FWFWKNavigationActionDataFromNavigationAction(
+ WKNavigationAction *action);
+
+/**
+ * Converts a NSURLRequest to an FWFNSUrlRequestData.
+ *
+ * @param request The object containing information to create a WKNavigationActionData.
+ *
+ * @return A FWFNSUrlRequestData.
+ */
+extern FWFNSUrlRequestData *FWFNSUrlRequestDataFromNSURLRequest(NSURLRequest *request);
+
+/**
+ * Converts a WKFrameInfo to an FWFWKFrameInfoData.
+ *
+ * @param info The object containing information to create a FWFWKFrameInfoData.
+ *
+ * @return A FWFWKFrameInfoData.
+ */
+extern FWFWKFrameInfoData *FWFWKFrameInfoDataFromWKFrameInfo(WKFrameInfo *info);
+
+/**
+ * Converts an FWFWKNavigationActionPolicyEnumData to a WKNavigationActionPolicy.
+ *
+ * @param data The data object containing information to create a WKNavigationActionPolicy.
+ *
+ * @return A WKNavigationActionPolicy or -1 if data could not be converted.
+ */
+extern WKNavigationActionPolicy FWFWKNavigationActionPolicyFromEnumData(
+ FWFWKNavigationActionPolicyEnumData *data);
+
+/**
+ * Converts a NSError to an FWFNSErrorData.
+ *
+ * @param error The object containing information to create a FWFNSErrorData.
+ *
+ * @return A FWFNSErrorData.
+ */
+extern FWFNSErrorData *FWFNSErrorDataFromNSError(NSError *error);
+
+/**
+ * Converts an NSKeyValueChangeKey to a FWFNSKeyValueChangeKeyEnumData.
+ *
+ * @param key The data object containing information to create a FWFNSKeyValueChangeKeyEnumData.
+ *
+ * @return A FWFNSKeyValueChangeKeyEnumData or nil if data could not be converted.
+ */
+extern FWFNSKeyValueChangeKeyEnumData *FWFNSKeyValueChangeKeyEnumDataFromNSKeyValueChangeKey(
+ NSKeyValueChangeKey key);
+
+/**
+ * Converts a WKScriptMessage to an FWFWKScriptMessageData.
+ *
+ * @param message The object containing information to create a FWFWKScriptMessageData.
+ *
+ * @return A FWFWKScriptMessageData.
+ */
+extern FWFWKScriptMessageData *FWFWKScriptMessageDataFromWKScriptMessage(WKScriptMessage *message);
+
NS_ASSUME_NONNULL_END
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFDataConverters.m b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFDataConverters.m
index a06b3d79b38c..759bfedc1621 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFDataConverters.m
+++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFDataConverters.m
@@ -153,3 +153,64 @@ WKAudiovisualMediaTypes FWFWKAudiovisualMediaTypeFromEnumData(
return nil;
}
+
+FWFWKNavigationActionData *FWFWKNavigationActionDataFromNavigationAction(
+ WKNavigationAction *action) {
+ return [FWFWKNavigationActionData
+ makeWithRequest:FWFNSUrlRequestDataFromNSURLRequest(action.request)
+ targetFrame:FWFWKFrameInfoDataFromWKFrameInfo(action.targetFrame)];
+}
+
+FWFNSUrlRequestData *FWFNSUrlRequestDataFromNSURLRequest(NSURLRequest *request) {
+ return [FWFNSUrlRequestData
+ makeWithUrl:request.URL.absoluteString
+ httpMethod:request.HTTPMethod
+ httpBody:request.HTTPBody
+ ? [FlutterStandardTypedData typedDataWithBytes:request.HTTPBody]
+ : nil
+ allHttpHeaderFields:request.allHTTPHeaderFields ? request.allHTTPHeaderFields : @{}];
+}
+
+FWFWKFrameInfoData *FWFWKFrameInfoDataFromWKFrameInfo(WKFrameInfo *info) {
+ return [FWFWKFrameInfoData makeWithIsMainFrame:@(info.isMainFrame)];
+}
+
+WKNavigationActionPolicy FWFWKNavigationActionPolicyFromEnumData(
+ FWFWKNavigationActionPolicyEnumData *data) {
+ switch (data.value) {
+ case FWFWKNavigationActionPolicyEnumAllow:
+ return WKNavigationActionPolicyAllow;
+ case FWFWKNavigationActionPolicyEnumCancel:
+ return WKNavigationActionPolicyCancel;
+ }
+
+ return -1;
+}
+
+FWFNSErrorData *FWFNSErrorDataFromNSError(NSError *error) {
+ return [FWFNSErrorData makeWithCode:@(error.code)
+ domain:error.domain
+ localizedDescription:error.localizedDescription];
+}
+
+FWFNSKeyValueChangeKeyEnumData *FWFNSKeyValueChangeKeyEnumDataFromNSKeyValueChangeKey(
+ NSKeyValueChangeKey key) {
+ if ([key isEqualToString:NSKeyValueChangeIndexesKey]) {
+ return [FWFNSKeyValueChangeKeyEnumData makeWithValue:FWFNSKeyValueChangeKeyEnumIndexes];
+ } else if ([key isEqualToString:NSKeyValueChangeKindKey]) {
+ return [FWFNSKeyValueChangeKeyEnumData makeWithValue:FWFNSKeyValueChangeKeyEnumKind];
+ } else if ([key isEqualToString:NSKeyValueChangeNewKey]) {
+ return [FWFNSKeyValueChangeKeyEnumData makeWithValue:FWFNSKeyValueChangeKeyEnumNewValue];
+ } else if ([key isEqualToString:NSKeyValueChangeNotificationIsPriorKey]) {
+ return [FWFNSKeyValueChangeKeyEnumData
+ makeWithValue:FWFNSKeyValueChangeKeyEnumNotificationIsPrior];
+ } else if ([key isEqualToString:NSKeyValueChangeOldKey]) {
+ return [FWFNSKeyValueChangeKeyEnumData makeWithValue:FWFNSKeyValueChangeKeyEnumOldValue];
+ }
+
+ return nil;
+}
+
+FWFWKScriptMessageData *FWFWKScriptMessageDataFromWKScriptMessage(WKScriptMessage *message) {
+ return [FWFWKScriptMessageData makeWithName:message.name body:message.body];
+}
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.h b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.h
index b291f4167725..ebd29f5cacad 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.h
+++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.h
@@ -1,7 +1,7 @@
// 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.
-// Autogenerated from Pigeon (v3.1.2), do not edit directly.
+// Autogenerated from Pigeon (v3.1.4), do not edit directly.
// See also: https://pub.dev/packages/pigeon
#import
@protocol FlutterBinaryMessenger;
@@ -79,12 +79,18 @@ typedef NS_ENUM(NSUInteger, FWFNSHttpCookiePropertyKeyEnum) {
};
@class FWFNSKeyValueObservingOptionsEnumData;
+@class FWFNSKeyValueChangeKeyEnumData;
@class FWFWKUserScriptInjectionTimeEnumData;
@class FWFWKAudiovisualMediaTypeEnumData;
@class FWFWKWebsiteDataTypeEnumData;
+@class FWFWKNavigationActionPolicyEnumData;
@class FWFNSHttpCookiePropertyKeyEnumData;
@class FWFNSUrlRequestData;
@class FWFWKUserScriptData;
+@class FWFWKNavigationActionData;
+@class FWFWKFrameInfoData;
+@class FWFNSErrorData;
+@class FWFWKScriptMessageData;
@class FWFNSHttpCookieData;
@interface FWFNSKeyValueObservingOptionsEnumData : NSObject
@@ -94,6 +100,13 @@ typedef NS_ENUM(NSUInteger, FWFNSHttpCookiePropertyKeyEnum) {
@property(nonatomic, assign) FWFNSKeyValueObservingOptionsEnum value;
@end
+@interface FWFNSKeyValueChangeKeyEnumData : NSObject
+/// `init` unavailable to enforce nonnull fields, see the `make` class method.
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)makeWithValue:(FWFNSKeyValueChangeKeyEnum)value;
+@property(nonatomic, assign) FWFNSKeyValueChangeKeyEnum value;
+@end
+
@interface FWFWKUserScriptInjectionTimeEnumData : NSObject
/// `init` unavailable to enforce nonnull fields, see the `make` class method.
- (instancetype)init NS_UNAVAILABLE;
@@ -115,6 +128,13 @@ typedef NS_ENUM(NSUInteger, FWFNSHttpCookiePropertyKeyEnum) {
@property(nonatomic, assign) FWFWKWebsiteDataTypeEnum value;
@end
+@interface FWFWKNavigationActionPolicyEnumData : NSObject
+/// `init` unavailable to enforce nonnull fields, see the `make` class method.
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)makeWithValue:(FWFWKNavigationActionPolicyEnum)value;
+@property(nonatomic, assign) FWFWKNavigationActionPolicyEnum value;
+@end
+
@interface FWFNSHttpCookiePropertyKeyEnumData : NSObject
/// `init` unavailable to enforce nonnull fields, see the `make` class method.
- (instancetype)init NS_UNAVAILABLE;
@@ -146,6 +166,41 @@ typedef NS_ENUM(NSUInteger, FWFNSHttpCookiePropertyKeyEnum) {
@property(nonatomic, strong) NSNumber *isMainFrameOnly;
@end
+@interface FWFWKNavigationActionData : NSObject
+/// `init` unavailable to enforce nonnull fields, see the `make` class method.
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)makeWithRequest:(FWFNSUrlRequestData *)request
+ targetFrame:(FWFWKFrameInfoData *)targetFrame;
+@property(nonatomic, strong) FWFNSUrlRequestData *request;
+@property(nonatomic, strong) FWFWKFrameInfoData *targetFrame;
+@end
+
+@interface FWFWKFrameInfoData : NSObject
+/// `init` unavailable to enforce nonnull fields, see the `make` class method.
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)makeWithIsMainFrame:(NSNumber *)isMainFrame;
+@property(nonatomic, strong) NSNumber *isMainFrame;
+@end
+
+@interface FWFNSErrorData : NSObject
+/// `init` unavailable to enforce nonnull fields, see the `make` class method.
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)makeWithCode:(NSNumber *)code
+ domain:(NSString *)domain
+ localizedDescription:(NSString *)localizedDescription;
+@property(nonatomic, strong) NSNumber *code;
+@property(nonatomic, copy) NSString *domain;
+@property(nonatomic, copy) NSString *localizedDescription;
+@end
+
+@interface FWFWKScriptMessageData : NSObject
+/// `init` unavailable to enforce nonnull fields, see the `make` class method.
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)makeWithName:(NSString *)name body:(id)body;
+@property(nonatomic, copy) NSString *name;
+@property(nonatomic, strong) id body;
+@end
+
@interface FWFNSHttpCookieData : NSObject
/// `init` unavailable to enforce nonnull fields, see the `make` class method.
- (instancetype)init NS_UNAVAILABLE;
@@ -298,6 +353,16 @@ extern void FWFWKScriptMessageHandlerHostApiSetup(
id binaryMessenger,
NSObject *_Nullable api);
+/// The codec used by FWFWKScriptMessageHandlerFlutterApi.
+NSObject *FWFWKScriptMessageHandlerFlutterApiGetCodec(void);
+
+@interface FWFWKScriptMessageHandlerFlutterApi : NSObject
+- (instancetype)initWithBinaryMessenger:(id)binaryMessenger;
+- (void)didReceiveScriptMessageForHandlerWithIdentifier:(NSNumber *)identifier
+ userContentControllerIdentifier:(NSNumber *)userContentControllerIdentifier
+ message:(FWFWKScriptMessageData *)message
+ completion:(void (^)(NSError *_Nullable))completion;
+@end
/// The codec used by FWFWKNavigationDelegateHostApi.
NSObject *FWFWKNavigationDelegateHostApiGetCodec(void);
@@ -318,6 +383,33 @@ NSObject *FWFWKNavigationDelegateFlutterApiGetCodec(void);
webViewIdentifier:(NSNumber *)webViewIdentifier
URL:(nullable NSString *)url
completion:(void (^)(NSError *_Nullable))completion;
+- (void)didStartProvisionalNavigationForDelegateWithIdentifier:(NSNumber *)identifier
+ webViewIdentifier:(NSNumber *)webViewIdentifier
+ URL:(nullable NSString *)url
+ completion:
+ (void (^)(NSError *_Nullable))completion;
+- (void)
+ decidePolicyForNavigationActionForDelegateWithIdentifier:(NSNumber *)identifier
+ webViewIdentifier:(NSNumber *)webViewIdentifier
+ navigationAction:
+ (FWFWKNavigationActionData *)navigationAction
+ completion:
+ (void (^)(FWFWKNavigationActionPolicyEnumData
+ *_Nullable,
+ NSError *_Nullable))completion;
+- (void)didFailNavigationForDelegateWithIdentifier:(NSNumber *)identifier
+ webViewIdentifier:(NSNumber *)webViewIdentifier
+ error:(FWFNSErrorData *)error
+ completion:(void (^)(NSError *_Nullable))completion;
+- (void)didFailProvisionalNavigationForDelegateWithIdentifier:(NSNumber *)identifier
+ webViewIdentifier:(NSNumber *)webViewIdentifier
+ error:(FWFNSErrorData *)error
+ completion:
+ (void (^)(NSError *_Nullable))completion;
+- (void)webViewWebContentProcessDidTerminateForDelegateWithIdentifier:(NSNumber *)identifier
+ webViewIdentifier:(NSNumber *)webViewIdentifier
+ completion:(void (^)(NSError *_Nullable))
+ completion;
@end
/// The codec used by FWFNSObjectHostApi.
NSObject *FWFNSObjectHostApiGetCodec(void);
@@ -345,6 +437,12 @@ NSObject *FWFNSObjectFlutterApiGetCodec(void);
@interface FWFNSObjectFlutterApi : NSObject
- (instancetype)initWithBinaryMessenger:(id)binaryMessenger;
+- (void)observeValueForObjectWithIdentifier:(NSNumber *)identifier
+ keyPath:(NSString *)keyPath
+ objectIdentifier:(NSNumber *)objectIdentifier
+ changeKeys:(NSArray *)changeKeys
+ changeValues:(NSArray *)changeValues
+ completion:(void (^)(NSError *_Nullable))completion;
@end
/// The codec used by FWFWKWebViewHostApi.
NSObject *FWFWKWebViewHostApiGetCodec(void);
@@ -420,6 +518,17 @@ NSObject *FWFWKUIDelegateHostApiGetCodec(void);
extern void FWFWKUIDelegateHostApiSetup(id binaryMessenger,
NSObject *_Nullable api);
+/// The codec used by FWFWKUIDelegateFlutterApi.
+NSObject *FWFWKUIDelegateFlutterApiGetCodec(void);
+
+@interface FWFWKUIDelegateFlutterApi : NSObject
+- (instancetype)initWithBinaryMessenger:(id)binaryMessenger;
+- (void)onCreateWebViewForDelegateWithIdentifier:(NSNumber *)identifier
+ webViewIdentifier:(NSNumber *)webViewIdentifier
+ configurationIdentifier:(NSNumber *)configurationIdentifier
+ navigationAction:(FWFWKNavigationActionData *)navigationAction
+ completion:(void (^)(NSError *_Nullable))completion;
+@end
/// The codec used by FWFWKHttpCookieStoreHostApi.
NSObject *FWFWKHttpCookieStoreHostApiGetCodec(void);
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.m b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.m
index f936d151ddd3..592fa87ac9d1 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.m
+++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.m
@@ -1,7 +1,7 @@
// 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.
-// Autogenerated from Pigeon (v3.1.2), do not edit directly.
+// Autogenerated from Pigeon (v3.1.4), do not edit directly.
// See also: https://pub.dev/packages/pigeon
#import "FWFGeneratedWebKitApis.h"
#import
@@ -37,6 +37,10 @@ @interface FWFNSKeyValueObservingOptionsEnumData ()
+ (FWFNSKeyValueObservingOptionsEnumData *)fromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
+@interface FWFNSKeyValueChangeKeyEnumData ()
++ (FWFNSKeyValueChangeKeyEnumData *)fromMap:(NSDictionary *)dict;
+- (NSDictionary *)toMap;
+@end
@interface FWFWKUserScriptInjectionTimeEnumData ()
+ (FWFWKUserScriptInjectionTimeEnumData *)fromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@@ -49,6 +53,10 @@ @interface FWFWKWebsiteDataTypeEnumData ()
+ (FWFWKWebsiteDataTypeEnumData *)fromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
+@interface FWFWKNavigationActionPolicyEnumData ()
++ (FWFWKNavigationActionPolicyEnumData *)fromMap:(NSDictionary *)dict;
+- (NSDictionary *)toMap;
+@end
@interface FWFNSHttpCookiePropertyKeyEnumData ()
+ (FWFNSHttpCookiePropertyKeyEnumData *)fromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@@ -61,6 +69,22 @@ @interface FWFWKUserScriptData ()
+ (FWFWKUserScriptData *)fromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
+@interface FWFWKNavigationActionData ()
++ (FWFWKNavigationActionData *)fromMap:(NSDictionary *)dict;
+- (NSDictionary *)toMap;
+@end
+@interface FWFWKFrameInfoData ()
++ (FWFWKFrameInfoData *)fromMap:(NSDictionary *)dict;
+- (NSDictionary *)toMap;
+@end
+@interface FWFNSErrorData ()
++ (FWFNSErrorData *)fromMap:(NSDictionary *)dict;
+- (NSDictionary *)toMap;
+@end
+@interface FWFWKScriptMessageData ()
++ (FWFWKScriptMessageData *)fromMap:(NSDictionary *)dict;
+- (NSDictionary *)toMap;
+@end
@interface FWFNSHttpCookieData ()
+ (FWFNSHttpCookieData *)fromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@@ -86,6 +110,24 @@ - (NSDictionary *)toMap {
}
@end
+@implementation FWFNSKeyValueChangeKeyEnumData
++ (instancetype)makeWithValue:(FWFNSKeyValueChangeKeyEnum)value {
+ FWFNSKeyValueChangeKeyEnumData *pigeonResult = [[FWFNSKeyValueChangeKeyEnumData alloc] init];
+ pigeonResult.value = value;
+ return pigeonResult;
+}
++ (FWFNSKeyValueChangeKeyEnumData *)fromMap:(NSDictionary *)dict {
+ FWFNSKeyValueChangeKeyEnumData *pigeonResult = [[FWFNSKeyValueChangeKeyEnumData alloc] init];
+ pigeonResult.value = [GetNullableObject(dict, @"value") integerValue];
+ return pigeonResult;
+}
+- (NSDictionary *)toMap {
+ return @{
+ @"value" : @(self.value),
+ };
+}
+@end
+
@implementation FWFWKUserScriptInjectionTimeEnumData
+ (instancetype)makeWithValue:(FWFWKUserScriptInjectionTimeEnum)value {
FWFWKUserScriptInjectionTimeEnumData *pigeonResult =
@@ -144,6 +186,26 @@ - (NSDictionary *)toMap {
}
@end
+@implementation FWFWKNavigationActionPolicyEnumData
++ (instancetype)makeWithValue:(FWFWKNavigationActionPolicyEnum)value {
+ FWFWKNavigationActionPolicyEnumData *pigeonResult =
+ [[FWFWKNavigationActionPolicyEnumData alloc] init];
+ pigeonResult.value = value;
+ return pigeonResult;
+}
++ (FWFWKNavigationActionPolicyEnumData *)fromMap:(NSDictionary *)dict {
+ FWFWKNavigationActionPolicyEnumData *pigeonResult =
+ [[FWFWKNavigationActionPolicyEnumData alloc] init];
+ pigeonResult.value = [GetNullableObject(dict, @"value") integerValue];
+ return pigeonResult;
+}
+- (NSDictionary *)toMap {
+ return @{
+ @"value" : @(self.value),
+ };
+}
+@end
+
@implementation FWFNSHttpCookiePropertyKeyEnumData
+ (instancetype)makeWithValue:(FWFNSHttpCookiePropertyKeyEnum)value {
FWFNSHttpCookiePropertyKeyEnumData *pigeonResult =
@@ -225,6 +287,100 @@ - (NSDictionary *)toMap {
}
@end
+@implementation FWFWKNavigationActionData
++ (instancetype)makeWithRequest:(FWFNSUrlRequestData *)request
+ targetFrame:(FWFWKFrameInfoData *)targetFrame {
+ FWFWKNavigationActionData *pigeonResult = [[FWFWKNavigationActionData alloc] init];
+ pigeonResult.request = request;
+ pigeonResult.targetFrame = targetFrame;
+ return pigeonResult;
+}
++ (FWFWKNavigationActionData *)fromMap:(NSDictionary *)dict {
+ FWFWKNavigationActionData *pigeonResult = [[FWFWKNavigationActionData alloc] init];
+ pigeonResult.request = [FWFNSUrlRequestData fromMap:GetNullableObject(dict, @"request")];
+ NSAssert(pigeonResult.request != nil, @"");
+ pigeonResult.targetFrame = [FWFWKFrameInfoData fromMap:GetNullableObject(dict, @"targetFrame")];
+ NSAssert(pigeonResult.targetFrame != nil, @"");
+ return pigeonResult;
+}
+- (NSDictionary *)toMap {
+ return @{
+ @"request" : (self.request ? [self.request toMap] : [NSNull null]),
+ @"targetFrame" : (self.targetFrame ? [self.targetFrame toMap] : [NSNull null]),
+ };
+}
+@end
+
+@implementation FWFWKFrameInfoData
++ (instancetype)makeWithIsMainFrame:(NSNumber *)isMainFrame {
+ FWFWKFrameInfoData *pigeonResult = [[FWFWKFrameInfoData alloc] init];
+ pigeonResult.isMainFrame = isMainFrame;
+ return pigeonResult;
+}
++ (FWFWKFrameInfoData *)fromMap:(NSDictionary *)dict {
+ FWFWKFrameInfoData *pigeonResult = [[FWFWKFrameInfoData alloc] init];
+ pigeonResult.isMainFrame = GetNullableObject(dict, @"isMainFrame");
+ NSAssert(pigeonResult.isMainFrame != nil, @"");
+ return pigeonResult;
+}
+- (NSDictionary *)toMap {
+ return @{
+ @"isMainFrame" : (self.isMainFrame ?: [NSNull null]),
+ };
+}
+@end
+
+@implementation FWFNSErrorData
++ (instancetype)makeWithCode:(NSNumber *)code
+ domain:(NSString *)domain
+ localizedDescription:(NSString *)localizedDescription {
+ FWFNSErrorData *pigeonResult = [[FWFNSErrorData alloc] init];
+ pigeonResult.code = code;
+ pigeonResult.domain = domain;
+ pigeonResult.localizedDescription = localizedDescription;
+ return pigeonResult;
+}
++ (FWFNSErrorData *)fromMap:(NSDictionary *)dict {
+ FWFNSErrorData *pigeonResult = [[FWFNSErrorData alloc] init];
+ pigeonResult.code = GetNullableObject(dict, @"code");
+ NSAssert(pigeonResult.code != nil, @"");
+ pigeonResult.domain = GetNullableObject(dict, @"domain");
+ NSAssert(pigeonResult.domain != nil, @"");
+ pigeonResult.localizedDescription = GetNullableObject(dict, @"localizedDescription");
+ NSAssert(pigeonResult.localizedDescription != nil, @"");
+ return pigeonResult;
+}
+- (NSDictionary *)toMap {
+ return @{
+ @"code" : (self.code ?: [NSNull null]),
+ @"domain" : (self.domain ?: [NSNull null]),
+ @"localizedDescription" : (self.localizedDescription ?: [NSNull null]),
+ };
+}
+@end
+
+@implementation FWFWKScriptMessageData
++ (instancetype)makeWithName:(NSString *)name body:(id)body {
+ FWFWKScriptMessageData *pigeonResult = [[FWFWKScriptMessageData alloc] init];
+ pigeonResult.name = name;
+ pigeonResult.body = body;
+ return pigeonResult;
+}
++ (FWFWKScriptMessageData *)fromMap:(NSDictionary *)dict {
+ FWFWKScriptMessageData *pigeonResult = [[FWFWKScriptMessageData alloc] init];
+ pigeonResult.name = GetNullableObject(dict, @"name");
+ NSAssert(pigeonResult.name != nil, @"");
+ pigeonResult.body = GetNullableObject(dict, @"body");
+ return pigeonResult;
+}
+- (NSDictionary *)toMap {
+ return @{
+ @"name" : (self.name ?: [NSNull null]),
+ @"body" : (self.body ?: [NSNull null]),
+ };
+}
+@end
+
@implementation FWFNSHttpCookieData
+ (instancetype)makeWithPropertyKeys:(NSArray *)propertyKeys
propertyValues:(NSArray *)propertyValues {
@@ -1095,6 +1251,87 @@ void FWFWKScriptMessageHandlerHostApiSetup(id binaryMess
}
}
}
+@interface FWFWKScriptMessageHandlerFlutterApiCodecReader : FlutterStandardReader
+@end
+@implementation FWFWKScriptMessageHandlerFlutterApiCodecReader
+- (nullable id)readValueOfType:(UInt8)type {
+ switch (type) {
+ case 128:
+ return [FWFWKScriptMessageData fromMap:[self readValue]];
+
+ default:
+ return [super readValueOfType:type];
+ }
+}
+@end
+
+@interface FWFWKScriptMessageHandlerFlutterApiCodecWriter : FlutterStandardWriter
+@end
+@implementation FWFWKScriptMessageHandlerFlutterApiCodecWriter
+- (void)writeValue:(id)value {
+ if ([value isKindOfClass:[FWFWKScriptMessageData class]]) {
+ [self writeByte:128];
+ [self writeValue:[value toMap]];
+ } else {
+ [super writeValue:value];
+ }
+}
+@end
+
+@interface FWFWKScriptMessageHandlerFlutterApiCodecReaderWriter : FlutterStandardReaderWriter
+@end
+@implementation FWFWKScriptMessageHandlerFlutterApiCodecReaderWriter
+- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
+ return [[FWFWKScriptMessageHandlerFlutterApiCodecWriter alloc] initWithData:data];
+}
+- (FlutterStandardReader *)readerWithData:(NSData *)data {
+ return [[FWFWKScriptMessageHandlerFlutterApiCodecReader alloc] initWithData:data];
+}
+@end
+
+NSObject *FWFWKScriptMessageHandlerFlutterApiGetCodec() {
+ static dispatch_once_t sPred = 0;
+ static FlutterStandardMessageCodec *sSharedObject = nil;
+ dispatch_once(&sPred, ^{
+ FWFWKScriptMessageHandlerFlutterApiCodecReaderWriter *readerWriter =
+ [[FWFWKScriptMessageHandlerFlutterApiCodecReaderWriter alloc] init];
+ sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
+ });
+ return sSharedObject;
+}
+
+@interface FWFWKScriptMessageHandlerFlutterApi ()
+@property(nonatomic, strong) NSObject *binaryMessenger;
+@end
+
+@implementation FWFWKScriptMessageHandlerFlutterApi
+
+- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger {
+ self = [super init];
+ if (self) {
+ _binaryMessenger = binaryMessenger;
+ }
+ return self;
+}
+- (void)didReceiveScriptMessageForHandlerWithIdentifier:(NSNumber *)arg_identifier
+ userContentControllerIdentifier:
+ (NSNumber *)arg_userContentControllerIdentifier
+ message:(FWFWKScriptMessageData *)arg_message
+ completion:(void (^)(NSError *_Nullable))completion {
+ FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+ messageChannelWithName:
+ @"dev.flutter.pigeon.WKScriptMessageHandlerFlutterApi.didReceiveScriptMessage"
+ binaryMessenger:self.binaryMessenger
+ codec:FWFWKScriptMessageHandlerFlutterApiGetCodec()];
+ [channel sendMessage:@[
+ arg_identifier ?: [NSNull null], arg_userContentControllerIdentifier ?: [NSNull null],
+ arg_message ?: [NSNull null]
+ ]
+ reply:^(id reply) {
+ completion(nil);
+ }];
+}
+@end
@interface FWFWKNavigationDelegateHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKNavigationDelegateHostApiCodecReader
@@ -1154,11 +1391,52 @@ void FWFWKNavigationDelegateHostApiSetup(id binaryMessen
@interface FWFWKNavigationDelegateFlutterApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKNavigationDelegateFlutterApiCodecReader
+- (nullable id)readValueOfType:(UInt8)type {
+ switch (type) {
+ case 128:
+ return [FWFNSErrorData fromMap:[self readValue]];
+
+ case 129:
+ return [FWFNSUrlRequestData fromMap:[self readValue]];
+
+ case 130:
+ return [FWFWKFrameInfoData fromMap:[self readValue]];
+
+ case 131:
+ return [FWFWKNavigationActionData fromMap:[self readValue]];
+
+ case 132:
+ return [FWFWKNavigationActionPolicyEnumData fromMap:[self readValue]];
+
+ default:
+ return [super readValueOfType:type];
+ }
+}
@end
@interface FWFWKNavigationDelegateFlutterApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKNavigationDelegateFlutterApiCodecWriter
+- (void)writeValue:(id)value {
+ if ([value isKindOfClass:[FWFNSErrorData class]]) {
+ [self writeByte:128];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFNSUrlRequestData class]]) {
+ [self writeByte:129];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKFrameInfoData class]]) {
+ [self writeByte:130];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKNavigationActionData class]]) {
+ [self writeByte:131];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKNavigationActionPolicyEnumData class]]) {
+ [self writeByte:132];
+ [self writeValue:[value toMap]];
+ } else {
+ [super writeValue:value];
+ }
+}
@end
@interface FWFWKNavigationDelegateFlutterApiCodecReaderWriter : FlutterStandardReaderWriter
@@ -1213,6 +1491,96 @@ - (void)didFinishNavigationForDelegateWithIdentifier:(NSNumber *)arg_identifier
completion(nil);
}];
}
+- (void)didStartProvisionalNavigationForDelegateWithIdentifier:(NSNumber *)arg_identifier
+ webViewIdentifier:(NSNumber *)arg_webViewIdentifier
+ URL:(nullable NSString *)arg_url
+ completion:
+ (void (^)(NSError *_Nullable))completion {
+ FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+ messageChannelWithName:
+ @"dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didStartProvisionalNavigation"
+ binaryMessenger:self.binaryMessenger
+ codec:FWFWKNavigationDelegateFlutterApiGetCodec()];
+ [channel sendMessage:@[
+ arg_identifier ?: [NSNull null], arg_webViewIdentifier ?: [NSNull null],
+ arg_url ?: [NSNull null]
+ ]
+ reply:^(id reply) {
+ completion(nil);
+ }];
+}
+- (void)
+ decidePolicyForNavigationActionForDelegateWithIdentifier:(NSNumber *)arg_identifier
+ webViewIdentifier:(NSNumber *)arg_webViewIdentifier
+ navigationAction:
+ (FWFWKNavigationActionData *)arg_navigationAction
+ completion:
+ (void (^)(FWFWKNavigationActionPolicyEnumData
+ *_Nullable,
+ NSError *_Nullable))completion {
+ FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+ messageChannelWithName:
+ @"dev.flutter.pigeon.WKNavigationDelegateFlutterApi.decidePolicyForNavigationAction"
+ binaryMessenger:self.binaryMessenger
+ codec:FWFWKNavigationDelegateFlutterApiGetCodec()];
+ [channel sendMessage:@[
+ arg_identifier ?: [NSNull null], arg_webViewIdentifier ?: [NSNull null],
+ arg_navigationAction ?: [NSNull null]
+ ]
+ reply:^(id reply) {
+ FWFWKNavigationActionPolicyEnumData *output = reply;
+ completion(output, nil);
+ }];
+}
+- (void)didFailNavigationForDelegateWithIdentifier:(NSNumber *)arg_identifier
+ webViewIdentifier:(NSNumber *)arg_webViewIdentifier
+ error:(FWFNSErrorData *)arg_error
+ completion:(void (^)(NSError *_Nullable))completion {
+ FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+ messageChannelWithName:@"dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFailNavigation"
+ binaryMessenger:self.binaryMessenger
+ codec:FWFWKNavigationDelegateFlutterApiGetCodec()];
+ [channel sendMessage:@[
+ arg_identifier ?: [NSNull null], arg_webViewIdentifier ?: [NSNull null],
+ arg_error ?: [NSNull null]
+ ]
+ reply:^(id reply) {
+ completion(nil);
+ }];
+}
+- (void)didFailProvisionalNavigationForDelegateWithIdentifier:(NSNumber *)arg_identifier
+ webViewIdentifier:(NSNumber *)arg_webViewIdentifier
+ error:(FWFNSErrorData *)arg_error
+ completion:
+ (void (^)(NSError *_Nullable))completion {
+ FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+ messageChannelWithName:
+ @"dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFailProvisionalNavigation"
+ binaryMessenger:self.binaryMessenger
+ codec:FWFWKNavigationDelegateFlutterApiGetCodec()];
+ [channel sendMessage:@[
+ arg_identifier ?: [NSNull null], arg_webViewIdentifier ?: [NSNull null],
+ arg_error ?: [NSNull null]
+ ]
+ reply:^(id reply) {
+ completion(nil);
+ }];
+}
+- (void)webViewWebContentProcessDidTerminateForDelegateWithIdentifier:(NSNumber *)arg_identifier
+ webViewIdentifier:
+ (NSNumber *)arg_webViewIdentifier
+ completion:(void (^)(NSError *_Nullable))
+ completion {
+ FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+ messageChannelWithName:
+ @"dev.flutter.pigeon.WKNavigationDelegateFlutterApi.webViewWebContentProcessDidTerminate"
+ binaryMessenger:self.binaryMessenger
+ codec:FWFWKNavigationDelegateFlutterApiGetCodec()];
+ [channel sendMessage:@[ arg_identifier ?: [NSNull null], arg_webViewIdentifier ?: [NSNull null] ]
+ reply:^(id reply) {
+ completion(nil);
+ }];
+}
@end
@interface FWFNSObjectHostApiCodecReader : FlutterStandardReader
@end
@@ -1350,11 +1718,106 @@ void FWFNSObjectHostApiSetup(id binaryMessenger,
@interface FWFNSObjectFlutterApiCodecReader : FlutterStandardReader
@end
@implementation FWFNSObjectFlutterApiCodecReader
+- (nullable id)readValueOfType:(UInt8)type {
+ switch (type) {
+ case 128:
+ return [FWFNSErrorData fromMap:[self readValue]];
+
+ case 129:
+ return [FWFNSHttpCookieData fromMap:[self readValue]];
+
+ case 130:
+ return [FWFNSHttpCookiePropertyKeyEnumData fromMap:[self readValue]];
+
+ case 131:
+ return [FWFNSKeyValueChangeKeyEnumData fromMap:[self readValue]];
+
+ case 132:
+ return [FWFNSKeyValueObservingOptionsEnumData fromMap:[self readValue]];
+
+ case 133:
+ return [FWFNSUrlRequestData fromMap:[self readValue]];
+
+ case 134:
+ return [FWFWKAudiovisualMediaTypeEnumData fromMap:[self readValue]];
+
+ case 135:
+ return [FWFWKFrameInfoData fromMap:[self readValue]];
+
+ case 136:
+ return [FWFWKNavigationActionData fromMap:[self readValue]];
+
+ case 137:
+ return [FWFWKNavigationActionPolicyEnumData fromMap:[self readValue]];
+
+ case 138:
+ return [FWFWKScriptMessageData fromMap:[self readValue]];
+
+ case 139:
+ return [FWFWKUserScriptData fromMap:[self readValue]];
+
+ case 140:
+ return [FWFWKUserScriptInjectionTimeEnumData fromMap:[self readValue]];
+
+ case 141:
+ return [FWFWKWebsiteDataTypeEnumData fromMap:[self readValue]];
+
+ default:
+ return [super readValueOfType:type];
+ }
+}
@end
@interface FWFNSObjectFlutterApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFNSObjectFlutterApiCodecWriter
+- (void)writeValue:(id)value {
+ if ([value isKindOfClass:[FWFNSErrorData class]]) {
+ [self writeByte:128];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFNSHttpCookieData class]]) {
+ [self writeByte:129];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFNSHttpCookiePropertyKeyEnumData class]]) {
+ [self writeByte:130];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFNSKeyValueChangeKeyEnumData class]]) {
+ [self writeByte:131];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFNSKeyValueObservingOptionsEnumData class]]) {
+ [self writeByte:132];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFNSUrlRequestData class]]) {
+ [self writeByte:133];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKAudiovisualMediaTypeEnumData class]]) {
+ [self writeByte:134];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKFrameInfoData class]]) {
+ [self writeByte:135];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKNavigationActionData class]]) {
+ [self writeByte:136];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKNavigationActionPolicyEnumData class]]) {
+ [self writeByte:137];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKScriptMessageData class]]) {
+ [self writeByte:138];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKUserScriptData class]]) {
+ [self writeByte:139];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKUserScriptInjectionTimeEnumData class]]) {
+ [self writeByte:140];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKWebsiteDataTypeEnumData class]]) {
+ [self writeByte:141];
+ [self writeValue:[value toMap]];
+ } else {
+ [super writeValue:value];
+ }
+}
@end
@interface FWFNSObjectFlutterApiCodecReaderWriter : FlutterStandardReaderWriter
@@ -1392,6 +1855,26 @@ - (instancetype)initWithBinaryMessenger:(NSObject *)bina
}
return self;
}
+- (void)observeValueForObjectWithIdentifier:(NSNumber *)arg_identifier
+ keyPath:(NSString *)arg_keyPath
+ objectIdentifier:(NSNumber *)arg_objectIdentifier
+ changeKeys:
+ (NSArray *)arg_changeKeys
+ changeValues:(NSArray *)arg_changeValues
+ completion:(void (^)(NSError *_Nullable))completion {
+ FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+ messageChannelWithName:@"dev.flutter.pigeon.NSObjectFlutterApi.observeValue"
+ binaryMessenger:self.binaryMessenger
+ codec:FWFNSObjectFlutterApiGetCodec()];
+ [channel sendMessage:@[
+ arg_identifier ?: [NSNull null], arg_keyPath ?: [NSNull null],
+ arg_objectIdentifier ?: [NSNull null], arg_changeKeys ?: [NSNull null],
+ arg_changeValues ?: [NSNull null]
+ ]
+ reply:^(id reply) {
+ completion(nil);
+ }];
+}
@end
@interface FWFWKWebViewHostApiCodecReader : FlutterStandardReader
@end
@@ -1399,27 +1882,45 @@ @implementation FWFWKWebViewHostApiCodecReader
- (nullable id)readValueOfType:(UInt8)type {
switch (type) {
case 128:
- return [FWFNSHttpCookieData fromMap:[self readValue]];
+ return [FWFNSErrorData fromMap:[self readValue]];
case 129:
- return [FWFNSHttpCookiePropertyKeyEnumData fromMap:[self readValue]];
+ return [FWFNSHttpCookieData fromMap:[self readValue]];
case 130:
- return [FWFNSKeyValueObservingOptionsEnumData fromMap:[self readValue]];
+ return [FWFNSHttpCookiePropertyKeyEnumData fromMap:[self readValue]];
case 131:
- return [FWFNSUrlRequestData fromMap:[self readValue]];
+ return [FWFNSKeyValueChangeKeyEnumData fromMap:[self readValue]];
case 132:
- return [FWFWKAudiovisualMediaTypeEnumData fromMap:[self readValue]];
+ return [FWFNSKeyValueObservingOptionsEnumData fromMap:[self readValue]];
case 133:
- return [FWFWKUserScriptData fromMap:[self readValue]];
+ return [FWFNSUrlRequestData fromMap:[self readValue]];
case 134:
- return [FWFWKUserScriptInjectionTimeEnumData fromMap:[self readValue]];
+ return [FWFWKAudiovisualMediaTypeEnumData fromMap:[self readValue]];
case 135:
+ return [FWFWKFrameInfoData fromMap:[self readValue]];
+
+ case 136:
+ return [FWFWKNavigationActionData fromMap:[self readValue]];
+
+ case 137:
+ return [FWFWKNavigationActionPolicyEnumData fromMap:[self readValue]];
+
+ case 138:
+ return [FWFWKScriptMessageData fromMap:[self readValue]];
+
+ case 139:
+ return [FWFWKUserScriptData fromMap:[self readValue]];
+
+ case 140:
+ return [FWFWKUserScriptInjectionTimeEnumData fromMap:[self readValue]];
+
+ case 141:
return [FWFWKWebsiteDataTypeEnumData fromMap:[self readValue]];
default:
@@ -1432,30 +1933,48 @@ @interface FWFWKWebViewHostApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKWebViewHostApiCodecWriter
- (void)writeValue:(id)value {
- if ([value isKindOfClass:[FWFNSHttpCookieData class]]) {
+ if ([value isKindOfClass:[FWFNSErrorData class]]) {
[self writeByte:128];
[self writeValue:[value toMap]];
- } else if ([value isKindOfClass:[FWFNSHttpCookiePropertyKeyEnumData class]]) {
+ } else if ([value isKindOfClass:[FWFNSHttpCookieData class]]) {
[self writeByte:129];
[self writeValue:[value toMap]];
- } else if ([value isKindOfClass:[FWFNSKeyValueObservingOptionsEnumData class]]) {
+ } else if ([value isKindOfClass:[FWFNSHttpCookiePropertyKeyEnumData class]]) {
[self writeByte:130];
[self writeValue:[value toMap]];
- } else if ([value isKindOfClass:[FWFNSUrlRequestData class]]) {
+ } else if ([value isKindOfClass:[FWFNSKeyValueChangeKeyEnumData class]]) {
[self writeByte:131];
[self writeValue:[value toMap]];
- } else if ([value isKindOfClass:[FWFWKAudiovisualMediaTypeEnumData class]]) {
+ } else if ([value isKindOfClass:[FWFNSKeyValueObservingOptionsEnumData class]]) {
[self writeByte:132];
[self writeValue:[value toMap]];
- } else if ([value isKindOfClass:[FWFWKUserScriptData class]]) {
+ } else if ([value isKindOfClass:[FWFNSUrlRequestData class]]) {
[self writeByte:133];
[self writeValue:[value toMap]];
- } else if ([value isKindOfClass:[FWFWKUserScriptInjectionTimeEnumData class]]) {
+ } else if ([value isKindOfClass:[FWFWKAudiovisualMediaTypeEnumData class]]) {
[self writeByte:134];
[self writeValue:[value toMap]];
- } else if ([value isKindOfClass:[FWFWKWebsiteDataTypeEnumData class]]) {
+ } else if ([value isKindOfClass:[FWFWKFrameInfoData class]]) {
[self writeByte:135];
[self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKNavigationActionData class]]) {
+ [self writeByte:136];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKNavigationActionPolicyEnumData class]]) {
+ [self writeByte:137];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKScriptMessageData class]]) {
+ [self writeByte:138];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKUserScriptData class]]) {
+ [self writeByte:139];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKUserScriptInjectionTimeEnumData class]]) {
+ [self writeByte:140];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKWebsiteDataTypeEnumData class]]) {
+ [self writeByte:141];
+ [self writeValue:[value toMap]];
} else {
[super writeValue:value];
}
@@ -1967,6 +2486,98 @@ void FWFWKUIDelegateHostApiSetup(id binaryMessenger,
}
}
}
+@interface FWFWKUIDelegateFlutterApiCodecReader : FlutterStandardReader
+@end
+@implementation FWFWKUIDelegateFlutterApiCodecReader
+- (nullable id)readValueOfType:(UInt8)type {
+ switch (type) {
+ case 128:
+ return [FWFNSUrlRequestData fromMap:[self readValue]];
+
+ case 129:
+ return [FWFWKFrameInfoData fromMap:[self readValue]];
+
+ case 130:
+ return [FWFWKNavigationActionData fromMap:[self readValue]];
+
+ default:
+ return [super readValueOfType:type];
+ }
+}
+@end
+
+@interface FWFWKUIDelegateFlutterApiCodecWriter : FlutterStandardWriter
+@end
+@implementation FWFWKUIDelegateFlutterApiCodecWriter
+- (void)writeValue:(id)value {
+ if ([value isKindOfClass:[FWFNSUrlRequestData class]]) {
+ [self writeByte:128];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKFrameInfoData class]]) {
+ [self writeByte:129];
+ [self writeValue:[value toMap]];
+ } else if ([value isKindOfClass:[FWFWKNavigationActionData class]]) {
+ [self writeByte:130];
+ [self writeValue:[value toMap]];
+ } else {
+ [super writeValue:value];
+ }
+}
+@end
+
+@interface FWFWKUIDelegateFlutterApiCodecReaderWriter : FlutterStandardReaderWriter
+@end
+@implementation FWFWKUIDelegateFlutterApiCodecReaderWriter
+- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
+ return [[FWFWKUIDelegateFlutterApiCodecWriter alloc] initWithData:data];
+}
+- (FlutterStandardReader *)readerWithData:(NSData *)data {
+ return [[FWFWKUIDelegateFlutterApiCodecReader alloc] initWithData:data];
+}
+@end
+
+NSObject *FWFWKUIDelegateFlutterApiGetCodec() {
+ static dispatch_once_t sPred = 0;
+ static FlutterStandardMessageCodec *sSharedObject = nil;
+ dispatch_once(&sPred, ^{
+ FWFWKUIDelegateFlutterApiCodecReaderWriter *readerWriter =
+ [[FWFWKUIDelegateFlutterApiCodecReaderWriter alloc] init];
+ sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
+ });
+ return sSharedObject;
+}
+
+@interface FWFWKUIDelegateFlutterApi ()
+@property(nonatomic, strong) NSObject *binaryMessenger;
+@end
+
+@implementation FWFWKUIDelegateFlutterApi
+
+- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger {
+ self = [super init];
+ if (self) {
+ _binaryMessenger = binaryMessenger;
+ }
+ return self;
+}
+- (void)onCreateWebViewForDelegateWithIdentifier:(NSNumber *)arg_identifier
+ webViewIdentifier:(NSNumber *)arg_webViewIdentifier
+ configurationIdentifier:(NSNumber *)arg_configurationIdentifier
+ navigationAction:(FWFWKNavigationActionData *)arg_navigationAction
+ completion:(void (^)(NSError *_Nullable))completion {
+ FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+ messageChannelWithName:@"dev.flutter.pigeon.WKUIDelegateFlutterApi.onCreateWebView"
+ binaryMessenger:self.binaryMessenger
+ codec:FWFWKUIDelegateFlutterApiGetCodec()];
+ [channel sendMessage:@[
+ arg_identifier ?: [NSNull null], arg_webViewIdentifier ?: [NSNull null],
+ arg_configurationIdentifier ?: [NSNull null], arg_navigationAction ?: [NSNull null]
+ ]
+ reply:^(id reply) {
+ completion(nil);
+ }];
+}
+@end
@interface FWFWKHttpCookieStoreHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKHttpCookieStoreHostApiCodecReader
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFNavigationDelegateHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFNavigationDelegateHostApi.h
index 2ac599603152..da5939a3abed 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFNavigationDelegateHostApi.h
+++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFNavigationDelegateHostApi.h
@@ -26,7 +26,9 @@ NS_ASSUME_NONNULL_BEGIN
* Implementation of WKNavigationDelegate for FWFNavigationDelegateHostApiImpl.
*/
@interface FWFNavigationDelegate : FWFObject
-@property(readonly, nonnull) FWFNavigationDelegateFlutterApiImpl *navigationDelegateAPI;
+@property(readonly, nonnull, nonatomic) FWFNavigationDelegateFlutterApiImpl *navigationDelegateAPI;
+- (instancetype)initWithBinaryMessenger:(id)binaryMessenger
+ instanceManager:(FWFInstanceManager *)instanceManager;
@end
/**
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFNavigationDelegateHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFNavigationDelegateHostApi.m
index be651c942c0e..6946783088d5 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFNavigationDelegateHostApi.m
+++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFNavigationDelegateHostApi.m
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#import "FWFNavigationDelegateHostApi.h"
+#import "FWFDataConverters.h"
#import "FWFWebViewConfigurationHostApi.h"
@interface FWFNavigationDelegateFlutterApiImpl ()
@@ -26,15 +27,82 @@ - (long)identifierForDelegate:(FWFNavigationDelegate *)instance {
- (void)didFinishNavigationForDelegate:(FWFNavigationDelegate *)instance
webView:(WKWebView *)webView
- URL:(NSString *)URL {
+ URL:(NSString *)URL
+ completion:(void (^)(NSError *_Nullable))completion {
+ NSNumber *webViewIdentifier =
+ @([self.instanceManager identifierWithStrongReferenceForInstance:webView]);
[self didFinishNavigationForDelegateWithIdentifier:@([self identifierForDelegate:instance])
- webViewIdentifier:
- @([self.instanceManager
- identifierWithStrongReferenceForInstance:webView])
+ webViewIdentifier:webViewIdentifier
URL:URL
- completion:^(NSError *error) {
- NSAssert(!error, @"%@", error);
- }];
+ completion:completion];
+}
+
+- (void)didStartProvisionalNavigationForDelegate:(FWFNavigationDelegate *)instance
+ webView:(WKWebView *)webView
+ URL:(NSString *)URL
+ completion:(void (^)(NSError *_Nullable))completion {
+ NSNumber *webViewIdentifier =
+ @([self.instanceManager identifierWithStrongReferenceForInstance:webView]);
+ [self didStartProvisionalNavigationForDelegateWithIdentifier:@([self
+ identifierForDelegate:instance])
+ webViewIdentifier:webViewIdentifier
+ URL:URL
+ completion:completion];
+}
+
+- (void)
+ decidePolicyForNavigationActionForDelegate:(FWFNavigationDelegate *)instance
+ webView:(WKWebView *)webView
+ navigationAction:(WKNavigationAction *)navigationAction
+ completion:
+ (void (^)(FWFWKNavigationActionPolicyEnumData *_Nullable,
+ NSError *_Nullable))completion {
+ NSNumber *webViewIdentifier =
+ @([self.instanceManager identifierWithStrongReferenceForInstance:webView]);
+ FWFWKNavigationActionData *navigationActionData =
+ FWFWKNavigationActionDataFromNavigationAction(navigationAction);
+ [self
+ decidePolicyForNavigationActionForDelegateWithIdentifier:@([self
+ identifierForDelegate:instance])
+ webViewIdentifier:webViewIdentifier
+ navigationAction:navigationActionData
+ completion:completion];
+}
+
+- (void)didFailNavigationForDelegate:(FWFNavigationDelegate *)instance
+ webView:(WKWebView *)webView
+ error:(NSError *)error
+ completion:(void (^)(NSError *_Nullable))completion {
+ NSNumber *webViewIdentifier =
+ @([self.instanceManager identifierWithStrongReferenceForInstance:webView]);
+ [self didFailNavigationForDelegateWithIdentifier:@([self identifierForDelegate:instance])
+ webViewIdentifier:webViewIdentifier
+ error:FWFNSErrorDataFromNSError(error)
+ completion:completion];
+}
+
+- (void)didFailProvisionalNavigationForDelegate:(FWFNavigationDelegate *)instance
+ webView:(WKWebView *)webView
+ error:(NSError *)error
+ completion:(void (^)(NSError *_Nullable))completion {
+ NSNumber *webViewIdentifier =
+ @([self.instanceManager identifierWithStrongReferenceForInstance:webView]);
+ [self
+ didFailProvisionalNavigationForDelegateWithIdentifier:@([self identifierForDelegate:instance])
+ webViewIdentifier:webViewIdentifier
+ error:FWFNSErrorDataFromNSError(error)
+ completion:completion];
+}
+
+- (void)webViewWebContentProcessDidTerminateForDelegate:(FWFNavigationDelegate *)instance
+ webView:(WKWebView *)webView
+ completion:(void (^)(NSError *_Nullable))completion {
+ NSNumber *webViewIdentifier =
+ @([self.instanceManager identifierWithStrongReferenceForInstance:webView]);
+ [self webViewWebContentProcessDidTerminateForDelegateWithIdentifier:
+ @([self identifierForDelegate:instance])
+ webViewIdentifier:webViewIdentifier
+ completion:completion];
}
@end
@@ -53,7 +121,64 @@ - (instancetype)initWithBinaryMessenger:(id)binaryMessen
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
[self.navigationDelegateAPI didFinishNavigationForDelegate:self
webView:webView
- URL:webView.URL.absoluteString];
+ URL:webView.URL.absoluteString
+ completion:^(NSError *error) {
+ NSAssert(!error, @"%@", error);
+ }];
+}
+
+- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
+ [self.navigationDelegateAPI didStartProvisionalNavigationForDelegate:self
+ webView:webView
+ URL:webView.URL.absoluteString
+ completion:^(NSError *error) {
+ NSAssert(!error, @"%@", error);
+ }];
+}
+
+- (void)webView:(WKWebView *)webView
+ decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
+ decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
+ [self.navigationDelegateAPI
+ decidePolicyForNavigationActionForDelegate:self
+ webView:webView
+ navigationAction:navigationAction
+ completion:^(FWFWKNavigationActionPolicyEnumData *policy,
+ NSError *error) {
+ NSAssert(!error, @"%@", error);
+ decisionHandler(
+ FWFWKNavigationActionPolicyFromEnumData(policy));
+ }];
+}
+
+- (void)webView:(WKWebView *)webView
+ didFailNavigation:(WKNavigation *)navigation
+ withError:(NSError *)error {
+ [self.navigationDelegateAPI didFailNavigationForDelegate:self
+ webView:webView
+ error:error
+ completion:^(NSError *error) {
+ NSAssert(!error, @"%@", error);
+ }];
+}
+
+- (void)webView:(WKWebView *)webView
+ didFailProvisionalNavigation:(WKNavigation *)navigation
+ withError:(NSError *)error {
+ [self.navigationDelegateAPI didFailProvisionalNavigationForDelegate:self
+ webView:webView
+ error:error
+ completion:^(NSError *error) {
+ NSAssert(!error, @"%@", error);
+ }];
+}
+
+- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
+ [self.navigationDelegateAPI webViewWebContentProcessDidTerminateForDelegate:self
+ webView:webView
+ completion:^(NSError *error) {
+ NSAssert(!error, @"%@", error);
+ }];
}
@end
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.h
index f1dbdbb20776..1f7b2943974e 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.h
+++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.h
@@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN
*
* Handles making callbacks to Dart for an NSObject.
*/
-@interface FWFObjectFlutterApi : FWFNSObjectFlutterApi
+@interface FWFObjectFlutterApiImpl : FWFNSObjectFlutterApi
- (instancetype)initWithBinaryMessenger:(id)binaryMessenger
instanceManager:(FWFInstanceManager *)instanceManager;
@end
@@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
* Implementation of NSObject for FWFObjectHostApiImpl.
*/
@interface FWFObject : NSObject
-@property(readonly, nonnull) FWFObjectFlutterApi *objectApi;
+@property(readonly, nonnull, nonatomic) FWFObjectFlutterApiImpl *objectApi;
- (instancetype)initWithBinaryMessenger:(id)binaryMessenger
instanceManager:(FWFInstanceManager *)instanceManager;
@end
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.m
index 0cc4c5693342..f88b91750493 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.m
+++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.m
@@ -5,12 +5,12 @@
#import "FWFObjectHostApi.h"
#import "FWFDataConverters.h"
-@interface FWFObjectFlutterApi ()
+@interface FWFObjectFlutterApiImpl ()
// This reference must be weak to prevent a circular reference with the objects it stores.
@property(nonatomic, weak) FWFInstanceManager *instanceManager;
@end
-@implementation FWFObjectFlutterApi
+@implementation FWFObjectFlutterApiImpl
- (instancetype)initWithBinaryMessenger:(id)binaryMessenger
instanceManager:(FWFInstanceManager *)instanceManager {
self = [self initWithBinaryMessenger:binaryMessenger];
@@ -19,6 +19,33 @@ - (instancetype)initWithBinaryMessenger:(id)binaryMessen
}
return self;
}
+
+- (long)identifierForObject:(NSObject *)instance {
+ return [self.instanceManager identifierWithStrongReferenceForInstance:instance];
+}
+
+- (void)observeValueForObject:(NSObject *)instance
+ keyPath:(NSString *)keyPath
+ object:(NSObject *)object
+ change:(NSDictionary *)change
+ completion:(void (^)(NSError *_Nullable))completion {
+ NSMutableArray *changeKeys = [NSMutableArray array];
+ NSMutableArray *changeValues = [NSMutableArray array];
+
+ [change enumerateKeysAndObjectsUsingBlock:^(NSKeyValueChangeKey key, id value, BOOL *stop) {
+ [changeKeys addObject:FWFNSKeyValueChangeKeyEnumDataFromNSKeyValueChangeKey(key)];
+ [changeValues addObject:value];
+ }];
+
+ NSNumber *objectIdentifier =
+ @([self.instanceManager identifierWithStrongReferenceForInstance:object]);
+ [self observeValueForObjectWithIdentifier:@([self identifierForObject:instance])
+ keyPath:keyPath
+ objectIdentifier:objectIdentifier
+ changeKeys:changeKeys
+ changeValues:changeValues
+ completion:completion];
+}
@end
@implementation FWFObject
@@ -26,11 +53,24 @@ - (instancetype)initWithBinaryMessenger:(id)binaryMessen
instanceManager:(FWFInstanceManager *)instanceManager {
self = [self init];
if (self) {
- _objectApi = [[FWFObjectFlutterApi alloc] initWithBinaryMessenger:binaryMessenger
- instanceManager:instanceManager];
+ _objectApi = [[FWFObjectFlutterApiImpl alloc] initWithBinaryMessenger:binaryMessenger
+ instanceManager:instanceManager];
}
return self;
}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath
+ ofObject:(id)object
+ change:(NSDictionary *)change
+ context:(void *)context {
+ [self.objectApi observeValueForObject:self
+ keyPath:keyPath
+ object:object
+ change:change
+ completion:^(NSError *error) {
+ NSAssert(!error, @"%@", error);
+ }];
+}
@end
@interface FWFObjectHostApiImpl ()
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScriptMessageHandlerHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScriptMessageHandlerHostApi.h
index 7440862ce4e4..36f12feac3fe 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScriptMessageHandlerHostApi.h
+++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScriptMessageHandlerHostApi.h
@@ -7,13 +7,28 @@
#import "FWFGeneratedWebKitApis.h"
#import "FWFInstanceManager.h"
+#import "FWFObjectHostApi.h"
NS_ASSUME_NONNULL_BEGIN
+/**
+ * Flutter api implementation for WKScriptMessageHandler.
+ *
+ * Handles making callbacks to Dart for a WKScriptMessageHandler.
+ */
+@interface FWFScriptMessageHandlerFlutterApiImpl : FWFWKScriptMessageHandlerFlutterApi
+- (instancetype)initWithBinaryMessenger:(id)binaryMessenger
+ instanceManager:(FWFInstanceManager *)instanceManager;
+@end
+
/**
* Implementation of WKScriptMessageHandler for FWFScriptMessageHandlerHostApiImpl.
*/
-@interface FWFScriptMessageHandler : NSObject
+@interface FWFScriptMessageHandler : FWFObject
+@property(readonly, nonnull, nonatomic)
+ FWFScriptMessageHandlerFlutterApiImpl *scriptMessageHandlerAPI;
+- (instancetype)initWithBinaryMessenger:(id)binaryMessenger
+ instanceManager:(FWFInstanceManager *)instanceManager;
@end
/**
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScriptMessageHandlerHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScriptMessageHandlerHostApi.m
index 9e4b5f003abc..69ace0202824 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScriptMessageHandlerHostApi.m
+++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFScriptMessageHandlerHostApi.m
@@ -5,14 +5,64 @@
#import "FWFScriptMessageHandlerHostApi.h"
#import "FWFDataConverters.h"
+@interface FWFScriptMessageHandlerFlutterApiImpl ()
+// This reference must be weak to prevent a circular reference with the objects it stores.
+@property(nonatomic, weak) FWFInstanceManager *instanceManager;
+@end
+
+@implementation FWFScriptMessageHandlerFlutterApiImpl
+- (instancetype)initWithBinaryMessenger:(id)binaryMessenger
+ instanceManager:(FWFInstanceManager *)instanceManager {
+ self = [self initWithBinaryMessenger:binaryMessenger];
+ if (self) {
+ _instanceManager = instanceManager;
+ }
+ return self;
+}
+
+- (long)identifierForHandler:(FWFScriptMessageHandler *)instance {
+ return [self.instanceManager identifierWithStrongReferenceForInstance:instance];
+}
+
+- (void)didReceiveScriptMessageForHandler:(FWFScriptMessageHandler *)instance
+ userContentController:(WKUserContentController *)userContentController
+ message:(WKScriptMessage *)message
+ completion:(void (^)(NSError *_Nullable))completion {
+ NSNumber *userContentControllerIdentifier =
+ @([self.instanceManager identifierWithStrongReferenceForInstance:userContentController]);
+ FWFWKScriptMessageData *messageData = FWFWKScriptMessageDataFromWKScriptMessage(message);
+ [self didReceiveScriptMessageForHandlerWithIdentifier:@([self identifierForHandler:instance])
+ userContentControllerIdentifier:userContentControllerIdentifier
+ message:messageData
+ completion:completion];
+}
+@end
+
@implementation FWFScriptMessageHandler
+- (instancetype)initWithBinaryMessenger:(id)binaryMessenger
+ instanceManager:(FWFInstanceManager *)instanceManager {
+ self = [super initWithBinaryMessenger:binaryMessenger instanceManager:instanceManager];
+ if (self) {
+ _scriptMessageHandlerAPI =
+ [[FWFScriptMessageHandlerFlutterApiImpl alloc] initWithBinaryMessenger:binaryMessenger
+ instanceManager:instanceManager];
+ }
+ return self;
+}
+
- (void)userContentController:(nonnull WKUserContentController *)userContentController
didReceiveScriptMessage:(nonnull WKScriptMessage *)message {
+ [self.scriptMessageHandlerAPI didReceiveScriptMessageForHandler:self
+ userContentController:userContentController
+ message:message
+ completion:^(NSError *error) {
+ NSAssert(!error, @"%@", error);
+ }];
}
@end
@interface FWFScriptMessageHandlerHostApiImpl ()
-@property(nonatomic) FWFInstanceManager *instanceManager;
+@property(nonatomic, weak) FWFInstanceManager *instanceManager;
@end
@implementation FWFScriptMessageHandlerHostApiImpl
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIDelegateHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIDelegateHostApi.h
index 8795b00e9001..65c148e6b0b1 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIDelegateHostApi.h
+++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIDelegateHostApi.h
@@ -7,13 +7,27 @@
#import "FWFGeneratedWebKitApis.h"
#import "FWFInstanceManager.h"
+#import "FWFObjectHostApi.h"
NS_ASSUME_NONNULL_BEGIN
+/**
+ * Flutter api implementation for WKUIDelegate.
+ *
+ * Handles making callbacks to Dart for a WKUIDelegate.
+ */
+@interface FWFUIDelegateFlutterApiImpl : FWFWKUIDelegateFlutterApi
+- (instancetype)initWithBinaryMessenger:(id)binaryMessenger
+ instanceManager:(FWFInstanceManager *)instanceManager;
+@end
+
/**
* Implementation of WKUIDelegate for FWFUIDelegateHostApiImpl.
*/
-@interface FWFUIDelegate : NSObject
+@interface FWFUIDelegate : FWFObject
+@property(readonly, nonnull, nonatomic) FWFUIDelegateFlutterApiImpl *UIDelegateAPI;
+- (instancetype)initWithBinaryMessenger:(id)binaryMessenger
+ instanceManager:(FWFInstanceManager *)instanceManager;
@end
/**
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIDelegateHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIDelegateHostApi.m
index 28d0ab53aaad..4ec8b583b1f8 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIDelegateHostApi.m
+++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIDelegateHostApi.m
@@ -3,13 +3,75 @@
// found in the LICENSE file.
#import "FWFUIDelegateHostApi.h"
+#import "FWFDataConverters.h"
#import "FWFWebViewConfigurationHostApi.h"
+@interface FWFUIDelegateFlutterApiImpl ()
+// This reference must be weak to prevent a circular reference with the objects it stores.
+@property(nonatomic, weak) FWFInstanceManager *instanceManager;
+@end
+
+@implementation FWFUIDelegateFlutterApiImpl
+- (instancetype)initWithBinaryMessenger:(id)binaryMessenger
+ instanceManager:(FWFInstanceManager *)instanceManager {
+ self = [self initWithBinaryMessenger:binaryMessenger];
+ if (self) {
+ _instanceManager = instanceManager;
+ }
+ return self;
+}
+
+- (long)identifierForDelegate:(FWFUIDelegate *)instance {
+ return [self.instanceManager identifierWithStrongReferenceForInstance:instance];
+}
+
+- (void)onCreateWebViewForDelegate:(FWFUIDelegate *)instance
+ webView:(WKWebView *)webView
+ configuration:(WKWebViewConfiguration *)configuration
+ navigationAction:(WKNavigationAction *)navigationAction
+ completion:(void (^)(NSError *_Nullable))completion {
+ NSNumber *configurationIdentifier =
+ @([self.instanceManager identifierWithStrongReferenceForInstance:configuration]);
+ FWFWKNavigationActionData *navigationActionData =
+ FWFWKNavigationActionDataFromNavigationAction(navigationAction);
+ [self onCreateWebViewForDelegateWithIdentifier:@([self identifierForDelegate:instance])
+ webViewIdentifier:
+ @([self.instanceManager
+ identifierWithStrongReferenceForInstance:webView])
+ configurationIdentifier:configurationIdentifier
+ navigationAction:navigationActionData
+ completion:completion];
+}
+@end
+
@implementation FWFUIDelegate
+- (instancetype)initWithBinaryMessenger:(id)binaryMessenger
+ instanceManager:(FWFInstanceManager *)instanceManager {
+ self = [super initWithBinaryMessenger:binaryMessenger instanceManager:instanceManager];
+ if (self) {
+ _UIDelegateAPI = [[FWFUIDelegateFlutterApiImpl alloc] initWithBinaryMessenger:binaryMessenger
+ instanceManager:instanceManager];
+ }
+ return self;
+}
+
+- (WKWebView *)webView:(WKWebView *)webView
+ createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration
+ forNavigationAction:(WKNavigationAction *)navigationAction
+ windowFeatures:(WKWindowFeatures *)windowFeatures {
+ [self.UIDelegateAPI onCreateWebViewForDelegate:self
+ webView:webView
+ configuration:configuration
+ navigationAction:navigationAction
+ completion:^(NSError *error) {
+ NSAssert(!error, @"%@", error);
+ }];
+ return nil;
+}
@end
@interface FWFUIDelegateHostApiImpl ()
-@property(nonatomic) FWFInstanceManager *instanceManager;
+@property(nonatomic, weak) FWFInstanceManager *instanceManager;
@end
@implementation FWFUIDelegateHostApiImpl