Skip to content

Commit

Permalink
[webview_flutter] Add iOS implementations for new cookie manager, to …
Browse files Browse the repository at this point in the history
…allow setting cookies directly and on webview creation. (flutter#4556)
  • Loading branch information
BeMacized authored Dec 7, 2021
1 parent 60cd47c commit ab99ed5
Show file tree
Hide file tree
Showing 20 changed files with 448 additions and 57 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.6.0

* Implements new cookie manager for setting cookies and providing initial cookies.

## 2.5.0

* Adds an option to set the background color of the webview.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1161,16 +1161,7 @@ String _webviewBool(bool value) {

/// Returns the value used for the HTTP User-Agent: request header in subsequent HTTP requests.
Future<String> _getUserAgent(WebViewController controller) async {
return _runJavascriptReturningResult(controller, 'navigator.userAgent;');
}

Future<String> _runJavascriptReturningResult(
WebViewController controller, String js) async {
if (defaultTargetPlatform == TargetPlatform.iOS) {
return await controller.runJavascriptReturningResult(js);
}
return jsonDecode(await controller.runJavascriptReturningResult(js))
as String;
return await controller.runJavascriptReturningResult('navigator.userAgent;');
}

class ResizableWebView extends StatefulWidget {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objectVersion = 46;
objects = {

/* Begin PBXBuildFile section */
Expand All @@ -16,8 +16,9 @@
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
AE8C124DC8CA68E4D9B30EAB /* libPods-RunnerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 528CB85D53C983D2C5DAFDC5 /* libPods-RunnerTests.a */; };
D7587C3652F6906210B3AE88 /* libPods-RunnerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 17781D9462A1AEA7C99F8E45 /* libPods-RunnerTests.a */; };
DAF0E91266956134538CC667 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 572FFC2B2BA326B420B22679 /* libPods-Runner.a */; };
E43693B527512C0F00382F85 /* FLTCookieManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E43693B427512C0F00382F85 /* FLTCookieManagerTests.m */; };
F7151F77266057800028CB91 /* FLTWebViewUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = F7151F76266057800028CB91 /* FLTWebViewUITests.m */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -54,10 +55,11 @@
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
17781D9462A1AEA7C99F8E45 /* libPods-RunnerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RunnerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
2286ACB87EA8CA27E739AD6C /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
39B2BDAA45DC06EAB8A6C4E7 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
528CB85D53C983D2C5DAFDC5 /* libPods-RunnerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RunnerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
572FFC2B2BA326B420B22679 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
5C776D27D0DDA247ED5EA72B /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
686B4BF82548DBC7000AEA36 /* FLTWKNavigationDelegateTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLTWKNavigationDelegateTests.m; sourceTree = "<group>"; };
68BDCAE923C3F7CB00D9C032 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
68BDCAED23C3F7CB00D9C032 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand All @@ -74,7 +76,7 @@
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B89AA31A64040E4A2F1E0CAF /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
C370F140C3A19241FD8C5E64 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
E43693B427512C0F00382F85 /* FLTCookieManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FLTCookieManagerTests.m; sourceTree = "<group>"; };
F7151F74266057800028CB91 /* RunnerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
F7151F76266057800028CB91 /* FLTWebViewUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FLTWebViewUITests.m; sourceTree = "<group>"; };
F7151F78266057800028CB91 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand All @@ -86,7 +88,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
AE8C124DC8CA68E4D9B30EAB /* libPods-RunnerTests.a in Frameworks */,
D7587C3652F6906210B3AE88 /* libPods-RunnerTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -112,7 +114,7 @@
isa = PBXGroup;
children = (
572FFC2B2BA326B420B22679 /* libPods-Runner.a */,
528CB85D53C983D2C5DAFDC5 /* libPods-RunnerTests.a */,
17781D9462A1AEA7C99F8E45 /* libPods-RunnerTests.a */,
);
name = Frameworks;
sourceTree = "<group>";
Expand All @@ -123,6 +125,7 @@
686B4BF82548DBC7000AEA36 /* FLTWKNavigationDelegateTests.m */,
68BDCAF523C3F97800D9C032 /* FLTWebViewTests.m */,
68BDCAED23C3F7CB00D9C032 /* Info.plist */,
E43693B427512C0F00382F85 /* FLTCookieManagerTests.m */,
);
path = RunnerTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -190,8 +193,8 @@
children = (
F7A1921261392D1CBDAEC2E8 /* Pods-Runner.debug.xcconfig */,
B89AA31A64040E4A2F1E0CAF /* Pods-Runner.release.xcconfig */,
C370F140C3A19241FD8C5E64 /* Pods-RunnerTests.debug.xcconfig */,
5C776D27D0DDA247ED5EA72B /* Pods-RunnerTests.release.xcconfig */,
39B2BDAA45DC06EAB8A6C4E7 /* Pods-RunnerTests.debug.xcconfig */,
2286ACB87EA8CA27E739AD6C /* Pods-RunnerTests.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
Expand All @@ -212,7 +215,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 68BDCAF223C3F7CB00D9C032 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
0067CEC0658A36CBFF8074E7 /* [CP] Check Pods Manifest.lock */,
AA38EF430495C2FB50F0F114 /* [CP] Check Pods Manifest.lock */,
68BDCAE523C3F7CB00D9C032 /* Sources */,
68BDCAE623C3F7CB00D9C032 /* Frameworks */,
68BDCAE723C3F7CB00D9C032 /* Resources */,
Expand Down Expand Up @@ -277,13 +280,16 @@
ORGANIZATIONNAME = "The Flutter Authors";
TargetAttributes = {
68BDCAE823C3F7CB00D9C032 = {
DevelopmentTeam = 7624MWN53C;
ProvisioningStyle = Automatic;
};
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
DevelopmentTeam = 7624MWN53C;
};
F7151F73266057800028CB91 = {
CreatedOnToolsVersion = 12.5;
DevelopmentTeam = 7624MWN53C;
ProvisioningStyle = Automatic;
TestTargetID = 97C146ED1CF9000F007C117D;
};
Expand Down Expand Up @@ -338,7 +344,21 @@
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
0067CEC0658A36CBFF8074E7 /* [CP] Check Pods Manifest.lock */ = {
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin\n";
};
6F536C27DD48B395A30EBB65 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
Expand All @@ -353,28 +373,28 @@
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Thin Binary";
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin\n";
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
};
6F536C27DD48B395A30EBB65 /* [CP] Check Pods Manifest.lock */ = {
AA38EF430495C2FB50F0F114 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
Expand All @@ -389,27 +409,13 @@
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
Expand All @@ -419,6 +425,7 @@
files = (
334734012669319100DCC49E /* FLTWebViewTests.m in Sources */,
334734022669319400DCC49E /* FLTWKNavigationDelegateTests.m in Sources */,
E43693B527512C0F00382F85 /* FLTCookieManagerTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -477,7 +484,7 @@
/* Begin XCBuildConfiguration section */
68BDCAF023C3F7CB00D9C032 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = C370F140C3A19241FD8C5E64 /* Pods-RunnerTests.debug.xcconfig */;
baseConfigurationReference = 39B2BDAA45DC06EAB8A6C4E7 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
Expand All @@ -491,7 +498,7 @@
};
68BDCAF123C3F7CB00D9C032 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 5C776D27D0DDA247ED5EA72B /* Pods-RunnerTests.release.xcconfig */;
baseConfigurationReference = 2286ACB87EA8CA27E739AD6C /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

@import Flutter;
@import XCTest;
@import webview_flutter_wkwebview;
@import webview_flutter_wkwebview.Test;

// OCMock library doesn't generate a valid modulemap.
#import <OCMock/OCMock.h>

@interface FLTCookieManagerTests : XCTestCase

@end

@implementation FLTCookieManagerTests

- (void)setUp {
[super setUp];
}

- (void)testSetCookieForResultSetsCookieAndReturnsResultOnIOS11 {
if (@available(iOS 11.0, *)) {
// Setup
XCTestExpectation *resultExpectation = [self
expectationWithDescription:@"Should return success result when setting cookie completes."];
[FLTCookieManager.instance setHttpCookieStore:OCMClassMock(WKHTTPCookieStore.class)];
NSDictionary *arguments = @{
@"name" : @"foo",
@"value" : @"bar",
@"domain" : @"flutter.dev",
@"path" : @"/",
};
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:@{
NSHTTPCookieName : arguments[@"name"],
NSHTTPCookieValue : arguments[@"value"],
NSHTTPCookieDomain : arguments[@"domain"],
NSHTTPCookiePath : arguments[@"path"],
}];
[OCMStub([FLTCookieManager.instance.httpCookieStore setCookie:[OCMArg isEqual:cookie]
completionHandler:[OCMArg any]])
andDo:^(NSInvocation *invocation) {
void (^setCookieCompletionHandler)(void);
[invocation getArgument:&setCookieCompletionHandler atIndex:3];
setCookieCompletionHandler();
}];
// Run
[[FLTCookieManager instance]
setCookieForResult:^(id _Nullable result) {
XCTAssertNil(result);
[resultExpectation fulfill];
}
arguments:arguments];
// Verify
[self waitForExpectationsWithTimeout:30.0 handler:nil];
}
}

