Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 0f90d24

Browse files
authored
[webview_flutter] Implement loadRequest in iOS package. (#4480)
1 parent 0cfbe17 commit 0f90d24

File tree

12 files changed

+334
-30
lines changed

12 files changed

+334
-30
lines changed

packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.3.0
2+
3+
* Implemented new `loadRequest` method from platform interface.
4+
15
## 2.2.0
26

37
* Implemented new `runJavascript` and `runJavascriptReturningResult` methods in platform interface.

packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@
193193
C370F140C3A19241FD8C5E64 /* Pods-RunnerTests.debug.xcconfig */,
194194
5C776D27D0DDA247ED5EA72B /* Pods-RunnerTests.release.xcconfig */,
195195
);
196-
name = Pods;
197196
path = Pods;
198197
sourceTree = "<group>";
199198
};

packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FLTWebViewTests.m

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
@import Flutter;
66
@import XCTest;
77
@import webview_flutter_wkwebview;
8+
@import webview_flutter_wkwebview.Test;
89

910
// OCMock library doesn't generate a valid modulemap.
1011
#import <OCMock/OCMock.h>
@@ -301,4 +302,196 @@ - (void)testRunJavascriptReturningResultReturnsErrorResultForWKError {
301302
[self waitForExpectationsWithTimeout:30.0 handler:nil];
302303
}
303304

