Category: Salesforce

Building Real-Time Lightning Apps Gets Even Simpler

Building modern apps that react to changes in real-time used to require some implementation effort, but the latest update to our streaming technologies greatly simplifies things. In this post we will go through a brief refresher on the Streaming API and we will introduce you to a new way of subscribing to streaming events using the lightning:empApi component. We’ll give you an overview of this game changer plus some sample code.

A brief refresher on the Streaming API

The Streaming API enables the streaming of near real-time events using push technology. This can be used to react to data changes or to broadcast messages across different systems for integration purposes.

With the release of Change Data Capture (CDC) in Developer Preview in Winter ’19, the Streaming API now includes four types of events: PushTopic events, generic events, platform events and CDC events. Each of these event types have their own characteristics but they all rely on the same routing technology: CometD.

In other words, CometD acts as a radio and all streaming events are registered as channels. These are the streaming channels currently available:

Event type Channel Description Example PushTopic event /topic/<Topic_Name> A PushTopic event /topic/MyPushTopic Generic event /u/<Event_Name> A generic event /u/MyGenericEvent Platform event /event/<Platform_Event_Name> A platform event /event/MyPlatformEvent__e CDC event /data/ChangeEvents All CDC events (standard and custom) CDC event /data/<Standard_Object_Name>ChangeEvent A CDC event associated to a standard object /data/AccountChangeEvent CDC event /data/<Custom_Object_Name>__ChangeEvent A CDC event associated to a custom object /data/MyCustomObject__ChangeEvent

Up till Winter ’19, developers had to manually manage CometD connections in JS in order to subscribe to streaming events in Lightning. Now times are changing! What used to be a rather complex setup is now greatly simplified with lightning:empApi, a new Lightning component that streamlines the use of the Streaming API (pun intended).

A game changer

If you were already establishing and managing CometD connections in Lightning, you’ll quickly see why lightning:empApi is a game changer: it provides an abstraction layer that increases performance and greatly reduces code complexity.

Performance increase

lightning:empApi increases streaming performances by saving some precious time on the CometD server connection initialization and reducing network traffic.

What happens behind the scenes is that as soon as a Lightning page loads, we are establishing a CometD connection in the background. This was already the case prior to Winter ’19 but we were reserving that connection for internal use. You had to establish your own connection in parallel for custom components.

With lightning:empApi you can now benefit from a single shared connection. Thanks to that, you no longer have to configure CometD, establish a connection, and wait for it to become available before subscribing to a streaming event. This reduces network traffic and solves potential connection conflicts you might have experienced in the past. You can now safely and efficiently add multiple lightning:empApi components to the same page.

Reduced code complexity

lightning:empApi greatly reduces code complexity by allowing you to get rid of close to a hundred lines of code for

Introducing New Content Security Policy Options for Lightning Communities

Trust has always been our #1 value here at Salesforce. We hold ourselves accountable for keeping your data secure at all times.

Community Cloud helps you build a digital experience for your customers, partners, and employees to interact with your company. Often, this requires bringing in resources from third parties (such as Google) in order to provide a comprehensive solution that fits your needs. With the Winter ‘19 release, we’ve added additional security options so that your new Lightning community has the flexibility to use the external resources you need.

The browser’s Content Security Policy (CSP) is a defense in-depth mechanism – it reduces the harm that malicious code can cause. CSP works by defining the “Content-Security-Policy” HTTP header, which instructs the browser what resources it can render or execute. It is meant to be used in addition to proper development patterns in order to mitigate potential damage from Cross-Site Scripting (XSS) attacks. To learn more about XSS, check out our Secure Coding Guidelines. We have, and will continue to provide, XSS protection for Salesforce components.

The combined policy

CSP for Lightning Communities is split into two parts. One part references the set of CSP directives shared with Lightning Experience (LEX). The second part is an additional set of script-src directives that are specific to each community.

Shared CSP directives

In LEX , we already support many CSP directives:

connect-src frame-src img-src style-src font-src media-src

As of Winter ‘19 our new Lightning Communities CSP can use these directives as well.

This means that non-script resources included in a Lightning Community will need to have their URLs added to CSP Trusted Sites before going live with the new security options. For example, if you are loading images from a third-party host in your head markup, you will need to whitelist that host on the CSP Trusted Sites page. Entries in the CSP Trusted Sites whitelist can be applied to LEX, all Lightning Communities, or both.

