What’s New in Mobile SDK 14.0

Mobile SDK 14.0 is a major release that features DPoP and advanced authentication by default for new logins, higher minimum iOS and Android versions, and breaking changes to Android account management, the iOS instrumentation subsystem, and native app templates.

In major releases, we typically remove items that have been deprecated. To learn about new features and breaking changes that can affect your app, read the rest of this article. In every release, be sure to check your compiler logs for deprecation warnings so that you can address these changes before they go into effect.

To upgrade an app from Mobile SDK 13.2, see Migrate All Apps from 13.2 to 14.0.

These changes apply to more than one platform.

Demonstrating Proof of Possession (DPoP) binds OAuth tokens to the device that obtained them. Mobile SDK creates and manages the per-user key material, and adds DPoP proofs to supported authentication and API requests. See OAuth 2.0 Demonstrating Proof of Possession (DPoP).

New logins request DPoP-bound tokens without an app change. Existing users keep the token type of their current credentials until they authenticate again, or until the app migrates them. To migrate an existing Bearer session, see Migrate Existing Sessions to DPoP.

To opt out for new logins, set the DPoP flag to false before authentication starts. The iOS and Android sections show the call. This setting affects new logins only. A credential that is already DPoP-bound continues to send DPoP proofs after the flag is set to false.

Until an external client app or connected app is configured to require DPoP, the server still accepts unbound (Bearer) tokens. Test DPoP-enabled login and API flows before you rely on the temporary opt-out.

Hybrid remote apps can use the UI session ID for WebView cookie injection regardless of auth type. The server returns ui_sid in DPoP token responses. See OAuth 2.0 Demonstrating Proof of Possession (DPoP).

When a session is DPoP-bound and a UI session token is available, apps can supply a path policy so that specific request paths use ui_sid Bearer authentication while every other request continues to use DPoP. By default no paths are opted in, so DPoP is used for all requests.

Advanced authentication uses a browser-based OAuth session. In Mobile SDK 14.0, it is enabled by default for every login server except welcome.salesforce.com, including login.salesforce.com and test.salesforce.com. Apps that used an embedded web view for these login servers now use a browser session. See Using Advanced Authentication.

To opt out, set forceAdvancedAuthentication to false before authentication starts. The iOS and Android sections show the call. forceAdvancedAuthentication is deprecated in Mobile SDK 14.0 and is scheduled for removal in Mobile SDK 15.0.

Test browser-based login, logout, and account switching during your upgrade.

Mobile SDK uses the OAuth web server flow by default. The user-agent flow, selected by setting useWebServerAuthentication to false, is deprecated in Mobile SDK 14.0 and scheduled for removal in Mobile SDK 15.0, or sooner if the server no longer supports that flow. Remove any code that sets the flag to false so the app uses the web server flow. See OAuth 2.0 User-Agent Flow.

Mobile SDK serializes token refresh requests per user. Concurrent refresh requests no longer race when the server rotates a refresh token. Existing apps keep working without code changes.

Mobile SDK stores SDK feature flags per user and adds them to the SDK user-agent string. The SDK records flags for the login method, the server type, and session security, including DPoP and refresh token rotation. Existing apps keep working without code changes.

To register custom SDK feature flags, use the per-user APIs in the iOS and Android sections.

Mobile SDK publishes installable agent skills that guide an AI coding agent through creating a native app, adding authentication, SmartStore, MobileSync, and biometric authentication, and upgrading a native app from 12.x to 13.x or from 13.x to 14.0. Add them to your project with:

See Build Apps with an Agent Skill and Upgrade with an Agent Skill.

React Native 0.86.0 requires the New Architecture. Mobile SDK React Native apps use bridgeless mode and TurboModule-based native bridges. The legacy architecture is no longer supported. Replace @react-navigation/stack with @react-navigation/native-stack.

  • React Native: 0.86.0
  • SQLCipher: 4.17.0

See also: General Updates in Mobile SDK 14.0.

Mobile SDK stores DPoP key material in the Secure Enclave when it is available. usesDPoP now defaults to true. To opt out of DPoP or advanced authentication for new logins, set the flag before authentication starts.

To migrate an already logged-in user, call upgradeToDPoP(_:success:failure:). The call reauthenticates with the user’s existing client ID, redirect URI, and scopes, and replaces the credentials with DPoP-bound credentials. It works independently of usesDPoP. Salesforce can still present an approval screen during reauthentication. See Migrate Existing Sessions to DPoP.

For hybrid remote apps, SFOAuthCredentials.mainSid resolves ui_sid for DPoP sessions, parentSid for JWT Bearer, or accessToken for opaque Bearer.

Mobile SDK includes client support for Salesforce App Attestation, which uses Apple App Attest to verify app and device integrity during login. Server-side enforcement is not yet generally available. Confirm Salesforce availability and configure Apple App Attest before you enable this feature in production.

