Last July, I started writing a series focused on how the Salesforce platform can be utilized in a manner without a traditional Salesforce client. Here are links to the other articles in the series: \ * [Leveraging Salesforce Using Spring Boot](https://hackernoon.com/how-to-leverage-the-salesforce-api-without-the-salesforce-client) * [Leveraging Salesforce Using a Client Written In Svelte](https://hackernoon.com/how-to-leverage-salesforce-using-a-client-written-in-svelte) * [Leveraging Salesforce Using a Client Written In Vue.js](https://hackernoon.com/leveraging-salesforce-using-a-client-written-in-vuejs) * [Leveraging Salesforce Using Mobile Applications Written (Once) In React Native](https://hackernoon.com/leveraging-salesforce-using-mobile-applications-written-once-in-react-native) * [Leveraging Salesforce Using a Client Written In Angular](https://hackernoon.com/how-to-leverage-salesforce-via-a-client-written-in-angular) \ A graphical representation of the series is shown below: \  The illustration above shows how various client frameworks can access the Salesforce data without actually utilizing clients provided by the Salesforce ecosystem. \ In November 2021, I started a new series to demonstrate the [Salesforce Mobile SDK](https://developer.salesforce.com/docs/atlas.en-us.mobile_sdk.meta/mobile_sdk/intro.htm), which harnesses the power of the Salesforce platform within standalone mobile apps. \ A graphical representation of this new series is shown below: \  “[Exploring the Salesforce Mobile SDK Using React Native](https://hackernoon.com/build-a-mobile-app-using-react-native-and-the-salesforce-mobile-sdk)” was the first article in this Mobile SDK series. I then switched gears for the “[Exploring the Salesforce Mobile SDK Using Android Studio](https://hackernoon.com/using-android-studio-to-explore-the-salesforce-mobile-sdk)” article to leverage Android Studio. In this article, I will focus on using Xcode to produce the same application. ## Benefits of the Salesforce Mobile SDK The Salesforce Mobile SDK provides several benefits for software engineers: \ * Allows custom mobile device applications to utilize Salesforce features and functionality * Full access to Salesforce functionality (no need to reinvent the wheel) * Applications can be distributed using the application store of the native device * Processing push notifications from Salesforce * The ability to work with Salesforce data in an offline mode \ If your application landscape utilizes Salesforce for key aspects of business operability, then consider leveraging the Salesforce Mobile SDK. By doing so, you can integrate data maintained by Salesforce into key component locations, allowing you to make strong business decisions. ## Benefits of Using Xcode If your client base requires support for iOS devices and you wish to use Xcode for app development, then you’ll find value in the `forceios` CLI for getting started quickly with Salesforce functionality. \ Key features for teams employing Xcode include: \ * Allows use of Swift or Objective-C as the base programming language * Provides 100% native support for features and functionality on iOS devices * Allows experienced iOS developers to quickly leverage Salesforce Mobile SDK functionality * Improvements in error handling, because both Swift and Objective-C maintain a strong typing and error handling design * Identify and fix build issues easier \ It may be obvious but you must have an Apple computer to use Xcode. For this article, I will be using my 16” MacBook Pro from March 2020. \ Now that we’re ready to dive in, let’s briefly review our use case. ## Finny’s Foods: An Example Use Case Having a son (Finny) born with special needs introduced a personal desire to gain an understanding and appreciation of the products we use in our daily life. Years before Finny was born, my wife (Nicole) and I lived a healthy lifestyle. However, as Nicole began deep-diving into the ingredients in the foods that made up our daily diet, we received a much-needed wake-up call. \ Fast-forward to today, our diet consists of few processed foods, no gluten, low sugar, and very little dairy. As much as possible, our protein originates from grass-fed sources, and we always favor organic options. Don’t get me started on GMO. \ For this series, our Finny’s Foods application provides a simple list of meals that are both acceptable to us and favored by Finny. For now, we will include two simple attributes for each meal: \ * Name of the meal * Rating (1 to 5, where a rating of 5 is an absolute favorite for Finny) \ Over time, I plan to introduce other attributes (such as summary, ingredients, directions, and even a photo), but let’s walk before we run. ## Getting Started with Xcode In addition to installing `git` and `npm` on my MacBook Pro, I made sure my Xcode version was up to date. Next, I visited the following URL to make sure everything was set up and configured as expected: \ [Set Up Your iOS Development Environment](https://developer.salesforce.com/docs/atlas.en-us.mobile_sdk.meta/mobile_sdk/ios_quickstart.htm) \ These steps include making sure Xcode, CocoaPods, node.js, npm, and the `forceios` CLI are all installed. \ Next, I executed `forceios` from a terminal session with the following options: \ ```javascript forceios create Enter your application type (native_swift or native, leave empty for native_swift): native_swift Enter your application name: FinnysFoodsIOS Enter your package name: com.gitlab.johnjvester.finnysfoods.ios Enter your organization name (Acme, Inc.): JVC Enter output directory for your app (leave empty for the current directory): Once completed, I followed the steps provided by the forceios CLI: ****************************************************************************** * * Next steps: * * Your application project is ready in FinnysFoodsIOS. * To use your new application in XCode, do the following: * - open FinnysFoodsIOS/FinnysFoodsIOS.xcworkspace in XCode * - build and run * Before you ship, make sure to plug your OAuth Client ID and Callback URI, * and OAuth Scopes into FinnysFoodsIOS/FinnysFoodsIOS/bootconfig.plist * ****************************************************************************** ``` \ ## Creating the Meal Object in Salesforce Before I could begin creating a new application in Xcode, I needed to establish the Meal object in Salesforce. \ I already had a Developer org that I could use. (You can create a new one [here](https://developer.salesforce.com/docs/atlas.en-us.externalidentityImplGuide.meta/externalidentityImplGuide/external_identity_create_developer_org.htm).) So, I simply logged in using my email address and password for that org. Next, I navigated to the **Apps | App Manager** and the **Setup** perspective in Salesforce. \ I created a new Lightning App called Meal: \ \  \ On the remaining setup screens, I selected all the default settings and granted access to all Salesforce User Profiles. \ Next, I visited the **Objects & Fields | Object Manager** menu option in the Salesforce Settings. Once I located the newly-created Meal item, I used the drop-down component to **Edit** the object. \ I switched from the **Details** submenu to the **Fields & Relationships** option. I quickly realized I did not need to create a Name property for my Meal object since Salesforce already took care of that for me. I just needed to add the Rating field. \ Using the **New** button, I selected the **number** field type and populated Step Two as noted below: \ \  \ I used the default values and saved my new field. Now, I can use both the name and rating fields in my iOS application. \ \  \ Using the Salesforce client, I populated some source data to develop the application in Xcode. Below is a summary of the submitted values: \ \  \ Based upon the sample data, Finny always prefers ”Pizza” over “Chicken & Rice”. ## Adding Meal Functionality in Xcode With the source object and data configured, I used my Xcode application to open the `finnys-foods-ios` project for the first time. \ By default, the `forceios` CLI creates a working application that displays Account and Contact information for the Salesforce org tied to the user account when running for the first time. To make things easier, I decided to go ahead and remove the following files from the project: \ * AccountsListModel.swift * AccountsListView.swift * ContactDetailModel.swift * ContactDetailsView.swift * ContactsForAccountListView.swift * ContactsForAccountModel.swift \ Since I plan to cover offline functionality in a future article, I updated the configuration data in the `userstore.json` to: \ ```javascript { "soups": [ ] } ``` \ The `usersyncs.json` file was also purged as shown below: \ ```javascript { "syncs": [ ] } ``` \ Next, I created a basic list view for the `Meal__c` object in Salesforce, called `MealsListView.swift`. \ ```javascript import Foundation import SwiftUI import Combine import SalesforceSDKCore struct MealsListView: View { var body: some View { Text("Finny's Foods (iOS)").bold() } } struct MealsList_Previews: PreviewProvider { static var previews: some View { MealsListView() } } ``` \ To use the meals list view when the application starts, I updated the `setupRootViewController()` method in the `SceneDelegate.swift` file as shown below: \ ```javascript func setupRootViewController() { // Setup store based on config userstore.json MobileSyncSDKManager.shared.setupUserStoreFromDefaultConfig() // Setup syncs based on config usersyncs.json MobileSyncSDKManager.shared.setupUserSyncsFromDefaultConfig() self.window?.rootViewController = UIHostingController( rootView: MealsListView() ) } ``` \ At this point, we have a functional iOS application that will merely show “Finny’s Foods (iOS)” using bold text. ### Using Font Awesome in Xcode Before I built out the rest of the application, I wanted to see how easy it would be to add Font Awesome icons in a Swift application created in Xcode. As you may recall, this task was super easy with React Native and not-so-easy in Android studio. \ I was able to use the steps provided at the following URL to get things working in about 15 minutes. I fully expect those with Xcode experience to complete these steps in a fraction of the time: \ [Easy Font Awesome in SwiftUI](https://iosexample.com/easy-font-awesome-in-swiftui/) \ As a result of these steps, the following supporting files are now part of my project: \ * fa-brands-400.ttf * fa-regular-400.ttf * fa-solid-900.ttf * icons.json ### Creating a Meals List Model The Xcode application needs to understand the `Meal__c` object which is driving the Finny’s Foods application. I created a `MealsListModel.swift` file which contained the following information: \ ```javascript import Combine import SmartStore import MobileSync struct Meal: Hashable, Identifiable, Decodable { let id: UUID = UUID() let Id: String let Name: String let Rating__c: Int } struct MealResponse: Decodable { var totalSize: Int var done: Bool var records: [Meal] } class MealsListModel: ObservableObject { @Published var meals: [Meal] = [] private var mealsCancellable: AnyCancellable? func fetchMeals(){ let request = RestClient.shared.request(forQuery: "SELECT Id, Name, Rating__c FROM Meal__c ORDER BY Name ASC", apiVersion: nil) mealsCancellable = RestClient.shared.publisher(for: request) .receive(on: RunLoop.main) .tryMap({ (response) -> Data in response.asData() }) .decode(type: MealResponse.self, decoder: JSONDecoder()) .map({ (record) -> [Meal] in record.records }) .catch( { error in Just([]) }) .assign(to: \.meals, on:self) } } ``` \ This file introduces a **Meal** object that contains the meta-data for each `Meal__c` object stored in Salesforce. There is also a `MealResponse` object, which represents the payload provided by Salesforce when asking for `Meal__c` data. With those two key structures defined, the `fetchMeals()` method makes a RESTful API call to Salesforce, then maps any response data to a list of **Meal** objects. The `MealsListView.swift` file created earlier then processes this data. ### Updating the Meals List View With the Meals List Model ready, the Meals List View can now be expanded to integrate with Salesforce and present data onto an iOS device. The first thing I had to do was establish a variable for the Meals List Model in the `MealsListView.swift` file: \ ```javascript struct MealsListView: View { @ObservedObject var viewModel = MealsListModel() ``` \ Next, I updated the body variable in the `MealsListView.swift` file as shown below: \ ```javascript var body: some View { Text("Finny's Foods (iOS)").bold() List(viewModel.meals) { dataItem in HStack(spacing: 10) { VStack(alignment: .leading, spacing: 3) { HStack { Text(dataItem.Name) } } } } .onAppear{ self.viewModel.fetchMeals() } ``` \ At this point, the iOS application shows the name of each meal on a new line. The `fetchMeals()` method call retrieves data from Salesforce, processing each `Meal__c` item as dataItem. \ However, I really wanted to add the star-rating system used in the React Native project. To do this, I updated the inner-most `HStack` object as shown below: \ ```javascript HStack { Text(dataItem.Name) Text(" ") switch dataItem.Rating__c { case 5: FAText(iconName: "star", size: 15, style: .solid) FAText(iconName: "star", size: 15, style: .solid) FAText(iconName: "star", size: 15, style: .solid) FAText(iconName: "star", size: 15, style: .solid) FAText(iconName: "star", size: 15, style: .solid) case 4: FAText(iconName: "star", size: 15, style: .solid) FAText(iconName: "star", size: 15, style: .solid) FAText(iconName: "star", size: 15, style: .solid) FAText(iconName: "star", size: 15, style: .solid) FAText(iconName: "star", size: 15) case 3: FAText(iconName: "star", size: 15, style: .solid) FAText(iconName: "star", size: 15, style: .solid) FAText(iconName: "star", size: 15, style: .solid) FAText(iconName: "star", size: 15) FAText(iconName: "star", size: 15) case 2: FAText(iconName: "star", size: 15, style: .solid) FAText(iconName: "star", size: 15, style: .solid) FAText(iconName: "star", size: 15) FAText(iconName: "star", size: 15) FAText(iconName: "star", size: 15) default: FAText(iconName: "star", size: 15, style: .solid) FAText(iconName: "star", size: 15) FAText(iconName: "star", size: 15) FAText(iconName: "star", size: 15) FAText(iconName: "star", size: 15) } } ``` \ With these changes in place, the iOS application is ready for use. ## Finny’s Foods in Action Using Xcode, I used the **Product** menu option and selected the **Run** option. First-time use will automatically redirect to a Salesforce login screen, where I used the same email address and password to access my Developer org. After signing in, the Finny’s Foods application appeared, including the five-star rating value for each item. \  In a matter of minutes, we were able to create an iOS application using Xcode and the Salesforce Mobile SDK. ## Conclusion In this article, I introduced a custom mobile application that deploys natively from the Apple store and uses source code written in Swift. Along the way, we gained a basic understanding of how iOS-based applications are structured. \ Starting in 2021, I have been trying to live by the following mission statement, which I feel can apply to any IT professional: \ > “Focus your time on delivering features/functionality which extends the value of your intellectual property. Leverage frameworks, products, and services for everything else.” > > \ > \- J. Vester \ The Salesforce Mobile SDK certainly adheres to my personal mission statement, which will benefit any feature team that requires Salesforce functionality as part of custom mobile applications running on iOS devices. Software engineers in this realm of development should certainly consider adding the Salesforce Mobile SDK as a project dependency. \ If you wish to see the full source code for this article, visit my project on GitLab: \ <https://gitlab.com/johnjvester/finnys-foods-ios> \ Have a really great day!