You can modify your CSP Trusted Sites in Setup under Security > CSP Trusted Sites.

Each of the trusted sites that is declared in that UI is given a name (e.g. “GoogleMaps”) which may be referenced elsewhere in our platform. Each of the trusted sites is also persisted in the CSPTrustedSites entity.

Script Src

In addition to the other directives, we are now adding a way to include additional third-party scripts on the page. Script resources can’t be added to CSP Trusted Sites in LEX at this time.

This is a much more complex area, as much of the XSS protection offered by CSP requires you to implement strict CSP. Strict CSP defines tight constraints on the script-src directive so that only trusted scripts can be executed. However, in many business applications, it is not possible to implement strict CSP and include all of the third-party services necessary for your business. To give you flexibility, the Winter ‘19 release offers two new levels of security for Lightning Communities: strict CSP and relaxed CSP.



What’s New in Sample Apps for Winter ’19

Winter ’19 is here with new and exciting features for developers! Like always, we have updated the Sample Gallery applications to leverage the features available in this new release. We are excited to share the Winter ’19 version of the sample apps in this blog post.

New Lightning Components

Winter ’19 comes with new components like lightning:map, lightning:menuDivider, and lightning:menuSubheader. Check out the Component Library to familiarize yourself with these new components as well as the existing ones. There are now 157 components available out-of-the-box!

As an example, the lightning:map component is used in the DreamHouse app to show the property location on the record page.

You can add a map to a component with a single line of code:

<lightning:map mapMarkers=”{!v.mapMarkers}” zoomLevel=”{!v.zoomLevel}” />

Check out the RecordMap component to learn more.

New and easy way to subscribe to Streaming API topics and platform events

lightning:empApi is another new component that makes it easy to subscribe to Streaming API topics and platform events. You no longer have to use a static resource to import a version of a CometD library.

To subscribe to a Streaming API topic or a platform event, simply add lightning:empApi to the markup (.cmp) file of your custom component:

<lightning:empApi aura:id=”empApi” />

Then, add the following code to your component controller or helper:

