Posted on Leave a comment

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 a basic use case. With lightning:empApi you won’t have to deal with the CometD server handshake and authentication. All of this is automated and performed in the background for you. This means no more custom Apex controller, no JS static resources and only a few JS lines. This lets you focus on what matters the most: subscribing to events and handling errors.

Working with the lightning:empApi component

lightning:empApi is a Lightning service component and like other service components, it has no user interface of its own and exposes its functionalities via Aura methods.

In order to use it, you just have to include it your Lightning component markup:

<aura:component>
  <!-- Declare the service -->
  <lightning:empApi aura:id="empApi"/>
  
  <!-- Call the onInit controller function on component initalization -->
  <aura:handler name="init" value="{!this}" action="{!c.onInit}"/>
  
  <!-- Hold a streaming event subscription (required for unsubscribing) -->
  <aura:attribute name="subscription" type="Map"/>
<aura:component>

Then get a reference to the service in your JS controller or helper and call the service’s aura methods.

As a best practice, I recommend setting up the debugging flag (if needed) and specifying an error handler in the component initialization handler, even if you plan to subscribe to events at later point in time.

// Sets an empApi error handler on component initialization
onInit : function(component, event, helper) {
  // Get a reference to the service component via its aura:id
  const empApi = component.find('empApi');

  // Enable debug logging (optional)
  empApi.setDebugFlag(true);

  // Register error listener and pass in the error handler function
  empApi.onError($A.getCallback(error => {
    // error can be any type of error (subscribe, unsubscribe...)
    console.error('An EMP API error occured: ', error);
}));

All error types (subscribe and unsubscribe errors) are handled by a unique function passed to onError. Make sure that you call onError only once in your component’s lifespan. Calling onError multiple times overwrites the previous error handler. Doing so may lead to inconsistent error handling such as handling a subscribe error with a function that you designed to handle unsubscribe errors.

Once you have set up an error handler, you can subscribe to a streaming event. To do so, you need to get the streaming channel associated with that event. Once you have the channel, subscribe to the event with the following code:

const channel = '/data/ChangeEvents'; // Channel for all CDC Events
const replayId = -1; // Get all new events

// Get a reference to the service component via its aura:id
const empApi = component.find('empApi');

// Subscribe to a streaming event
empApi.subscribe(channel, replayId, $A.getCallback(eventReceived => {
  // Process event (this is called each time we receive an event)
  console.log('Received event ', JSON.stringify(eventReceived));
}))
.then(subscription => {
  // Confirm that we have subscribed to the event channel
  // We haven't received an event yet
  console.log('Subscribed to channel ', subscription.channel);
  // Save subscription in order unsubscribe later
  component.set('v.subscription', subscription);
});

Later on, you can unsubscribe from the event with the following code:

// Get previously saved subscription
const subscription = component.get('v.subscription');

// Get a reference to the service component via its aura:id
const empApi = component.find('empApi');

// Unsubscribe from the streaming event
empApi.unsubscribe(subscription, $A.getCallback(unsubscribed => {
  // Confirm that we have unsubscribed from the event channel
  console.log('Unsubscribed from channel '+ unsubscribed.subscription);
}));

Full ‘stream’ ahead on Trailhead

Now that we have covered the basics of streaming events and the use of lightning:empApi, how about some hands-on exercises? We have updated the Build an Instant Notification Trailhead project to use the new lightning:empApi component. Why don’t you give it at try or even retry it? You’ll notice how easy it is to use the Streaming API with platform events in less than an hour.

Resources

About the author

Philippe Ozil is a Senior Developer Evangelist at Salesforce where he focuses on the Salesforce Platform. He writes technical content and speaks frequently at conferences. He is a full stack developer and a VR expert. Prior to joining Salesforce, he worked as a developer and consultant in the Business Process Management (BPM) space. Follow him on Twitter @PhilippeOzil or check his GitHub projects @pozil.

Posted on Leave a comment

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.

Strict CSP is the recommended option as it uses the most secure CSP we can provide. With strict CSP enabled, you won’t be able to load scripts from non-Salesforce domains.

Relaxed CSP allows both unsafe-inline and unsafe-eval, as well as the ability to provide a list of whitelisted hosts for serving scripts. We provide unsafe-inline and unsafe-eval because we know some common services, such as Google Tag Manager, require these to work properly.

Once you have added your external script sources, you can execute scripts from those third-party libraries in your community. Be careful to only whitelist sites that you trust. In addition, partners and packages on the AppExchange may also require you to whitelist their services in order to work correctly.

The new security tab

These new options are available on the new Security page of your Community Builder settings.

Grandfathered

All Lighting Communities created before the Spring ‘19 release automatically use the lowest level of security to maintain backwards compatibility. This setting doesn’t use the shared CSP Trusted Sites, nor does it have defined JavaScript resources.

Existing customers can continue using their current security levels until Winter ‘20. We strongly encourage you to update your Lighting Community to one of our new options on your own before that option expires. You should be able to accomplish everything you need using the new security options.

See our Rollout plan and enforcement strategy for details.

Strict CSP

Strict CSP is the recommended and default setting for new Lightning Communities. In strict CSP, the non-script directives will follow what you allowed using CSP Trusted Sites. For the script-src directive, you won’t have access to external JavaScript resources.

Relaxed CSP

Relaxed CSP is the most flexible option. In relaxed CSP, like strict CSP, the non-script directives will follow what you have allowed using CSP Trusted Sites. But unlike strict CSP, for the script-src directive, you’ll be able to list script resources you want to make available. In the “Add Trusted Site” dialog, enter the new trusted endpoints you need to access.

 

If you later select Strict CSP, any trusted sites you have added will remain saved on your community, but will no longer be included in your policy.

Managed packages

In order to keep the trust of our vendors and partners, we must provide them the same level of control over their data and keep their data secure. We want to follow the principle of “secure by default.” This led us to a very hard question: What if a package developer only wants their code executed in a strict CSP environment?

We want to leave this choice to our partners. In order to follow the idea of “Secure By Default,” we will not be allowing Lightning components in relaxed CSP communities without the explicit consent of the package developer.

I know this sounds scary, but we expect most partners will be comfortable allowing their code in Lightning Communities without strict CSP, as packaged components would rarely contain any sensitive data about the partner’s business. In order to expose your packaged components to relaxed CSP communities, we’ve added a new Aura Interface: lightningcommunity:allowInRelaxedCSP

This must be present on every Lightning component that you want to make available in Relaxed CSP communities. Here is an example component.

–taggedComponent.cmp—

<aura:component access="global" implements="forceCommunity:availableForAllPageTypes,lightningcommunity:allowInRelaxedCSP">
    <div>This is a correctly tagged component.</div>
</aura:component>

It’s important to note that all child components must also be tagged. In the example below, you wouldn’t be able to use parent.cmp in strict CSP. This will be enforced starting Winter ‘20.

–child.cmp—

<aura:component>
  <div>This is an empty, untagged component.</div>
</aura:component>

–parent.cmp—

<aura:component access="global" implements="forceCommunity:availableForAllPageTypes,lightningcommunity:allowInRelaxedCSP">

  <div>Tagged component using an untagged component.</div>

  <YourPackage:child/>

</aura:component>

All components introduced during or after API v44 will need to include this tag in order to pass our component security validation.

Rollout plan and enforcement strategy

We understand that this is a lot to process. In order to give our developers and customers time to understand and prepare for these changes, we’re following a multi-release deployment plan.

Winter ‘19 (Oct 2018) Spring ‘19 (Mar 2019) Summer ‘19 (June 2019) Winter ‘20 (Oct 2019)
Lightning Communities Platform “Stricter CSP for Lightning Communities Critical Update” is removed
Strict CSP / Relaxed CSP communities functionality available (opt-in)
Component-level interface introduced for developers
All new Lightning Communities are defaulted to Strict CSP.
Introduce tooling for customer migration efforts (Security Meter, etc)
Enforcement Begins
Sunset support for ‘Grandfathered’ communities.
Enforcement of managed components in ‘Relaxed CSP’ communities.
Customer Action(s) Start working on migration plans to Strict CSP / Relaxed CSP. Configure & test security configurations in Sandbox, rollout to Prod Migrate all ‘Grandfathered’ communities to Strict CSP / Relaxed CSP.
Partner / Developer Action(s) Start adopting the component-level interface Start working on customer deployments / upgrades in Sandbox
Upload new package version to AppExchange (if needed)
All managed packages need to be updated, tested & deployed in Production orgs

Beginning in Spring ‘19, expect to see warning messages in the builder when selecting relaxed CSP, alerting you to any components that won’t pass component validation. When enforcement begins, any disallowed components will show the following message:

The component will not be displayed on the page. In addition, you’ll no longer be able to include components in Builder that do not pass component security validation and you won’t be able to save packages or custom components that introduce a component security violation. We can’t conduct static analysis on components created dynamically using JavaScript, such as those using $A.createComponent. Those components can be saved, but will still be validated at runtime.

Summary

We have provided new CSP options to Lightning Communities in order to enable you to build a more secure community, and we’ve provided a mechanism for our developers to protect their code. This will make Lightning Communities less vulnerable to XSS attacks and enhances the security controls for Salesforce developers and customers. We’re providing a roadmap to enforce these changes over the next several releases.

Resources

Here’s some further reading from all over the Web on what CSP is and why it is important:

About the authors

James Wonsever is a Lead Engineer on Community Cloud for four years since the inception of the Napili template. He has been involved with many parts of Community Cloud development.

Haris Ikram is a Product Manager on Community Cloud with experience on the Communities Experience Builder, Partner Communities & Salesforce Files.

Harold Gross is a Staff Technical Writer on the Community Cloud team.

Posted on Leave a comment

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 behavior of menu items (like object home pages and custom Lightning page tabs).

To gain access to the Navigation Item API, add the lightning:navigationItemAPI component into your custom component markup (.cmp) file:

<lightning:navigationItemAPI aura:id="navigationItemAPI"/>

Then in your component’s controller or helper, use Navigation Item API methods to control menu items. For example, to refresh the selected navigation object’s home page (typically the object’s list view), call the refreshNavigationItem() method as follows:

handleRefresh: function(component, event, helper){   
    var navigationItemAPI = component.find("navigationItemAPI");
    navigationItemAPI.refreshNavigationItem()
        .then(function(response) {
            // Handle response (true on success and false if there are unsaved
            // changes)
        })
        .catch(function(error) {
            // Handle error
        });
    }
}