To enable client-side attestation, set UserAccountManager.shared.appAttestationEnabled to true before authentication.

  • OAuth errors are available as typed SFOAuthErrorCode values. To read an OAuth error, use the typed error code. Legacy string constants are deprecated.
  • SFOAuthSessionRefresher is deprecated. Use UserAccountManager.refresh(credentials:) instead.

To register a custom SDK feature flag for a user, use SFSDKAppFeatureMarkers.registerAppFeature(_:forUser:) and SalesforceManager.shared.userAgent(qualifier:for:).

The encrypted-notification template includes actionable-notification scaffolding. It retrieves notification types, registers iOS notification categories, and handles notification actions that invoke server-side actions. See Actionable Notifications.

BiometricAuthenticationManager.automaticPresentation can present the biometric opt-in dialog after login and the biometric prompt when an opted-in user’s app locks. This includes SwiftUI apps.

Mobile SDK 14.0 removes the SDK instrumentation and signpost subsystem. Remove references to these types and APIs:

  • SFInstrumentation, SFMethodInterceptor, and SFSDKInstrumentationHelper
  • SFRestAPI+Instrumentation, SFUserAccountManager+Instrumentation, and SFMobileSyncSyncManager+Instrumentation
  • sf_os_signpost_interval_begin, sf_os_signpost_interval_end, and sf_os_signpost_id
  • SFTestContext, SFSDKAsyncProcessListener, and SFSDKOAuthSessionManaging
  • SFOAuthCoordinator.userAgentForAuth
  • signposts_post_install in Podfile post_install blocks

Replace SFSDKWebViewStateManager.removeSession() with resetSessionCookie(). The shared process-pool API is removed.

The Objective-C native app-generation template is removed. forceios now generates native apps with the Swift native_swift app type. Existing Objective-C apps continue to work with the SDK libraries.

  • Native iOS templates raise the Pod deployment target floor to 15.0. The IDP and encrypted-notification templates adopt the UIKit scene lifecycle, which fixes a launch termination on iOS 27 for apps that only implement UIApplicationDelegate.
  • The hybrid SDK replaces CocoaPods submodule references with Swift Package Manager. CocoaLumberjack is updated to 3.9.1.
  • Hybrid templates inject a post_install hook into Cordova-generated Podfiles to raise pod targets below 15.0.
  • React Native iOS templates adopt the UIKit scene lifecycle. Set RCTNewArchEnabled and UIViewControllerBasedStatusBarAppearance to YES in Info.plist.
  • Minimum deployment target: iOS 18.0
  • Base SDK: iOS 18
  • SQLCipher: 4.17.0
  • CocoaLumberjack: 3.9.1
  • Cordova iOS: 8.1.0

All Mobile SDK podspecs require iOS 18.0. Update your Podfile and Xcode project deployment target before you install Mobile SDK 14.0. If your app pins SQLCipher, update the pin to 4.17.0.

Races in SFRestAPI between token-refresh replay and task completion could run a REST completion block twice. For the Swift async API, that resumed a checked continuation twice and crashed the process. Replay and terminal delivery now run in series, so each request gets one terminal callback. A request that logout cleanup has already retired no longer publishes a network task. Network and user-agent work no longer runs while the REST lock is held, which avoids a deadlock during multi-user logout and login. Internal safe-collection writes also publish synchronously, so in-flight requests under heavy concurrent load no longer hang without a completing continuation.

These APIs are deprecated in Mobile SDK 14.0 and scheduled for removal in Mobile SDK 15.0. They still work. Compiler warnings identify them.

  • The IDP login flow has no drop-in replacement. Migrate to advanced authentication.
  • useWebServerAuthentication. The user-agent flow is retired. Use the web server flow.
  • forceAdvancedAuthentication.
  • SFOAuthSessionRefresher. Use UserAccountManager.refresh(credentials:) instead.
  • OAuth error string constants. Use typed SFOAuthErrorCode values.
  • TestSetupUtils instant-auth helpers. They are incompatible with DPoP.

Check your compiler warnings, or see iOS Current Deprecations.

See also: General Updates in Mobile SDK 14.0.

Mobile SDK stores DPoP key material in Android Keystore. Advanced authentication uses a Chrome Custom Tab. useDPoP now defaults to true. To opt out of DPoP or advanced authentication for new logins, set the flag before authentication starts. See Configuring Advanced Authentication in Android Apps.

To migrate an already logged-in user, call upgradeToDPoP(). The call reauthenticates with the user’s existing consumer key, redirect URI, and scopes, and replaces the credentials with DPoP-bound credentials. It works independently of useDPoP. Salesforce can still present an approval screen during reauthentication. See Migrate Existing Sessions to DPoP.

For hybrid remote apps, UserAccount.getMainSid() resolves ui_sid for DPoP sessions, parentSid for JWT Bearer, or the access token for opaque Bearer.

