What’s New in Mobile SDK 9.0?

I’m so excited to announce that the new version of the Salesforce Mobile SDK is now available. Mobile SDK 9.0 is focused on developer and end-user productivity. Regardless of whether you’re building iOS apps, Android apps, or cross-platform apps, you and your end-users will love the enhancements in this release.

Your multitasking end-users will jump for joy with our support for multiple windows for iPadOS. Manage different accounts, records, and use cases side-by-side.

You spoke, we listened. Based on developer feedback, we have added an external ID to eliminate duplication of records after a sync restart for parent/child info. No need to code this yourself, we’ve done it for you.

And… we highlight the power of open source. We’ve incorporated TypeScript for React Native with the help of a community contribution! Now, React Native developers can leverage the debugging and error detection features of TypeScript early and often during mobile app development.

If this is your first introduction to the Salesforce Mobile SDK, head straight to Trailhead and check out the Develop with Mobile SDK trail to get started today.

You can also review the release notes for SDK for iOS and SDK for Android to view all the changes for this release.

Release Highlights

  • SDK for iOS
    • Multiple windows support for iPadOS
    • Landscape improvements for iOS devices
  • SDK for React Native
    • TypeScript for React Native
    • Modernized Templates
  • General
    • External ID for Parent / Child Sync Up
    • OS & Library Updates

SDK for iOS

Salesforce + Apple = Better together. Deliver impactful customer experiences by leveraging best of breed Apple hardware, the latest Mobile SDK features, and Salesforce’s world-leading CRM. In this release, Mobile SDK expands on our partnership with Apple by fully supporting Apple iOS 14 and iPadOS 14 features, adding support for multiple windows, and making landscape orientation improvements. Upgrade your apps to the latest release to take advantage of iOS 14 and iPadOS 14 capabilities.

To learn more about developing for Salesforce & Apple iOS, review Getting Started with iOS App Development.

Apple iOS 14

Starting with Mobile SDK 8.3, you can leverage all the new features from Apple iOS 14. Create App Clips, Widgets, Augmented Reality and more. Learn more about Apple iOS 14 features for developers here.

OS and Library updates
iOS base SDK is now 14 (instead of 13) and min version is 13 instead of 12.

Apple iPadOS 14

With Mobile SDK 9.0, you can leverage the new features of Apple iPadOS and specifically iPadOS 14. With the latest Mobile SDK, developers can take advantage of features like copy/paste, multitasking, split view and more when building for iPad, all without making additional changes to your applications.

To add multiple windows support for iPadOS apps, you will need to use new methods in Mobile SDK 9.0. Learn more in the next section. Learn more about Apple iPadOS features for developers here.

Multiple windows support for iPadOS

Apple added support for multiple windows on iPad starting with iOS 13. This means that a single app can have two windows running side-by-side sigh each window doing its own thing.

In Mobile SDK 9.0, we now provide support for multiple windows for iPadOS applications. Enabling this feature in your application allows your end-users to be more productive. As an example, an end-user can work on two different records simultaneously and copy/paste from one window to the other. The multitasking benefits are endless.

Apple iOS has the concept of scenes, which ultimately enables the multiple windows feature. Each scene is associated with a scene session which has a unique identifier. For the remainder of this section, the “window” feature will be referred to as a “scene”.

To implement this feature in new or existing Mobile SDK applications, developers need to use new methods to properly manage the login flow. Mobile SDK takes care of the rest.

Learn more about multiple windows for iPadOS here.

Login
For end-users, the login flow is very simple. The app will show a login screen if the user has not authenticated anywhere yet. Once the end-user completes a successful login in one scene, Mobile SDK applies this to all scenes and triggers each scene’s login completion block. Logging out of one scene would also apply to all scenes. You can view an example of this in the image below.

SFSDKAuthHelper provides a standard and recommended way to do login flow – and this class has been enhanced with new methods that take a scene parameter. Developers will need to use these new methods to properly manage multiple scenes in the login flow.

In addition, RestAPIExplorer now has a scene delegate that uses these methods.

The example below shows two of the methods in use.

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

        AuthHelper.registerBlock(forCurrentUserChangeNotifications: scene) {
            self.resetViewState {
                self.setupRootViewController()
            }
        }
        self.initializeAppViewState()
        AuthHelper.loginIfRequired(scene) {
            self.setupRootViewController()
        }
    }

IDP
If you are using advanced auth with IDP, scene delegates have a method for opening URLs similar to an app delegate, so an IDP client app with multiple scenes would need to use the scene delegate and pass in the scene’s persistent identifier. The code below provides an example of this.

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    if let urlContext = URLContexts.first {
        UserAccountManager.shared.handleIdentityProviderResponse(from: urlContext.url, with: [UserAccountManager.IDPSceneKey: scene.session.persistentIdentifier])
    }
}

New methods in SFSDKAuthHelper