Check out the spaceDesigner and reservationHelper components in Easy Spaces for examples of how to work with the menu item navigation methods.

New metadata type to deploy and package your Lightning themes

The new LightningExperienceTheme metadata type means you can now retrieve, deploy, and update custom themes through the Metadata API or with change sets, and add them to unlocked or managed packages. You can also manage your themes, branding assets and related metadata in source control.

We leveraged this new feature in Easy Spaces and created a fresh theme for Winter ’19:

The clarity this new metadata type enables in source is even more beautiful than the theme! Check out the new theme metadata and branding resources in the es-base-styles module. It is also included it in the latest release of the Easy Spaces unlocked packages.

New configuration format for Scratch Org creation

Winter ’19 gives you even more control over settings when creating scratch orgs. With the new settings key, you can enable, disable, or configure any setting exposed as part of the Metadata API.

{
    "orgName": "Easy Spaces",
    "edition": "Developer",
    "hasSampleData": "false",
    "features": "ServiceCloud;ServiceWave;SalesWave",
    "settings": {
      "orgPreferenceSettings": {
        "s1DesktopEnabled": true,
        "s1EncryptedStoragePref2": false,
        "isLiveAgentEnabled": true
      }
    }
}

This new syntax is used in all sample apps. The previous configuration format is scheduled to be deprecated in Spring ’19. Make sure you familiarize yourself with the new configuration file format to gain greater control with less manual configuration when creating scratch orgs.

