Closed sortinousn closed 3 months ago
@sortinousn can you tell us more about your integration? Are you using AuthHelper.loginIfRequired
? Where do you call it from if so?
@sortinousn can you tell us more about your integration? Are you using
AuthHelper.loginIfRequired
? Where do you call it from if so?
Yes, i am using one of the SDK iOS templates for Salesforce since we want to use biometrics to allow users log in to our member portal. Our authenticated site is served through a webview (Contentview.Swift) after successful authentication with Salesforce. This is working for the most part, its only when a user gets prompted for an MFA code that they can never enter the code since when the minimize the app/background the app to retrieve the code via email or message app the MFA screen to enter the code is lost and they are back at the login screen to enter their username/password
I am thinking the authview/initial view controller is always being recreated whenever the app is foregrounded rather than restoring the view? We don't seem to have any control of the app during authentication process as it seems the sdk handles this. Is there a way to restore the MFA screen on foregrounding/backgrounding of the app?
// SceneDelegate.swift
....
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
self.window = UIWindow(frame: windowScene.coordinateSpace.bounds)
self.window?.windowScene = windowScene
SalesforceManager.shared.biometricAuthenticationManager().biometricOptIn(optIn: true)
// Define a response to user change events
AuthHelper.registerBlock(forCurrentUserChangeNotifications: {
self.resetViewState {
self.setupRootViewController()
}
})
}
func setupRootViewController() {
MobileSyncSDKManager.shared.setupUserStoreFromDefaultConfig()
// We are authenticated and redirected to authenticated member portal
self.window?.rootViewController = UIHostingController(rootView: ContentView())
}
func sceneWillEnterForeground(_ scene: UIScene) {
self.initializeAppViewState()
AuthHelper.loginIfRequired {
self.setupRootViewController()
}
}
}
...
ContentView.swift
...
struct ContentView: View {
@State private var isLoading = true
let accessToken = UserAccountManager.shared.currentUserAccount?.credentials.accessToken as? String ?? ""
let clientID = UserAccountManager.shared.currentUserAccount?.credentials.clientId as? String ?? ""
var body: some View {
let url = String("\(Environment.sf)/secur/frontdoor.jsp?allp=1&apv=1&cshc=C00000000084sfhj3e&refURL=\(Environment.sf)%2Fsecur%2Ffrontdoor.jsp&retURL=%2Fphim%2Fapex%2FPHMPCommunitiesLanding&sid=\(accessToken)&untethered=")
WebView(url: URL(string: url)!, isLoading: $isLoading)
.overlay(ActivityIndicator(isAnimating: $isLoading))
}
}
Could you try moving AuthHelper.loginIfRequired
from sceneWillEnterForeground...
to scene(_ scene: UIScene, willConnectTo...
? Here's a similar example: https://github.com/forcedotcom/SalesforceMobileSDK-iOS/blob/07d450509d7e60ee4a89ca39ece22776355555c0/native/SampleApps/RestAPIExplorer/RestAPIExplorer/SceneDelegate.swift#L41-L49
Please fill out the following details: