Search code examples
iosswiftsalesforce-ios-sdk

Build Failed: Value of optional type '[SFUserAccount]?' not unwrapped


A newbie to native swift development! Opened the below issue in https://github.com/forcedotcom/SalesforceMobileSDK-iOS/issues/2072

Version of Mobile SDK Used: 5.1.0
Issue found in Native App or Hybrid App: Native App
OS Version: 10.12.5
Device: iPhone 6

Steps to reproduce:

  1. forceios create
  2. Provided application type as native_swift and add other requested details
  3. Open the *.xcworkspace file in Xcode
  4. Build the project

Error: Value id optional type '[SFUserAccount]?' not unwrapped;

    func handleSdkManagerLogout()
        {
            self.log(.debug, msg: "SFAuthenticationManager logged out.  Resetting app.")
            self.resetViewState { () -> () in
                self.initializeAppViewState()

                // Multi-user pattern:
                // - If there are two or more existing accounts after logout, let the user choose the account
                //   to switch to.
                // - If there is one existing account, automatically switch to that account.
                // - If there are no further authenticated accounts, present the login screen.
                //
                // Alternatively, you could just go straight to re-initializing your app state, if you know
                // your app does not support multiple accounts.  The logic below will work either way.

                var numberOfAccounts : Int;
                let allAccounts = SFUserAccountManager.sharedInstance().allUserAccounts()
                numberOfAccounts = (allAccounts!.count);

                if numberOfAccounts > 1 {
                    let userSwitchVc = SFDefaultUserManagementViewController(completionBlock: {
                        action in
                        self.window!.rootViewController!.dismiss(animated:true, completion: nil)
                    })
                    if let actualRootViewController = self.window!.rootViewController {
                        actualRootViewController.present(userSwitchVc!, animated: true, completion: nil)
                    }
                } else {
                    if (numberOfAccounts == 1) {
                        SFUserAccountManager.sharedInstance().currentUser = allAccounts[0]

// ERROR: Value id optional type '[SFUserAccount]?' not unwrapped;
                    }
                    SalesforceSDKManager.shared().launch()
                }
            }
        }

Solution

  • The allUserAccounts property of SFUserAccountManager is nullable.

    - (nullable NSArray <SFUserAccount *> *) allUserAccounts;
    

    https://github.com/forcedotcom/SalesforceMobileSDK-iOS/blob/master/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFUserAccountManager.h#L188

    If you know for a fact that it will exist at the time you are trying to use it, you can perform a force unwrap by typing allAccounts![0]. If you need to handle the case where it may be nil, you need to check for that by doing something like:

    if let accounts = allAccounts
    {
       currentUser = accounts[0]
    }
    else
    {
       // does not exist
    }
    

    What I can't tell you is whether it being nil is actually a valid case that you need to handle, as I am not familiar with the library. You'll need to do the research or ask them yourself.