Unlocked Packages are GA

The unlocked package feature is GA in Winter ’19. All the sample apps can be installed in two different ways:

  • From source, using the Salesforce CLI: this is the recommended option for developers who want to experience the app and make changes to the applications.
  • Using unlocked packages: this is the recommended option for non developers. Use this option if you want to experience the sample app but do not plan to modify the source code.

Blaze your own Winter ’19 trail!

We hope that you’ll enjoy Winter ’19 as much as we do and that you’ll find some inspiration in the updated Sample Gallery applications to blaze your own Winter ’19 trail, plus incorporate some of these new and exciting features into your own applications.

Additional resources

Winter ’19 Release Highlights module in Trailhead.

Posted on Leave a comment

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.

Posted on Leave a comment

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, 'Entered ' );
      }
          :
          :
      if (Test.isRunningTest ()) {
           System.debug (logginglevel.INFO, 'Exited');
      }
}

New hammer (ACCC)

private void determineCachePartition (String category, String label) {

accc_ApexEnvironment.getRuntimeEnvironment ().logger().trace('Entered');          
          :
          :

accc_ApexEnvironment.getRuntimeEnvironment ().logger().trace('Exited');

}

Using ACCC framework, you have the ability to be loosely coupled to a sink (system log, custom object, platform event, etc.) as well as vary the runtime environment (test, debug, production) behavior. As you can see, the old hammer littered the method with if/else as well as controlled the amount of information (via INFO) making the old hammer very brittle. The ACCC code can change without recompiling and testing and does not change. You are no longer coupled to new requirements, environments, and behavior.