subscribe: function (component, event) { var empApi = component.find(“empApi”); var channel = “YourChannelName”; var replayId = -2; empApi.subscribe(channel, replayId, $A.getCallback(function(message) { // handle message })); }

Usage in sample apps:

In PureAloe, lightning:empAPI is used to subscribe to the BundleStatusChange Streaming API topic (bundlePath component) and to the Field_Status_Change__e platform event (harvestFieldMap component). In Northern Trail Outfitters, lightning:empAPI is used to subscribe to the MixStatusChange Streaming API topic (MixPath component), and to the Einstein_Event__e platform event (EinsteinTwitterFeed component). New Apex caching annotation

Winter ’19 makes it easy to cache Apex method call responses at the client-side and improve the performance of your applications. Prior to Winter ’19, you had to call setStorable() in JavaScript on every action object that called an Apex method whose response you wanted to cache.

var action = component.get(“c.getItems”); action.setStorable(); action.setCallback(this, function(response) { // handle response }); $A.enqueueAction(action);

In Winter ’19, you can now centralize your caching strategy directly in Apex controllers by annotating methods with @AuraEnabled(cacheable=true).

@AuraEnabled(cacheable=true) public static List<String> getItems() { }

Usage in sample apps:

The new caching annotation is used throughout all the sample apps to improve their performance. For example, check out:

PropertyController.cls in Dreamhouse FundController.cls in DreamInvest MerchandiseController.cls in PureAloe MerchandiseController.cls in Northern Trail Outfitters CustomerServices.cls and MarketServices.cls in Easy Spaces

Read this blog post to learn more about storable (or cacheable) actions, but remember to use the new syntax.

New Lightning Console JavaScript API methods

Winter ’19 changes the default navigation behavior of menu items in console apps. As a developer, you can use new methods of the Navigation Item API (part of the Lightning Console JavaScript API) to programmatically control the


Upcoming Maintenance on Developer Edition Signup for Winter ‘19

Heads up, Salesforce Developers and #AwesomeAdmins – we will be performing maintenance on our sign-up infrastructure this weekend to bring the Winter ’19 Release to new Developer Editions and Admin Playgrounds. During this maintenance window, you will not be able to sign up for brand-new accounts, but you WILL be able to access your existing accounts.

Here’s the timeline for this upcoming maintenance:

Friday, Oct 12th, 2018 at 4 PM PST: New Developer Edition sign-ups pause and maintenance window begins. Saturday, Oct 13th, 2018 at 2 AM PST: Sign-ups resume for users in the AMER (North, Central, & South America) & EMEA (Europe, Middle East & Africa) regions. Saturday, Oct 13th, 2018 at 2 PM PST: Maintenance window ends. Sign-ups resume for all users.

These times are approximate, so make sure you are following @SalesforceDevs on Twitter for updates. If you think you will need a new Developer Edition during the maintenance window, we encourage you to sign up for a new Developer Edition right away. Again, access to existing Developer Editions will not be affected.

Want to learn more about the exciting Winter ‘19 release? Check out our Winter ’19 Release Readiness broadcast.

Configuration First: Replacing Code at Runtime

At Salesforce you have heard the saying “Extend Salesforce with Clicks, Not Code.” However, there are times we must code to extend Salesforce — why not extend code to support clicks? After all, using configuration to change the runtime behavior of code is possible, if you are willing to follow good design principles and use the provided aspects in Apex.

This blog post will provide more details as how one might go about the “configuration first” in code. This post will specifically only address logging (cross-cutting concern); however, the other concerns (caching, exception handling, etc.) follow the same pattern.

Which hammer?

Take Logging for example. It seems easy but it can become an issue no matter how small or large the project is. Here are issues I have experienced (you may as well):

Too verbose Not verbose enough Disagreement on log level Disagreement on which layer to log Inconsistent logging behavior

Figure 1 Complexity of where to log?

Even if you could agree upon some of the above aspects, you still encounter code like:

private void determineCachePartition(String category, String label) { if(Test.isRunningTest()){ System.debug(logginglevel.INFO , ‘Entered ‘ ); } : : if(Test.isRunningTest()){ System.debug(logginglevel.INFO ,‘Exited‘); } }

Figure 2 Example logging code

Why is this considered a problem? The above code is only writing to the system debug log and only during tests. In production, or not running tests, it provides no value when trying to determine entry/exit for users. In addition, the class and method were excluded and only informational data is provided. The tightly coupled dependent code has the following issues:

Dependent upon system debug log Dependent upon test execution Tightly coupled to INFO logging level and system log No means to vary the logging level or output content

As you can see, something like logging is more challenging than you may think. Couple this with different development teams, experience, changing requirements, and needs and the problem becomes more exacerbated — and this is only logging! Taking other cross-cutting concerns into consideration (exception handling, caching, etc.) we begin to see our code becomes very brittle and subject to software rot. We need the right hammer to address these issues.

New hammer / Apex Cross-Cutting Concerns

As discussed previously, these issues with logging surface in other cross-cutting concerns. We need to find a new hammer. This new hammer has a goal. The goal is to split code into loosely-coupled, highly-cohesive components and then glue them back together in a flexible manner to meet different requirements based on environments. To realize this goal, I decided to develop an unmanaged package I called Apex Cross-Cutting Concerns/ACCC (found in GitHub).

Cross cutting concerns are aspects, such as, logging, exception handling, caching, etc. which are found in your basic code layers, i.e., Presentation, Business and Data; thus, cross-cutting

Let’s go back to the original example and compare the old hammer with the new hammer.

Old hammer

private void determineCachePartition (String category, String label) { if (Test.isRunningTest ()) { System.debug (logginglevel.INFO,


Developers at #DF18: Developer Keynote and More on Day 3

The third day of Dreamforce 2018 brought us the Developer Keynote and a very special surprise! Of course, there were lots of sessions presented by our community and other keynotes and events in the Trailhead Zone and around the Dreamforce campus. We’ve got all the highlights right here for you.

Salesforce MVP Gaurav Kheterpal delivered a session on Storefront Reference Architecture (SFRA) in Commerce Cloud, talking about how to leverage it for mobile-first sites.

Learning a lot about @CommerceCloud SFRA from @gauravkheterpal

— Peter Knolle (@PeterKnolle) September 27, 2018

In a Trailblazer Community Campfire session, Radhika Bansal and Daniel Peter spoke about utilizing Trailblazer Community Groups to connect with other developers, even when you’re traveling.

@RadhikaBansalSF & @danieljpeter sharing the experiences and benefits they have had by travelling and connecting with the @Salesforce #TrailheadCommunity #DF18 @AccentureTech

— Kerry Townsend (@KerryTownsend) September 27, 2018

Dan Appleman, CTO of Full Circle Insights, taught developers how to build custom configuration pages with Lightning components and custom metadata.

@danappleman teaching a full Developer Theater about custom configuration pages with Lightning components and custom metadata

— Paul Battisson (@pbattisson) September 27, 2018

John Daniel from Rootstock Software and John Storey from MIL Corp talked about advanced tools and techniques to adopt Salesforce DX for unlocked packages. Did you miss this session today during your time at DF18? They’ll be presenting again tomorrow at 8AM PST!

Absolutely JAM packed session to hear @ImJohnMDaniel & @stohn777 demonstrate how to adopt #SalesforceDX Unlocked Packages #DF18

— Alex Sutherland (@apexsutherland) September 27, 2018

Day 3 across all of Dreamforce focused on Equality, with a couple of fireside chats and the Equality Summit Keynote featuring Tracee Ellis Ross and Adam Rippon.

“When you have access you are given not only the opportunity — but the responsibility to use it!” @Adaripp #DF18 #EqualityForAll

— Office of Equality (@SalesforceEQ) September 28, 2018

We are all using Trailhead to learn, and it is constantly evolving. Sarah Franklin, the EVP of Developer Relations and GM of Trailhead, along with Chris Duarte, Kris Lande, Leah McGowen-Hare and a few Trailblazers, spoke about best practices to drive Salesforce adoption and scale onboarding with your own branded and customized content with myTrailhead.

@TheChrisDuarte: The real magic of @trailhead is that it is hands-on”

💯 agreed. And for me that is also what makes it so fun! #DF18

— Jacob Lehrbaum (@jlehrbaum) September 27, 2018

Last but definitely not least, all eyes were on the Developer Keynote! Christophe Coenraets, Zayne Turner, Qingqing Liu, and Margaret Francis told us all about building apps of the future: faster, more integrated, and smarter. Through demos and Trailblazer stories, we learned all about the latest and exciting developments in building on Salesforce.

A lot of familiar faces at the @SalesforceDevs keynote! #DF18

— Adam Olshansky (@adam17amo) September 27, 2018

@ccoenraets is talking about how you can build apps fast in


Developers at #DF18: The Fun Continues on Day 2

Day 2 of Dreamforce brought out some heavy hitters in the developer world. From Salesforce co-founder Parker Harris discussing the future of IdeaExchange, to our developer evangelists offering valuable insight on the various uses of Salesforce DX, it was a big day in the world of developing. Check out more #DF18 highlights here.

Flagstar Bank’s lead Salesforce developer Jay Janarthanan sparked the Trailblazer Community Campfire with valuable insights on the Salesforce Connector for Mulesoft and its various use cases like platform events, ETL, composite messages, and more.

It’s on! So many trailblazers came to hear from @JayOnSoftware… join us!

— MuleSoft Developers (@MuleDev) September 26, 2018

Salesforce MVP and TexeiFrance CTO Fabien Taillon gave a talk on how he moved his company’s developer workflow over to Salesforce DX and unlocked packages, and why they’re here to stay.

@FabienTaillon telling @SalesforceDevs about how he moved @TexeiFrance to implement #SalesforceDX and #UnlockedPackages @Dreamforce #DF18

— John M. Daniel ☁ (@ImJohnMDaniel) September 26, 2018

David Frudd, senior developer at FinancialForce, talked accessibility and building the apps everyone loves, syncing social inclusivity with building your own Lightning Components and Lightning Apps.

@frup42 talking about accessibility – salesforce for all ! @FinancialForce @SalesforceDevs #DF18

— Alba Rivas (@Alba_ARivas) September 26, 2018

We held our always-popular Meet the Developers session. The technical leadership team at Salesforce sat down for some Q&A with attendees. It was a valuable opportunity to hear directly from the product owners and engineers who build all aspects of the Salesforce Platform.

Meeting the Developers Breakout #DF18 @SalesforceDevs

— Jennifer W. Lee (@jenwlee) September 26, 2018

The Integration Keynote featured Pop Health’s Mike Berger, Unilever’s Reema Jain and Jane Morgan, and MuleSoft’s Mark Dao, Vidya Peters, and Greg Schott. Together, they covered integration, the customer touchpoint, and how MuleSoft helps them create more connected experiences for their customers.

We want to create frictionless experiences. Anypoint Platform is how we’re getting there. – Mike Berger, @MountSinaiNYC VP #DF18

— MuleSoft (@MuleSoft) September 26, 2018

Salesforce co-founder Parker Harris joined Bret Taylor, Kristen Engelhardt, Eric Jacobson, and Jennifer Sacks to discuss the future of a more transparent IdeaExchange, making way for meaningful, progressive dialogue around product direction and the Trailblazer Community’s role in that initiative.

Parker Harris is previewing our re-energized IdeaExchange with Bret Taylor. We’re re-committed to listening to our customers’ ideas about how our products can be even better. The Ohana rocks! @salesforce #DF18 @parkerharris @btaylor

— Stephanie Buscemi (@sbuscemi) September 26, 2018

Salesforce developer evangelism director Peter Chittum talked about the Salesforce CLI and how it can be used to connect with many parts of your org aside from Application Lifecycle Management. He also offered hands-on examples to boost your productivity. As Peter has said a few times, if you can write a Salesforce formula, you can use the command line. For proof, check out one of his previous sessions on writing command lines

Developers at #DF18: Check Out the Fun from Day 1

Dreamforce ’18 kicked off with a bunch of sessions for our developers, the Dreamforce Keynote, and even a visit from a couple of familiar faces! Check out some of the action here:

Salesforce developer evangelists Zayne Turner and Rene Winkelmeyer spoke about VS Code to a packed room. At DF18 and missed the session? They’ll be presenting again on Friday!


Kicking off our 8am session @Dreamforce about @code for @SalesforceDevs with packed room!

— René Winkelmeyer ☁ (@muenzpraeger) September 25, 2018

Salesforce MVP Christian Szandor Knapp and Frankfurt User Group leader Daniel Stange presented a session on enhancing your triggers with the open source MyTriggers framework by Appero. Check it out in this GitHub repo.


Start with the MyTriggers framework now to enhance your trigger handling now!
Proudly presented at Dreamforce18 by @ch_sz_knapp & @stangomat and developed and open sourced by @appero_com @SalesforceDevs

— Christian Menzinger (@chris_menzinger) September 25, 2018

Salesforce product superstars Andrew Fawcett and Wade Wegner presented a super session on all things Salesforce DX. The all-demos session was a deep dive on new and improved tools, metadata coverage and usability, and change management to increase productivity and make developers lives better. Check out some of the code in Andy’s GitHub repo.


Packed room for Salesforce DX super session! One of the most interesting topics for @SalesforceDevs at #D18 @WadeWegner @andyinthecloud

— Mohamed El Moussaoui (@melmoussaoui) September 25, 2018

Salesforce CEO Marc Benioff — along with a slew of special guests — officially kicked Dreamforce off with the Opening Keynote. Benioff said this is the biggest Dreamforce yet, with 2,700 sessions, 171,000 in-person attendees, and 10 million+ joining online. Each day of Dreamforce is dedicated to a key value that we are working on and promote within ourselves and express back to our community: Trust, Innovation and AI, Equality and Sustainability, and Personal Empowerment and Mindfulness.


“Allow me to express my sincere gratitude to all of you for all you do — our customers, our partners, our communities, our Trailblazers. Every day you guide us further and show us the way to be connected.” Salesforce Co-CEO Marc @Benioff live at #DF18:

— Salesforce (@salesforce) September 25, 2018

All areas of the Trailhead Zone were bustling, including the Developer Forest. Our friends Codey and SaaSy even popped in for a visit!

To close out the evening, we entertained and engaged with attendees with interactive games (Including Programmers, PRESENT! — an improv style activity) in the Canyon Theater.

Stay tuned on our blog and social networks (Twitter, Facebook, and Instagram) for all of the Day 2 goodness! Whether you’re joining us on-site in San Francisco or remotely, you can be part of the Developer Keynote for Day 3 (Thursday, September 27th at 1PM PST). Bookmark the session in the Salesforce Events app or save the link for our livestream.


#DF18 Developer Guide: Sessions for All the Architects!

Dreamforce ’18 is any minute now! Whether you are already an architect with Salesforce, or whether you’re exploring how to be one, we’ve curated a few great sessions for you to check out at Dreamforce.


Build and Test AI Models for Trust (2)

Tuesday, September 25, 8:30 AM – 8:50 AM
Machine learning software differs from traditional software in that outcomes are not based on a set of hand-coded rules and are not easily predictable. The behavior of such software changes over time-based on data and feedback loops. The results and predictions of a machine learning model are not always clear. Join us to learn how Salesforce Einstein provides you with insights into why models behave the way they do, and build trust and confidence as a result. We’ll cover model explainability, and how we seamlessly integrate this into the machine learning pipeline.

The Architect Journey: Becoming a Domain or Technical Architect
Tuesday, September 25, 9:00 AM – 9:40 AM
For Salesforce architects who have the technical ability, business acumen and drive to push their limits. Salesforce CTA is the certification that opens career-transforming opportunities to solve Salesforce customers’ greatest business challenges. Come hear top tips from the experts on what it takes to achieve the most prestigious credential.

Architecture of End-to-End Einstein Solutions
Tuesday, September 25, 9:30 AM – 10:10 AM
The architecture of the Einstein Platform is an important element for developers and architects to understand. Which components typically make up an Einstein feature? In this session, we’ll cover the general principles illustrated with solution architectures and best practices from different customer examples, such as Einstein Vision for Retail or CPG companies, Einstein Next Best Action in customer communities, and Einstein Bots for customer service.

Practical Architecture Strategies for Banking
Tuesday, September 25, 12:00 AM – 12:40 AM
Banks struggle to provide customer engagement solutions due to the sheer number of core product platforms. Join us as we cover proven architecture strategies for delivering a customer engagement platform using Financial Services Cloud.

Architect Journey—Discovering Your Path (2)

Tuesday, September 25, 5:30 PM – 6:00 PM
Whether you wear one or many hats in your role, we’ve got a specialized domain Designer certification that will validate your specific area of expertise. Join us to learn more about Designer certifications and the resources available to build your knowledge, that will help you on your path toward becoming a Salesforce Architect.


Org Consolidation in a Post Merger Environment
Wednesday, September 26, 8:30 AM – 9:10 AM
Join us as we discuss how to develop and execute on a consolidation journey after companies not only combine people and processes, but orgs as well. We’ll cover the new challenges companies don’t anticipate, and the new way that IT and business teams need to work together to build a better seamless experience for the combined companies.

Cox Automotive Switches Gears for Sales Success Through Org Consolidation
Wednesday, September 26, 9:30 AM – 10:10 AM
Join us to learn how after making a run at a single org for sales, Cox Automotive’s leadership in the various BU’s began to

Empowering Everyone to Build World-Class iOS Apps with Salesforce

Today everything is connected and everything is mobile. People expect access to their data and their apps across all their devices, and this means that as developers we have more work to do than ever. To make it easier to build amazing, enterprise-class mobile apps, Apple and Salesforce have announced a strategic partnership to redefine the mobile customer experience and to empower learning for all.

For developers, this partnership gives you access to the tools and educational resources you’ll need to start building custom apps for iOS that leverage customer data from Salesforce. These resources include an all-new Salesforce Mobile SDK for iOS optimized for Swift, and new learning content on Trailhead built in collaboration with Apple.

Let’s start by taking a look at how Swift makes it easy to build great apps on iOS.

Introduction to Swift

Swift is a modern programming language that is perfect for developing mobile apps, and is designed to be safe, fast, and expressive. Some of the features that make Swift a modern language include:

Clean, easy to read, declarative syntax Powerful error handling and throwing capabilities Built-in type safety and inference Handles values that might not exist with new Optional type Simple functional computations with map, filter, reduce Developed in the open, with community input and support – and much more!

Let’s take a look at how simple it is to read a Swift code sample:

As you can see, the syntax is simple and is to understand – even at first glance! Next, let’s take a look at a slightly more complicated code sample where we define a Type called person that contains two variables for First Name and Last Name. And then we’ll also define two instances of the person using constants.

When coding in Swift you get a unique feature called Optional to define variables that may or may not contain a value, as well as modern capabilities like Switch statements to efficiently handle things like flow control. Let’s take a look at how this works:

The first thing you might have noticed when you look at this code sample is that you can use emojis when defining constants, variables and values! While that’s a fun and useful way to code in the modern era, what’s even more exciting is the power you get from the Optional type and switch statement features. At the start of the code sample, we defined a variable called animal as an optional string indicated by “String?” and set its value to 😺. We then evaluated the Optional to see if it had a value and used the switch statement (via case) to further evaluate our value. Here’s how it looks in the Xcode IDE and you can see the expected value printed out in the console at the bottom of the screenshot below:

Now that you’ve had a quick introduction to Swift, let’s take a look at how you can start building iOS apps that connect to Salesforce data.