As I mentioned, there are four new methods for scene support in SFSDKAuthHelper. You will need to use these to properly manage the login flow for multiple scenes.

  • (*void*)loginIfRequired:(UIScene *)scene completion:(*nullable* *void* (^)(*void*))completionBlock;
    • Initiate a login flow if the user is not already logged in to Salesforce and if the app config’s `shouldAuthenticate` flag is set to false.
  • (*void*)handleLogout:(UIScene *)scene completion:(*nullable* *void* (^)(*void*))completionBlock;
    • Handles user switching or presenting a login screen for the scene.
  • (*void*)registerBlockForCurrentUserChangeNotifications:(UIScene *)scene completion:(*void* (^)(*void*))completionBlock;
    • Triggers the logout flow for the given scene upon notification and registers a block to run on user switch.
  • (*void*)registerBlockForLogoutNotifications:(UIScene *)scene completion:(*void* (^)(*void*))completionBlock;
    • Triggers the logout flow for the given scene upon notification.

For more information about how these methods are used, review the Mobile SDK developers guide.

Enable in XCode project settings
In addition to the above methods, you’ll also need to update the project settings for your application in XCode. An app enables multiple scenes through the app target’s general settings in the “Deployment Info” section.


Known limitations
There are a few limitations to be aware of when enabling multiple scenes for your application.

  • App passcode is not currently supported with multiple windows, so if an app uses passcode, they shouldn’t enable multiple windows.
  • A limitation to the login simplicity is the inability for a user to login to their sandbox environment in one scene and production environment in another scene.

Landscape improvements for iOS devices

The Mobile SDK has supported landscape mode for awhile now. However, we’ve received feedback from customers that end-users were experiencing instances where the iPhone or iPad unexpectedly switched to portrait mode. Login is an example of when the switch to portrait occurred.

For Mobile SDK 9.0, we changed our view controllers to support all device orientations instead of being hardcoded to portrait in certain instances. We also made sure that the sizing is correct right after rotation.

All you need to do here is to update your Mobile SDK app to the 9.0 version.

SDK for React Native

Our React Native SDK has a few awesome updates this release to help increase developer productivity.

OS and library updates
React Native is now at 0.63.4 (which addresses some XCode 12 issues)

TypeScript for React Native

TypeScript is an open source programming language created by Microsoft to help developers build and maintain enterprise-grade JavaScript applications. It is a superset of JavaScript which primarily provides optional static typing, classes, and interfaces. TypeScript has gained popularity in the last few years among frontend developers for its ability to help catch errors sooner, its code consistency, and debugging capabilities.

For more information see: https://www.typescriptlang.org/

For Mobile SDK 9.0, the React Native JavaScript modules were rewritten in TypeScript.

If you already have an existing Mobile SDK for React Native application, your application does not need to change.

If you’re creating a new application, you can now choose to write your React Native application in JavaScript or TypeScript. Applications written in TypeScript can now leverage the typed APIs to do static validation of their code. View the new TypeScript modules here.

New template: ReactNativeTypeScriptTemplate
Mobile SDK 9.0 also added a new React Native template that uses TypeScript called ReactNativeTypeScriptTemplate. We recommend that TypeScript developers generate their application based on that template to get started, so we’ve made this the default template.

To build a new application based on that template, do the following:

forcereact create

React Native templates modernized

We’re always looking for ways to modernize Mobile SDK and integrate the latest technologies. In addition to adding TypeScript to our React Native SDK, we’ve also modernized our React Native templates.

Starting with Mobile SDK 9.0, applications generated with forcereact will auto-link their dependencies. When you add a dependency, you only need to add it to your package.json – you don’t need to change the podfile anymore. Native libraries for your dependency will automatically be linked into your project.

General updates

External ID for Parent / Child Sync Up

In Mobile SDK 8.0, we enhanced single record and batch sync up to allow sync up by external ID (upserts).

Upserts are useful to avoid duplication. If the network disconnects while a sync up happens, a client might not know if its last request made it through or not. Re-running the sync without using upsert will create a duplicate if the original create request had actually been received by the server. With an upsert, the replayed request will do nothing (it will do an update that sets the same values for the fields).

We received feedback from our developer community that some of you were running into issues with duplicate records being created during parent / child sync up. To help alleviate this issue and remove the need for developers to code their own solution, the Mobile SDK has added the same external ID capability to parent / child sync up for 9.0.

When an external ID field name is provided in the parent info or children info, and a locally created parent or child record has a value for that field, the Mobile Sync engine will do an upsert instead of a create against the server.

In order for this External ID to do an upsert, you need to do the following:

  • Declaratively: add custom fields of type external ID to the relevant objects in your org.
  • Mobile app: choose between managing the external ID sync up through a syncs config file or programmatically.

Declaratively
In your Salesforce org, create a custom field on the object for the parent or child information. The field can have any name, and can even be an existing field. The field name you specify here will need to match what you put in the syncs config or use programmatically.

On the mobile client, in the parent and children info, they should specify: externalIdFieldName: “the-actual-custom-field-name”.