Figure 3 ACCC framework — consistent, extendable, and reusable

Furthermore, the above code falls back to its parent class. For example, if there is an exception (i.e. DML exception, etc.) while writing to a custom object or publishing a platform event, the logger will call its parent class; in this case, accc_ApexLogger, which writes to the system debug log.

How does Apex Cross-Cutting Concerns work?

In order to satisfy the defined goal: loosely-coupled, highly-cohesive components, and then glue them back together in a flexible manner to meet different requirements based on environments, the following recipe was followed:

  1. Use SOLID Principles,
  2. Decouple the environments (test, debug, production) from the code (via custom metadata)
  3. Use Dependency Injection (DI) and Inversion of Control (IoC).

The sub-sections which follow expound upon this recipe.

SOLID Principles

SOLID Principles make it easy for a programmer to develop software that is easy to maintain and extend. SOLID defines five principles:

S – Single-Responsibility (SRP) – A class should have one and only one reason to change.
O – Open-Closed (OCP) – Class should be open for extension, closed for modification.
L – Liskov substitution (LSP) – Derived classes must be substitutable for their base classes.
I – Interface Segregation (ISP) – Make fine grained interfaces that are client-specific
D – Dependency Inversion (DIP) – Depend on abstractions, not on concretions.

Here is how SOLID principles were applied to the framework and how they benefit the user:

  • [SRP] Ensured we kept the classes singularly focused and the number of methods small. This allowed for others to easily replace sub-types (classes/methods) as well as refactor and test.
  • [OCP] If there was a need to vary the behavior of the class (i.e. logging), extensions (sub-classing) were used. This made testing the sub-classes easier because the parent was already tested; just tested the overridden methods. In addition, I could fallback to the parent’s behavior without introducing the duplicate logic.
  • [LSP] All loggers supported the same interface. One can substitute logging to a custom object (accc_ApexObjectLogging) with sending platform events (accc_ApexPublishEventLogger).
  • [ISP] Interfaces were used for specific behavior, i.e., ILogger for logging, ICache for caching, IExceptionHandler for exception handling, etc. This allows the concreteness of the logger behavior (ILogger) to be substituted at runtime.
  • [DIP] The defined abstractions/interfaces were used so one can vary implementations. The reader will note that all cross-cutting concerns can be referenced by the interface. All interfaces were prefixed with an I, for example, ILogger. This will allow users to implement new functionality without overriding current behavior.

With SOLID principles the ACCC framework can easily support many different behaviors (sub-types):

  1. Logging to System.Debug (accc_ApexLogging->accc_ILogger)
  2. Logging to a custom object, Application_Log (accc_ApexObjectLogging -> accc_ApexLogging)
  3. Logging via Platform Events (accc_ApexPublishEventLogger->accc_ApexLogging)
  4. No Logging (accc_ApexNoOpLogger→accc_ApexLogging)

Notice how all classes (above) inherited from the base class, accc_ApexLogger. This was done to ensure if an exception occurred (DML exception, etc.) the child class could invoke the parent’s write method; in this case, writing to the system debug log.

Decouple the environments

At this time, ACCC supports three runtime environments:

  1. Debug (i.e. Are you in a sandbox?)
  2. Test (i.e. Are you running in a Test (Test.isRunning)?)
  3. Production (neither item 1 nor 2)

This provides the ability to have different runtime behavior in different environments. In a production environment you may want to log to the application-log (custom) object, but in the debug environment you want to log to the System Debug Log. In test, you may not want to log at all. This is all controlled by changing the custom metadata (DI/IoC). The next section covers the metadata.

Dependency Injection (DI) and Inversion of Control (IoC)