- (void)testSetCookieForDataSetsCookieOnIOS11 {
if (@available(iOS 11.0, *)) {
// Setup
WKHTTPCookieStore *mockHttpCookieStore = OCMClassMock(WKHTTPCookieStore.class);
[FLTCookieManager.instance setHttpCookieStore:mockHttpCookieStore];
NSDictionary *cookieData = @{
@"name" : @"foo",
@"value" : @"bar",
@"domain" : @"flutter.dev",
@"path" : @"/",
};
// Run
[[FLTCookieManager instance] setCookieForData:cookieData];
// Verify
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:@{
NSHTTPCookieName : cookieData[@"name"],
NSHTTPCookieValue : cookieData[@"value"],
NSHTTPCookieDomain : cookieData[@"domain"],
NSHTTPCookiePath : cookieData[@"path"],
}];
OCMVerify([mockHttpCookieStore setCookie:[OCMArg isEqual:cookie]
completionHandler:[OCMArg any]]);
}
}

- (void)testSetCookiesForDataSetsCookiesOnIOS11 {
if (@available(iOS 11.0, *)) {
// Setup
WKHTTPCookieStore *mockHttpCookieStore = OCMClassMock(WKHTTPCookieStore.class);
[FLTCookieManager.instance setHttpCookieStore:mockHttpCookieStore];
NSArray<NSDictionary *> *cookieDatas = @[
@{
@"name" : @"foo1",
@"value" : @"bar1",
@"domain" : @"flutter.dev",
@"path" : @"/",
},
@{
@"name" : @"foo2",
@"value" : @"bar2",
@"domain" : @"flutter2.dev",
@"path" : @"/2",
}
];
// Run
[[FLTCookieManager instance] setCookiesForData:cookieDatas];
// Verify
NSHTTPCookie *cookie1 = [NSHTTPCookie cookieWithProperties:@{
NSHTTPCookieName : cookieDatas[0][@"name"],
NSHTTPCookieValue : cookieDatas[0][@"value"],
NSHTTPCookieDomain : cookieDatas[0][@"domain"],
NSHTTPCookiePath : cookieDatas[0][@"path"],
}];

OCMVerify([mockHttpCookieStore setCookie:[OCMArg isEqual:cookie1]
completionHandler:[OCMArg any]]);
NSHTTPCookie *cookie2 = [NSHTTPCookie cookieWithProperties:@{
NSHTTPCookieName : cookieDatas[1][@"name"],
NSHTTPCookieValue : cookieDatas[1][@"value"],
NSHTTPCookieDomain : cookieDatas[1][@"domain"],
NSHTTPCookiePath : cookieDatas[1][@"path"],
}];
OCMVerify([mockHttpCookieStore setCookie:[OCMArg isEqual:cookie2]
completionHandler:[OCMArg any]]);
}
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
@import Flutter;
@import XCTest;
@import webview_flutter_wkwebview;
@import webview_flutter_wkwebview.Test;

// OCMock library doesn't generate a valid modulemap.
#import <OCMock/OCMock.h>
Expand Down
Loading

0 comments on commit ab99ed5

Please sign in to comment.