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

322 Views Asked by At

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()
                }
            }
        }
2

There are 2 best solutions below

2
Dima On BEST ANSWER

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.

0
deadbeef On

You need to unwrap allAccounts because it's an optional array. And since force unwrapping has been used above to get numberOfAccounts, it's probably safe to use it.

Try this:

SFUserAccountManager.sharedInstance().currentuser = allAccounts![0]