The cross-cutting concerns/aspects use custom metadata types to allow runtime behavior to be changed. There are three custom metadata types. However, in this blog, only two are discussed.

  • Accc_Apex_Code_Configuration__mdt contains the concrete classes that implement the interfaces. These concrete classes are then loaded by the object factory and exposed via the runtime engine.
  • AcccCrossCuttingUtilityData__mdt holds singleton values such as, log-level, tracing on/off, caching strategy turned on, etc.
  • AcccDataCachingDataModel__mdt defines aspect of data caching (Which is covered in the Wiki in the GitHub repo, but not in this blog).

accc_Apex_Code_Configuration__mdt?

This metadata holds the concrete class names. To provide a bit more context, ACCC defines a core set of runtime interfaces. For example, logging (accc_ILogger), exception handling (accc_IApexExceptionHandler), caching (accc_ICache), etc. These interfaces rely on an implementation. When the runtime is referenced, it uses a factory to load the implementation by reading this custom metadata. It is this metadata which can be changed at runtime to vary execution behavior (the underlying implementation). Additionally, a developer is able to define new concrete classes that adhere to the interface/behavior (see the four different loggers) which can also be injected at runtime and different environments.

The observer will note there are three defined environments (Production, Debug, and Test). These defined environments allows one to further alter which behavior will be used. For example, if you look at test configuration below (outlined in red), you will see that the logging behavior is defined to use accc_ApexLogger (which writes to the system-debug log) in the test environment; while in the production environment, accc_ApexObjectLogger, is defined (which writes data to a custom application log when called).

Again, it should be noted that we are speaking on just the logger aspect. There are other aspects (caching, exception handling, caching strategy, etc.) which this blog does not cover (see the Wiki for more discussion on the other aspects).

AcccCrossCuttingUtilityData__mdt ?

This custom metadata type defines singleton values used to control finer details such as Log-Level, Caching Strategy On/Off, tracing, etc.

For example, in the above configuration, the production environment will log with Info details and will use a caching strategy, if caching is used (i.e. accc_CacheMgr), to determine whether a called SOQL expression should be cached. Show CC Information indicates whether to allow the cross-cutting code to write to the logger. Normally, you would not because it adds to the log data about ACCC code. However, enabling this flag will include log information from the ACCC framework. LogLevel for Trace provides a means to provide more detail information (see the below section on Log Level Information for more details).

Log level information

The trace method in logging uses log level to provide a convenient (controllable) way to write additional information to a sink. For example, the code below writes more information to the sink than what you see in the code below. This is controlled by the log level defined in the custom metadata (see previous section), LogLevel for Trace. This provides the ability to write more or less information out to the sink via configuration.

//
// The trace in the CCC code is can be turned off via ShowCC flag (see custom metadata).
//
private string getCachePartition(String category, String label) {
    String partition = accc_ApexConstants.DefaultCachePartitionName_s;
    accc_DataCachingDataModel.CacheInformation info = this.cacheInformation(category, label);
    
    accc_ApexEnvironment.getRuntimeEnvironment().logger().trace('Entered');
    if ( info != null ) {
        partition = info.cachePartition;
    }
    accc_ApexEnvironment.getRuntimeEnvironment().logger().trace('Exited, partition=' + partition);

    return partition;
} // end of getPartition

For example, selecting a Log Level of Finest (LogLevel for Trace) and enabling tracing (custom metadata, AcccCrossCuttingUtilityData__mdt), you would see the following additional information in the log (Note: the above code was extracted from the accc_ApexCacheMgr class and is an example only).

The above granularity applies to the following LogLevel: INTERNAL, ERROR and FINEST.

The following LogLevel values are defined below along with the additional information written to the sink:

  1. INTERNAL, ERROR and FINEST will add LogLevel, Class Name, Method Name, Line Number, User- Message, Start Time, Start Time (Long), Stack trace
  2. FINER will add LogLevel, Class Name, Method Name, Line Number, User- Message, Stack trace
  3. FINE will add LogLevel, Class Name, Method Name, Line Number, User- Message
  4. DEBUG will add LogLevel, Class Name, Method Name, User-Message
  5. None of the above will add LogLevel, User- Message

Furthermore, all loggers use accc_ApexLogFormatter (which inherits from accc_IDataFormat) to write the log level information to the sinks. This is advantageous because you can change what/how gets added to the sink.