305+
- (void)testBuildNSURLRequestReturnsNilForNonDictionaryValue {
306+
// Setup
307+
FLTWebViewController *controller =
308+
[[FLTWebViewController alloc] initWithFrame:CGRectMake(0, 0, 300, 400)
309+
viewIdentifier:1
310+
arguments:nil
311+
binaryMessenger:self.mockBinaryMessenger];
312+
313+
// Run
314+
NSURLRequest *request = [controller buildNSURLRequest:@{@"request" : @"Non Dictionary Value"}];
315+
316+
// Verify
317+
XCTAssertNil(request);
318+
}
319+
320+
- (void)testBuildNSURLRequestReturnsNilForMissingURI {
321+
// Setup
322+
FLTWebViewController *controller =
323+
[[FLTWebViewController alloc] initWithFrame:CGRectMake(0, 0, 300, 400)
324+
viewIdentifier:1
325+
arguments:nil
326+
binaryMessenger:self.mockBinaryMessenger];
327+
328+
// Run
329+
NSURLRequest *request = [controller buildNSURLRequest:@{@"request" : @{}}];
330+
331+
// Verify
332+
XCTAssertNil(request);
333+
}
334+
335+
- (void)testBuildNSURLRequestReturnsNilForInvalidURI {
336+
// Setup
337+
FLTWebViewController *controller =
338+
[[FLTWebViewController alloc] initWithFrame:CGRectMake(0, 0, 300, 400)
339+
viewIdentifier:1
340+
arguments:nil
341+
binaryMessenger:self.mockBinaryMessenger];
342+
343+
// Run
344+
NSDictionary *requestData = @{@"uri" : @"invalid uri"};
345+
NSURLRequest *request = [controller buildNSURLRequest:@{@"request" : requestData}];
346+
347+
// Verify
348+
XCTAssertNil(request);
349+
}
350+
351+
- (void)testBuildNSURLRequestBuildsNSMutableURLRequestWithOptionalParameters {
352+
// Setup
353+
FLTWebViewController *controller =
354+
[[FLTWebViewController alloc] initWithFrame:CGRectMake(0, 0, 300, 400)
355+
viewIdentifier:1
356+
arguments:nil
357+
binaryMessenger:self.mockBinaryMessenger];
358+
359+
// Run
360+
NSDictionary *requestData = @{
361+
@"uri" : @"https://flutter.dev",
362+
@"method" : @"POST",
363+
@"headers" : @{@"Foo" : @"Bar"},
364+
@"body" : [FlutterStandardTypedData
365+
typedDataWithBytes:[@"Test Data" dataUsingEncoding:NSUTF8StringEncoding]],
366+
};
367+
NSURLRequest *request = [controller buildNSURLRequest:@{@"request" : requestData}];
368+
369+
// Verify
370+
XCTAssertNotNil(request);
371+
XCTAssertEqualObjects(request.URL.absoluteString, @"https://flutter.dev");
372+
XCTAssertEqualObjects(request.HTTPMethod, @"POST");
373+
XCTAssertEqualObjects(request.allHTTPHeaderFields, @{@"Foo" : @"Bar"});
374+
XCTAssertEqualObjects(request.HTTPBody, [@"Test Data" dataUsingEncoding:NSUTF8StringEncoding]);
375+
}
376+
377+
- (void)testBuildNSURLRequestBuildsNSMutableURLRequestWithoutOptionalParameters {
378+
// Setup
379+
FLTWebViewController *controller =
380+
[[FLTWebViewController alloc] initWithFrame:CGRectMake(0, 0, 300, 400)
381+
viewIdentifier:1
382+
arguments:nil
383+
binaryMessenger:self.mockBinaryMessenger];
384+
385+
// Run
386+
NSDictionary *requestData = @{
387+
@"uri" : @"https://flutter.dev",
388+
};
389+
NSURLRequest *request = [controller buildNSURLRequest:@{@"request" : requestData}];
390+
391+
// Verify
392+
XCTAssertNotNil(request);
393+
XCTAssertEqualObjects(request.URL.absoluteString, @"https://flutter.dev");
394+
XCTAssertEqualObjects(request.HTTPMethod, @"GET");
395+
XCTAssertNil(request.allHTTPHeaderFields);
396+
XCTAssertNil(request.HTTPBody);
397+
}
398+
399+
- (void)testOnLoadUrlReturnsErrorResultForInvalidRequest {
400+
// Setup
401+
FLTWebViewController *controller =
402+
[[FLTWebViewController alloc] initWithFrame:CGRectMake(0, 0, 300, 400)
403+
viewIdentifier:1
404+
arguments:nil
405+
binaryMessenger:self.mockBinaryMessenger];
406+
XCTestExpectation *resultExpectation =
407+
[self expectationWithDescription:@"Should return error result when request cannot be built"];
408+
409+
// Run
410+
FlutterMethodCall *methodCall = [FlutterMethodCall methodCallWithMethodName:@"loadUrl"
411+
arguments:@{}];
412+
[controller onLoadUrl:methodCall
413+
result:^(id _Nullable result) {
414+
XCTAssertTrue([result class] == [FlutterError class]);
415+
[resultExpectation fulfill];
416+
}];
417+
418+
// Verify
419+
[self waitForExpectationsWithTimeout:30.0 handler:nil];
420+
}
421+
422+
- (void)testOnLoadUrlLoadsRequestWithSuccessResult {
423+
// Setup
424+
FLTWebViewController *controller =
425+
[[FLTWebViewController alloc] initWithFrame:CGRectMake(0, 0, 300, 400)
426+
viewIdentifier:1
427+
arguments:nil
428+
binaryMessenger:self.mockBinaryMessenger];
429+
XCTestExpectation *resultExpectation = [self expectationWithDescription:@"Should return nil"];
430+
FLTWKWebView *mockView = OCMClassMock(FLTWKWebView.class);
431+
controller.webView = mockView;
432+
433+
// Run
434+
FlutterMethodCall *methodCall =
435+
[FlutterMethodCall methodCallWithMethodName:@"loadUrl"
436+
arguments:@{@"url" : @"https://flutter.dev/"}];
437+
[controller onLoadUrl:methodCall
438+
result:^(id _Nullable result) {
439+
XCTAssertNil(result);
440+
[resultExpectation fulfill];
441+
}];
442+
443+
// Verify
444+
OCMVerify([mockView loadRequest:[OCMArg any]]);
445+
[self waitForExpectationsWithTimeout:30.0 handler:nil];
446+
}
447+
448+
- (void)testOnLoadRequestReturnsErroResultForInvalidRequest {
449+
// Setup
450+
FLTWebViewController *controller =
451+
[[FLTWebViewController alloc] initWithFrame:CGRectMake(0, 0, 300, 400)
452+
viewIdentifier:1
453+
arguments:nil
454+
binaryMessenger:self.mockBinaryMessenger];
455+
XCTestExpectation *resultExpectation =
456+
[self expectationWithDescription:@"Should return error result when request cannot be built"];
457+
458+
// Run
459+
FlutterMethodCall *methodCall = [FlutterMethodCall methodCallWithMethodName:@"loadRequest"
460+
arguments:@{}];
461+
[controller onLoadRequest:methodCall
462+
result:^(id _Nullable result) {
463+
XCTAssertTrue([result class] == [FlutterError class]);
464+
[resultExpectation fulfill];
465+
}];
466+
467+
// Verify
468+
[self waitForExpectationsWithTimeout:30.0 handler:nil];
469+
}
470+
471+
- (void)testOnLoadRequestLoadsRequestWithSuccessResult {
472+
// Setup
473+
FLTWebViewController *controller =
474+
[[FLTWebViewController alloc] initWithFrame:CGRectMake(0, 0, 300, 400)
475+
viewIdentifier:1
476+
arguments:nil
477+
binaryMessenger:self.mockBinaryMessenger];
478+
XCTestExpectation *resultExpectation = [self expectationWithDescription:@"Should return nil"];
479+
FLTWKWebView *mockView = OCMClassMock(FLTWKWebView.class);
480+
controller.webView = mockView;
481+
482+
// Run
483+
FlutterMethodCall *methodCall = [FlutterMethodCall
484+
methodCallWithMethodName:@"loadRequest"
485+
arguments:@{@"request" : @{@"uri" : @"https://flutter.dev/"}}];
486+
[controller onLoadRequest:methodCall
487+
result:^(id _Nullable result) {
488+
XCTAssertNil(result);
489+
[resultExpectation fulfill];
490+
}];
491+
492+
// Verify
493+
OCMVerify([mockView loadRequest:[OCMArg any]]);
494+
[self waitForExpectationsWithTimeout:30.0 handler:nil];
495+
}
496+
304497
@end