Advanced authentication requests an ephemeral Chrome Custom Tab by default. useEphemeralSessionForAdvancedAuth defaults to true, so the browser doesn’t persist cookies or session state across logins. A browser that doesn’t support ephemeral browsing can use a regular Custom Tab instead, and LoginActivity logs a warning in that case. The login options screen includes a toggle for this setting.

To opt out, set the property to false before authentication starts.

See Configuring Advanced Authentication in Android Apps.

Mobile SDK includes client support for Salesforce App Attestation, which uses Google Play Integrity to verify app and device integrity during login. Server-side enforcement is not yet generally available. Confirm Salesforce availability and provide the Google Cloud project ID when you initialize SalesforceSDKManager, before you enable this feature in production.

  • OAuth errors are available as typed OAuthErrorCode values. To read an OAuth error, use the typed error code.
  • RestClient.refreshAccessToken() is now public for apps that refresh an access token before it expires.

To register a custom SDK feature flag for a user, use SalesforceSDKManager.getInstance().registerUsedAppFeature(code, user) and SalesforceSDKManager.getInstance().getUserAgent(qualifier, user).

  • The ClientManager(Context, String, boolean) constructor is removed. Create a ClientManager with a Context and a persisted UserAccount.
  • getRestClient and RestClientCallback moved to SalesforceSDKManager.
  • peekRestClient(UserAccount) and peekRestClient(Account) are removed. Create a manager for the target user and call peekRestClient() with no arguments.
  • Unauthenticated REST client APIs are removed from ClientManager. Use SalesforceSDKManager.getUnauthenticatedRestClient().
  • Logout APIs that don’t name a user are removed. Use UserAccountManager.signoutCurrentUser(...) or signoutUser(...).
  • Account-management methods, including createNewAccount, getAccountByName, getAccounts, and removeAccount, moved from ClientManager to UserAccountManager.
  • SalesforceSDKManager.clientManager is nullable when no current user is persisted. Handle a null value in Kotlin.

Override the account_type string resource with an app-specific value. Apps that use the SDK default fail at startup.

  • Mobile SDK uses OkHttp 5. Update direct calls to RequestBody.create() for the (content, mediaType) argument order.
  • Custom push workers use ORG_ID and USER_ID. The USER_ACCOUNT WorkManager key is removed.
  • Push foreground registration now defaults to all users. To restore the previous behavior, set PushService.foregroundRegistrationMode = CURRENT_USER.
  • HybridApp.java is removed. Hybrid apps that extend HybridApp must migrate to a Kotlin Application subclass that calls SalesforceHybridSDKManager.initHybrid().

The Kotlin native template includes opt-in scaffolding for actionable notifications. Enable the supplied action adapter and broadcast receiver to handle notification actions and invoke the corresponding server-side action. See Actionable Notifications.

The Java native app-generation template is removed. forcedroid now generates native apps with the Kotlin native_kotlin app type. Existing Java apps continue to work with the SDK libraries.

  • Minimum SDK: API 31 (Android 12) or later
  • Compile SDK: API 36 or later
  • Android Gradle Plugin: 9.1.1
  • Kotlin: 2.0 or later (Mobile SDK is built with Kotlin 2.3.20)
  • SQLCipher: 4.17.0
  • OkHttp: 5.3.2
  • Cordova Android: 15.0.0

Mobile SDK 14.0 native, hybrid, and React Native templates target Android 17 (API 37). Choose the targetSdk that is appropriate for your app. Hybrid support includes Cordova Android 15.0.0.

Android Gradle Plugin 9 requires JDK 17. If your app uses a composite build with Mobile SDK, apply the Gradle settings that the SDK uses.

com.salesforce.mobilesdk:SalesforceReact is published to Maven Central from the React Native repository. The Android bridge is included in the react-native-force package and registered through React Native autolinking, so remove any direct SalesforceReact Gradle dependency.

  • DPoP proof generation caches per-user key material for the process lifetime, which removes a repeated Android Keystore lookup on every request.
  • Account resolution is cached per user again. This removes a large increase in AccountManager interprocess calls at app startup that was introduced during the 14.x work.
  • Logout clears the departing account’s refresh-coordination state, including its DPoP UI session ID, so a stale token response or a duplicate refresh does not affect a quick re-login with the same account.
  • Developer Support, including its notification and dialog, can be shown in apps that consume the SDK as a release AAR. Availability follows the consuming app’s debuggable flag, so DevInfoActivity and LoginOptionsActivity behave correctly in release builds. TestAuthenticationActivity stays debug-only.

These APIs are deprecated in Mobile SDK 14.0 and scheduled for removal in Mobile SDK 15.0. They still work. Compiler warnings identify them.

  • The IDP login flow has no drop-in replacement. Migrate to advanced authentication.
  • useWebServerAuthentication. The user-agent flow is retired. Use the web server flow.
  • forceAdvancedAuthentication.
  • TestAuthenticationActivity. It is incompatible with DPoP.

Check your compiler warnings, or see Android Current Deprecations.