The custom metadata configuration above shows the class, accc_ApexLogFormatter as the Log Formatter. Because this class is used by ALL the loggers to add log level information, you can change the log level data written to the sinks. Thus, if you did not want the LogLevel to be written out in the log, you can easily change this as well. Note: For long term compatibility, code changes made should be done via inheritance; thus, create a class call MyLogFormatter and inherit from accc_ApexLogFormatter and override the appropriate methods.

Conclusion

Whether Cross-Cutting Concerns or code in general, Salesforce provides the ability to extend code to support clicks as demonstrated in the Salesforce Cross-Cutting Concerns framework (ACCC). There are other aspects in the framework we did not cover in this blog for brevity. Unfortunately, with extensibility comes complexity. However, the Wiki found on GitHub provides considerable information on logging and the other cross-cutting concerns supported to provide more clarity.

I hope you have found it useful and/or informative. It is only the start as there are other layers (data, business, service, presentation) we have yet to touch.

To learn more about this topic in Trailhead, check out the Custom Metadata Types module.

Posted on Leave a comment

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.

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.

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

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!

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.

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.

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.

That’s not all — the first Developer Golden Hoodie was revealed and it went to David Liu!

Get the highlights from the DF18 Developer Keynote in this new trailmix. Follow along and complete it by October 31st and earn a special Codey badge.

Posted on Leave a comment

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.

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.

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.

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.

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.

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.

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 from TrailheaDX’18.

Salesforce evangelists Zayne Turner and René Winkelmeyer took us on a journey through developing with Salesforce DX, utilizing unlocked packages and other tools you can use to modernize delivery cycles. If you haven’t checked out their blog series on unlocked packaging yet, it’s a good place to get started.

Dreampitch made a triumphant return! A panel of industry luminaries like will.i.am and Emily Chang came together to find the next great startup built on the Salesforce Platform. Three entrepreneurs had five minutes each to pitch their companies live on stage for a chance to win a $250,000 investment from Salesforce Ventures. Find out more about the finalists here.

We’ll be closing out the night with Dreamfest featuring Janet Jackson and Metallica, putting a whole new spin on “Ride the Lightning.”

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

Posted on Leave a comment

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!

 

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.

 

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.

 

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.

 

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.

Posted on Leave a comment

#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.

Tuesday

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.

Wednesday

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 question the value of this approach. So, after much information gathering and analysis, it was determined by senior leadership that the ultimate goal is still single org for sales, but leveraging a multi-org model along the journey.

Managing 40 Million Sensors Worldwide with an IoT App Built on Heroku

Wednesday, September 26, 2:30 PM – 2:50 PM
Keeping track of the thousands of parts and spares in a manufacturing plant is a daunting task. Leveraging Heroku and IoT, Endress + Hauser delivered a mobile app for plant managers to easily track the 40 million parts they sell worldwide, leading to massive savings in time and budget.

Design and Deploy Secure, Compliant Business Apps with Salesforce Shield

Wednesday, September 26, 3:00 PM – 3:40 PM
At Salesforce, trust is our top priority. Earning that trust from our enterprise customers, especially those in regulated industries like Financial Services, requires that we meet rigorous security and compliance requirements. Join us to hear how Fidelity Investments and City National Bank, an RBC Company, translated their security and compliance requirements to an actionable plan with Salesforce Shield. Learn how they architected their Salesforce deployments, along with Salesforce Shield, to deliver secure, compliant, and performant business solutions.

Thursday

Data Integration Heroes!

Thursday, September 27, 8:45 – 9:05 AM
Join us to dive into the new world of MuleSoft within Salesforce. Managing data integration is commonly one of the most important aspects of a Salesforce implementation. Companies need to have a good data migration strategy when they move from their legacy systems to Salesforce, or simply when they want all their systems to seamlessly communicate. You’ll learn how to use the out-of-the-box connectors provided by the MuleSoft Anypoint Platform to build scalable data integrations and flows with minimal code.

Lightning Performance Management & Scalability Best Practices
Thursday, September 27, 9:45 AM – 10:05 AM
Join us as customers and Salesforce architects share how you can help ensure a performant and scalable Lightning-enabled implementation. You’ll hear real-world insight on optimizing Salesforce in large, complex enterprises, leveraging Lightning Performance Management & Scalability Best Practices.