In the syncs config example below, the field name is:

  • ExternalIdX for the parent.
  • ExternalIdY for the children.
{
   "syncName":"parentChildrenSyncUp",
   "syncType":"syncUp",
   "soupName":"accounts",
   "target":{
      "iOSImpl":"SFParentChildrenSyncUpTarget",
      "androidImpl":"com.salesforce.androidsdk.mobilesync.target.ParentChildrenSyncUpTarget",
      "parent":{
         "idFieldName":"IdX",
         "externalIdFieldName":"ExternalIdX",
         "sobjectType":"Account",
         "modificationDateFieldName":"LastModifiedDateX",
         "soupName":"accounts"
      },
      "createFieldlist":[
         "IdX",
         "Name",
         "Description"
      ],
      "updateFieldlist":[
         "Name",
         "Description"
      ],
      "children":{
         "parentIdFieldName":"AccountId",
         "idFieldName":"IdY",
         "externalIdFieldName":"ExternalIdY",
         "sobjectType":"Contact",
         "modificationDateFieldName":"LastModifiedDateY",
         "soupName":"contacts",
         "sobjectTypePlural":"Contacts"
      },
      "childrenCreateFieldlist":[
         "LastName",
         "AccountId"
      ],
      "childrenUpdateFieldlist":[
         "FirstName",
         "AccountId"
      ],
      "relationshipType":"MASTER_DETAIL"
   },
   "options":{
      "fieldlist":[
         
      ],
      "mergeMode":"LEAVE_IF_CHANGED"
   }
}

Programmatically
On iOS, create your parent info and/or children info passing a non-null externalIdFieldName to the new factory methods.

// From SFParentInfo.h
+ (SFParentInfo *)newWithSObjectType:(NSString *)sobjectType
                            soupName:(NSString *)soupName
                         idFieldName:(NSString *)idFieldName
           modificationDateFieldName:(NSString *)modificationDateFieldName
                 externalIdFieldName:(NSString * __nullable) externalIdFieldName;

// From SFChildrenInfo.h
+ (SFChildrenInfo *)newWithSObjectType:(NSString *)sobjectType
                     sobjectTypePlural:(NSString *)sobjectTypePlural
                              soupName:(NSString *)soupName
                     parentIdFieldName:(NSString *)parentIdFieldName
                           idFieldName:(NSString *)idFieldName
             modificationDateFieldName:(NSString *)modificationDateFieldName
                   externalIdFieldName:(NSString * __nullable)externalIdFieldName;

On Android, create your parent info and/or children info passing a non-null externalIdFieldName to the new constructors.

// From ParentInfo.java public ParentInfo(String sobjectType, String soupName, String idFieldName, String modificationDateFieldName, String externalIdFieldName)  // From ChildrenInfo.java
public ChildrenInfo(String sobjectType, String sobjectTypePlural, String soupName, String parentIdFieldName, String idFieldName, String modificationDateFieldName, String externalIdFieldName)

OS and library updates

In addition to all the cool new features are the OS and library updates expected in a new major release of the Mobile SDK:

  • SDK for iOS
    • iOS base SDK is now 14 (instead of 13) and min version is 13 instead of 12
  • SDK for Android
    • Android target API is 30 (instead of 29)
  • SDK for Hybrid
    • Cordova iOS is 6.1.1 (instead of 5.1.1) which uses WKWebView and can consume cocoapod dependencies natively (previously we had to use third party plugins), Cordova Android is 9.0.0 (instead of 8.1.0) and Cordova CLI is 10.0.0 (instead of 8.1.2)
  • SDK for React Native
    • React Native is now at 0.63.4 (which addresses some XCode 12 issues)
  • General
    • sqlcipher is 4.4.2 (instead of 4.4.0)
    • cocoapod min version is 1.8 (instead of 1.7.5)

Conclusion

Mobile SDK 9.0 has something for everyone. Add the power of multitasking to your existing iPad apps. Leverage external IDs to be confident that users won’t see duplicate records even if the sync restarts for parent / child sync up. Take advantage of powerful debugging and catch errors sooner with TypeScript for React Native. Grab these new features for yourself and end-users today by upgrading your mobile applications to Mobile SDK 9.0.

View Mobile SDK for iOS and Mobile SDK for Android.

 

Other resources

Salesforce provides mobile tools to help verify that your Lightning Web Components work everywhere – especially on mobile. Check out the Salesforce Mobile Tools playlist on the Salesforce Developers YouTube channel.

 

About the authors

Sue Berry is a Director of Product Management at Salesforce where she focuses on Salesforce Mobile. She’s currently working on Salesforce Mobile SDK and the new Mobile tools for LWC debugging. She has been building developer tools for over 15 years.

Brianna Birman is a lead engineer on Salesforce Mobile SDK and has worked on Salesforce Mobile products for the last seven years.

Wolfgang Mathurin is an architect in the Salesforce Mobile Platform team and has worked on Salesforce Mobile products for the last ten years. He has been in development for over 20 years.