packages/webview_flutter/webview_flutter_wkwebview/example/lib/main.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import 'dart:async';
88
import 'dart:convert';
9+
import 'dart:typed_data';
910
import 'package:flutter/foundation.dart';
1011
import 'package:flutter/material.dart';
1112
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
@@ -120,6 +121,7 @@ enum _MenuOptions {
120121
listCache,
121122
clearCache,
122123
navigationDelegate,
124+
doPostRequest,
123125
}
124126

125127
class _SampleMenu extends StatelessWidget {
@@ -157,6 +159,9 @@ class _SampleMenu extends StatelessWidget {
157159
case _MenuOptions.navigationDelegate:
158160
_onNavigationDelegateExample(controller.data!, context);
159161
break;
162+
case _MenuOptions.doPostRequest:
163+
_onDoPostRequest(controller.data!, context);
164+
break;
160165
}
161166
},
162167
itemBuilder: (BuildContext context) => <PopupMenuItem<_MenuOptions>>[
@@ -189,6 +194,10 @@ class _SampleMenu extends StatelessWidget {
189194
value: _MenuOptions.navigationDelegate,
190195
child: Text('Navigation Delegate example'),
191196
),
197+
const PopupMenuItem<_MenuOptions>(
198+
value: _MenuOptions.doPostRequest,
199+
child: Text('Post Request'),
200+
),
192201
],
193202
);
194203
},
@@ -259,6 +268,17 @@ class _SampleMenu extends StatelessWidget {
259268
await controller.loadUrl('data:text/html;base64,$contentBase64');
260269
}
261270

271+
void _onDoPostRequest(
272+
WebViewController controller, BuildContext context) async {
273+
WebViewRequest request = WebViewRequest(
274+
uri: Uri.parse('https://httpbin.org/post'),
275+
method: WebViewRequestMethod.post,
276+
headers: {'foo': 'bar', 'Content-Type': 'text/plain'},
277+
body: Uint8List.fromList('Test Body'.codeUnits),
278+
);
279+
await controller.loadRequest(request);
280+
}
281+
262282
Widget _getCookieList(String cookies) {
263283
if (cookies == null || cookies == '""') {
264284
return Container();

packages/webview_flutter/webview_flutter_wkwebview/example/lib/web_view.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,11 @@ class WebViewController {
322322
return _webViewPlatformController.loadUrl(url, headers);
323323
}
324324

325+
/// Loads a page by making the specified request.
326+
Future<void> loadRequest(WebViewRequest request) async {
327+
return _webViewPlatformController.loadRequest(request);
328+
}
329+
325330
/// Accessor to the current URL that the WebView is displaying.
326331
///
327332
/// If [WebView.initialUrl] was never specified, returns `null`.

packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ NS_ASSUME_NONNULL_BEGIN
2727
- (UIView*)view;
2828

2929
- (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result;
30+
3031
@end
3132

3233
@interface FLTWebViewFactory : NSObject <FlutterPlatformViewFactory>

0 commit comments

Comments
 (0)