Build an Amazing Enterprise Rockstar Solution with Ladies Be Architects

Thursday, September 27, 11:00 – 11:40 AM
Grab your magic markers and join Ladies Be Architects for an hour of solution design. Think you’re just a clicker? Well, you don’t need to know how to code. We’ll be working together on a hypothetical scenario, so be prepared to roll up your sleeves and have fun with your architect friends of all levels and abilities. #DF18Partners

Developer Keynote: Build the Future of Apps
Thursday, September 27, 1:00 PM – 2:00 PM
People now expect apps of the future; continuously improving, integrated, and smarter. As developers, you are more empowered than ever to build these apps. Join this developer keynote and be the first to see how the Salesforce Platform can help you build apps faster, integrate apps easily, and make apps smarter.

Friday

Build and Test AI Models for Trust (1)
Friday September 28, 9:00 AM – 9:20 AM
MachinelLearning 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.

Decouple Architectures with High Volume Platform Events Using Clicks and Code (2)
Friday, September 28, 11:45 AM – 12:05 PM
High volume platform events unlock high-throughput, high-value event-based architectures to replace fragile and point-to-point integrations. Learn how decoupled, real-time apps can be built using Apex triggers, workflows, and the Streaming API. Jumpstart your knowledge of platform events and event-driven systems with this fast-paced session.

Data Mapping: Tips to Being Successful with the Latest Salesforce Innovation

Friday, September 28, 12:30 PM – 12:50 PM
Join us as we explore how the new field mapping editor helps you enable integrated experiences between your Salesforce clouds. The Design Team will discuss the process of creating the Field Mapping Experience and share best practices for preparing data for mapping and integration.

If you can’t join us in-person, you can check out the Developer Keynote online. Mark your calendar for Thursday, September 27th at 1:00 PST and join us for our livestream here.

Posted on Leave a comment

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.

Building iOS apps with Swift and the Salesforce Mobile SDK

The Salesforce Mobile SDK incorporates all the benefits of Swift, Apple’s flagship programming language, and allows you to build custom mobile applications on Salesforce with great services such as:

  • Offline synchronization of Salesforce data with SmartSync
  • Encrypted storage with SmartStore

Let’s take a quick look at how easy it is to synchronize data between your iOS app and Salesforce with this Swift code sample:

Taking a look at this code, you can immediately see that it is both simple and powerful. Let’s review:

  1. Target: specify which records you want to sync.
  2. Options: define sync logic. For example, you can set the sync to overwrite modified records or leave them alone.
  3. Soup: This value might look delicious, but it’s a self-contained data set (or table) in the underlying SQLite database that comes with the Salesforce Mobile SDK. It typically maps to a standard or custom object.
  4. SyncName: create, delete, run or re-run a named sync operation at runtime

In addition to powerful Mobile SDK features like secure storage and out-of-the-box synchronization, you access to a ton of trusted enterprise services from the Salesforce platform, without having to reinvent the wheel, such as:

  • Access control, authentication, user management, and mobile device management
  • Social collaboration and file storage with Chatter
  • Salesforce Mobile Push Notification Services
  • Massively scalable mobile backends on Heroku

As part of this partnership, Salesforce and Apple are working together to optimize Swift support in the Salesforce Mobile SDK. The new SDK will make it easier for developers to use native iOS features and constants and enums are now namespaced for better discoverability. A developer preview of the new SDK will be coming soon!

Start learning with Trailhead and join us at Dreamforce

Together, Salesforce and Apple are launching new learning content on Trailhead to help everyone learn how to build native iOS apps with Swift and Xcode. Effective today, you can take the new Get Started with iOS App Development trail and earn the following badges:

  • Swift Essentials – new!
  • Xcode Essentials – new!
  • Salesforce Mobile SDK Basics
  • Native iOS

By taking this trail, you will get a hands-on introduction to Swift, create a basic iOS app with Xcode, and learn how to leverage data and services from Salesforce in a secure, trusted environment. Updates to the Salesforce Mobile SDK Basics and Native iOS modules are coming this fall, and all of this content is available free on Trailhead today.

And if you’re joining us at Dreamforce, make sure to stop by the Apple and Salesforce area in the Trailhead Zone (Moscone West, 1st floor) to earn your Swift and Xcode badges on Trailhead.