Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class SFSDKWebViewStateManager: NSObject {

@objc
@MainActor
@available(*, deprecated, renamed: "resetSessionCookie", message: "Deprecated in Salesforce Mobile SDK 13.2 and will be removed in Salesforce Mobile SDK 14.0. Use resetSessionCookie instead.")
public static func removeSession() {
if sessionCookieManagementDisabled {
SFSDKCoreLogger.d(SFSDKWebViewStateManager.self, message: "[\(Self.self) removeSession]: Cookie Management disabled. Will do nothing.")
Expand All @@ -62,6 +63,14 @@ public class SFSDKWebViewStateManager: NSObject {
}
}

@objc
@MainActor
public static func clearCache() async {
let dataStore = WKWebsiteDataStore.default()
let websiteDataTypes: Set<String> = [WKWebsiteDataTypeFetchCache, WKWebsiteDataTypeMemoryCache, WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeOfflineWebApplicationCache]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I included any type that had cache in the name

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use: WKWebsiteDataStore.allWebsiteDataTypes() ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it okay that it would also include the cookies that we have the other method for? Having a way to get rid of everything sounds good to me

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my mind, it was about starting clean. Let me check the Android code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Android we are doing webView.clearCache(true) (see https://github.com/forcedotcom/SalesforceMobileSDK-Android/pull/2752/files#diff-2b4d6c9697f160bfbefe121309b911622ea530d287a7fbc780a872cfd75cd82aR247) which does not clear the cookies.

To do everything but the cookies we could do

let nonCookieDataTypes: Set<String> = [
    WKWebsiteDataTypeDiskCache,
    WKWebsiteDataTypeMemoryCache,
    WKWebsiteDataTypeLocalStorage,
    WKWebsiteDataTypeSessionStorage,
    WKWebsiteDataTypeIndexedDBDatabases,
    WKWebsiteDataTypeWebSQLDatabases,
    WKWebsiteDataTypeOfflineWebApplicationCache,
    WKWebsiteDataTypeServiceWorkerRegistrations
]```

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, updated! I also changed the "Clear Cookies" option to use the method that clears the cookies regardless of the cookie management flag, I was thinking that would be better to make sure it starts clean like you said (let me know if you think I should change it back)

await dataStore.removeData(ofTypes: websiteDataTypes, modifiedSince: Date.distantPast)
}

@objc
@MainActor
public static func removeSessionForcefully() async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ NS_SWIFT_NAME(SalesforceLoginViewControllerDelegate)
*/
- (void)loginViewController:(nonnull SFLoginViewController *)loginViewController didChangeLoginHost:(nonnull SFSDKLoginHost *)newLoginHost;

- (void)loginViewControllerDidClearCache:(nonnull SFLoginViewController *)loginViewController;

- (void)loginViewControllerDidClearCookies:(nonnull SFLoginViewController *)loginViewController;

- (void)loginViewControllerDidReload:(nonnull SFLoginViewController *)loginViewController;

@end

/** The Salesforce login screen view.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,20 +200,10 @@ - (void)setupNavigationBar {
if (self.showNavbar) {
self.navBar = self.navigationController.navigationBar;
self.navBar.topItem.titleView = [self createTitleItem];
// Hides the gear icon if there are no hosts to switch to.
SFManagedPreferences *managedPreferences = [SFManagedPreferences sharedPreferences];
if (managedPreferences.onlyShowAuthorizedHosts && managedPreferences.loginHosts.count == 0) {
self.config.showSettingsIcon = NO;
}

if(self.showSettingsIcon) {
// Setup right bar button.
UIBarButtonItem *button = [self createSettingsButton];
if (!button.target){
[button setTarget:self];
}
if (!button.action){
[button setAction:@selector(showLoginHost:)];
}
self.navBar.topItem.rightBarButtonItem = button;
}
[self styleNavigationBar:self.navBar];
Expand Down Expand Up @@ -265,9 +255,53 @@ - (UIBarButtonItem *)createBackButton {

- (UIBarButtonItem *)createSettingsButton {
UIImage *image = [[SFSDKResourceUtils imageNamed:@"login-window-gear"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIBarButtonItem *settingsButton = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:@selector(showLoginHost:)];
settingsButton.accessibilityLabel = [SFSDKResourceUtils localizedString:@"LOGIN_CHOOSE_SERVER"];
settingsButton.accessibilityIdentifier = @"choose connection button";

NSMutableArray *menuActions = [[NSMutableArray alloc] initWithCapacity:3];

// Don't show the change server option if there are no hosts to switch to.
SFManagedPreferences *managedPreferences = [SFManagedPreferences sharedPreferences];
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved this check to just be around the “Choose Connection” option instead of the settings icon but that would just be for MDM. @wmathurin what do you think about having another property like showServerPicker on the login config in case an app wants to show the settings icon but hide the change server option? Here’s the existing configuration doc: https://developer.salesforce.com/docs/platform/mobile-sdk/guide/oauth-hide-gear-icon.html

if (!managedPreferences.onlyShowAuthorizedHosts || managedPreferences.loginHosts.count != 0) {
[menuActions addObject:[UIAction actionWithTitle:[SFSDKResourceUtils localizedString:@"LOGIN_CHOOSE_SERVER"]
image:nil
identifier:nil
handler:^(__kindof UIAction* _Nonnull action) {
[self showLoginHost:self];
}]];
}


[menuActions addObject:[UIAction actionWithTitle:[SFSDKResourceUtils localizedString:@"LOGIN_CLEAR_COOKIES"]
image:nil
identifier:nil
handler:^(__kindof UIAction* _Nonnull action) {
if ([self.delegate respondsToSelector:@selector(loginViewControllerDidClearCookies:)]) {
[self.delegate loginViewControllerDidClearCookies:self];
}
}]];

[menuActions addObject:[UIAction actionWithTitle:[SFSDKResourceUtils localizedString:@"LOGIN_CLEAR_CACHE"]
image:nil
identifier:nil
handler:^(__kindof UIAction* _Nonnull action) {
if ([self.delegate respondsToSelector:@selector(loginViewControllerDidClearCache:)]) {
[self.delegate loginViewControllerDidClearCache:self];
}
}]];

[menuActions addObject:[UIAction actionWithTitle:[SFSDKResourceUtils localizedString:@"LOGIN_RELOAD"]
image:nil
identifier:nil
handler:^(__kindof UIAction* _Nonnull action) {
if ([self.delegate respondsToSelector:@selector(loginViewControllerDidReload:)]) {
[self.delegate loginViewControllerDidReload:self];
}
}]];

UIMenu *menu = [UIMenu menuWithTitle:@"" // No title
children:menuActions];
UIBarButtonItem *settingsButton = [[UIBarButtonItem alloc] initWithImage:image menu:menu];
settingsButton.accessibilityLabel = [SFSDKResourceUtils localizedString:@"LOGIN_SETTINGS_BUTTON"];
settingsButton.accessibilityIdentifier = @"settings";
return settingsButton;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ - (void)postPushUnregistration:(SFUserAccount *)user logoutReason:(SFLogoutReaso
[self setCurrentUserInternal:nil];
}

[SFSDKWebViewStateManager removeSession];
[SFSDKWebViewStateManager resetSessionCookie];

//restore these id's inorder to enable post logout cleanup of components
// TODO: Revisit the userInfo data structure of kSFNotificationUserDidLogout in 7.0.
Expand Down Expand Up @@ -1044,6 +1044,25 @@ - (void)loginViewController:(SFLoginViewController *)loginViewController didChan
[[NSNotificationCenter defaultCenter] postNotification:loginHostChangedNotification];
NSString *sceneId = loginViewController.view.window.windowScene.session.persistentIdentifier;
self.authSessions[sceneId].oauthRequest.loginHost = newLoginHost.host;
[self restartAuthenticationForViewController:loginViewController];
}

- (void)loginViewControllerDidClearCache:(SFLoginViewController *)loginViewController {
Copy link
Member Author

@bbirman bbirman Oct 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From this comment about reloading, I used the same restart method as the one that happens after the login host is changed

[SFSDKWebViewStateManager clearCacheWithCompletionHandler:^{}];
[self restartAuthenticationForViewController:loginViewController];
}

- (void)loginViewControllerDidClearCookies:(SFLoginViewController *)loginViewController {
[SFSDKWebViewStateManager resetSessionCookie];
[self restartAuthenticationForViewController:loginViewController];
}

- (void)loginViewControllerDidReload:(SFLoginViewController *)loginViewController {
[self restartAuthenticationForViewController:loginViewController];
}

- (void)restartAuthenticationForViewController:(SFLoginViewController *)loginViewController {
NSString *sceneId = loginViewController.view.window.windowScene.session.persistentIdentifier;
[self restartAuthentication:self.authSessions[sceneId]];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,18 @@
"LOGIN_SERVER_PRODUCTION" = "Production";
"LOGIN_SERVER_SANDBOX" = "Sandbox";
"LOGIN_SERVER_WELCOME" = "Welcome";
"LOGIN_CHOOSE_SERVER" = "Choose Connection";
"LOGIN_CHOOSE_SERVER" = "Change Server";
"LOGIN_ADD_SERVER" = "Add Connection";
"LOGIN_SERVER_URL" = "Host";
"LOGIN_SERVER_NAME" = "Label";
"LOGIN_SERVER_URL_PLACEHOLDER" = "Example: login.salesforce.com";
"LOGIN_SERVER_NAME_PLACEHOLDER" = "Optional";
"DONE_BUTTON" = "Done";
"LOGIN_SETTINGS_BUTTON" = "Settings";

"LOGIN_CLEAR_COOKIES" = "Clear Cookies";
"LOGIN_CLEAR_CACHE" = "Clear Cache";
"LOGIN_RELOAD" = "Reload";

// Account Switcher
"ACCOUNT_SWITCHER_TITLE" = "Manage Accounts";
Expand Down
Loading