Salesforce Mobile Services
Salesforce Mobile Services
Table of Contents
Preface................................................................................................................................................1
Salesforce Platform Mobile Services..........................................................................................................................................2
Mobile Services in Force.com........................................................................................................................................2
Mobile Container (Salesforce Mobile SDK 1.3)...........................................................................................................3
Identity..........................................................................................................................................................................3
The Dreamforce App................................................................................................................................................................3
About This Book.......................................................................................................................................................................4
Chapter Contents..........................................................................................................................................................4
Version..........................................................................................................................................................................5
Sending Feedback..........................................................................................................................................................5
Keeping Up to Date..................................................................................................................................................................5
Mobile SDK GitHub Repository..................................................................................................................................5
i
Table of Contents
Android Native Quick Start....................................................................................................................................................30
Native Android Requirements.....................................................................................................................................30
Installing the Mobile SDK for Android......................................................................................................................30
Creating a New Android Project.................................................................................................................................31
Android Template Application........................................................................................................................31
Setting Up Projects in Eclipse.................................................................................................................................................32
Android Project Files...................................................................................................................................................32
Cleaning and Building From Eclipse......................................................................................................................................32
Android RestExplorer Sample Application.............................................................................................................................32
ii
Table of Contents
OAuth 2.0 Refresh Token Flow..................................................................................................................................70
Scope Parameter Values...............................................................................................................................................70
Using Identity URLs...................................................................................................................................................71
Revoking OAuth Tokens............................................................................................................................................75
Creating a Remote Access Application...................................................................................................................................75
iii
Table of Contents
Upserting the Information into Force.com with Mobile SDK..................................................................................107
Wrap Up - The Internet of Things and the Future of NFC.....................................................................................107
Glossary...........................................................................................................................................124
Index...............................................................................................................................................133
iv
Preface
In 1981, the IBM PC was released with a 5Mhz 16 bit processor running Microsoft DOS. In 2012, the Apple iPhone 4s was
released with a dual-core, 1GHz processor. Thirty years of hardware and software gave us three orders of magnitude of
performance improvement -- in our pockets. We live in a world with 2.3B internet users and 6.1B mobile phone users.
Mobile devices have radically changed the way we work and play. Workers stay in touch, connect with customers and peers,
and engage on social networks and apps. Data must be consumed, created, and shared from a wide range of connected devices.
Most companies have an assortment of applications they run their businesses on, but most of these apps don’t work in the mobile
world. They simply aren’t available in the workers’ hands when they need them. HR, ERP, intranets, and custom apps are
locked away. They don’t provide the app experience users expect, and they aren’t wired into social graphs like consumer apps.
Yesterday’s platforms were not designed for the fundamental changes needed in the mobile world.
The platforms most companies have bought and built these old apps around were not built for this new world. Big monolithic
stacks and rigid integration patterns don’t work in this mobile world. These apps are getting replaced by cloud apps every day.
Mobile applications require fundamentally new architectures and application designs. The techniques that evolved since the
1990s for web applications on PCs don’t apply in the mobile world. Enterprise mobile applications need a new, modern platform
designed for the demands of mobile application development.
Perimeter Security • Corporate VPN or LAN access to • Cumbersome to require VPN from mobile devices
applications • IP restrictions ineffective with public mobile
networks
Device • Typically purchased and controlled by IT • Often Bring Your Own Device (BYOD)
Standardization • Multiple platforms
Form Factor • Large (PC) screen • Apps must support phone, tablet, and PC
1
Preface Salesforce Platform Mobile Services
Multi-device • Client-server architectures with data stored • Instant sharing between devices
on server (Web) • Data propogation between devices
Device Interaction • Applications rarely leverage telephony, • Native use of mobile device’s camera, contacts,
camera etc. calendar, and location
Location • Rarely used in web applications • Commonly used to both associate data with a
location and filter data and services based on location
• Mobile REST APIs provide access to enterprise data and services, leveraging standard web protocols. Developers can
quickly expose their business data as REST APIs and leverage those common APIs across their different phone, tablet,
and web user interfaces. The REST APIs provide a single place to enforce access, security, common policy, and enforcement
across all device types.
• Social (Chatter) REST APIs enable developers to quickly transform their applications with social networks and collaboration
features. The Chatter REST APIs provide access to the feed, as well as the social graph of user connections. Mobile
applications can easily consume or post items to a user or group, or leverage the social graph to enable instant collaboration
between connected users.
2
Preface Mobile Container (Salesforce Mobile SDK 1.3)
• Mobile Policy management enables administrators to enforce their enterprise security policy on mobile applications in a
world without perimeter security. Administrators can enable security features such as 2-factor authentication, device PIN
protection, and password rotation, as well as enabling or disabling user access to mobile applications.
• Geolocation provides location-based information to enhance your online business processes with geospatial data. Starting
with the Winter ‘13 release, all objects in Salesforce include a compound geolocation field. The entire platform is
location-ready, allowing spatial query functionality such as radius-based searching.
• Native device services allow developers to easily add camera, location, and contacts into their application using a common
set of APIs across a broad range of devices, including iPhone, iPad, and Android devices.
• Secure offline storage enables developers to build applications which continue to function with limited or no network
connectivity. The data stored on the device is securely encrypted and safe even if the device is lost or stolen.
• Client OAuth authentication support freeing developers from having to rebuild login pages and general authentication in
their mobile applications. It quickly and easily integrates mobile applications with enterprise security management.
Identity
Identity provides a single enterprise identity and sign-on service to connect mobile devices with enterprise data and services,
providing the following advantages:
• Allows for single sign-on across applications and devices so users are not forced to create multiple usernames and passwords.
• A trusted identity provider that you can leverage for any enterprise platform or application.
• A Cloud Directory that enables enterprises to white label identity services and use company-speicific appearance and
branding.
• The ability to utilize consumer identity providers, such as Facebook, for customer-facing applications to quickly engage
with customer social data.
3
Preface About This Book
Responsive design provides an optimal user experience no matter what the device. Be it a PC browser, tablet, or mobile device,
you can view and use the app with a minimum of resizing, panning, and scrolling, while taking advantage of the features and
functionality native to the device. If you’ve used the Dreamforce app from more than one device, you probably already know
this.
Chapter Contents
The organization of this guide is loosely based on how you’d develop an application. First there’s a look at architectural
decisions, followed by an immediate hands-on exercise using Visualforce with HTML5 and Javascript. Not only is this an
easy way to start, but you don’t need to ponder devices, authentication, or distribution. The guide then proceeds into native
and hybrid development.
You might have noticed that native development comes before hybrid. This doesn’t reflect a preference for development
options; every development scenario has its time and place. But because the hybrid tutorials require some of the native setup,
once you’re set up for native, the rest is easy.
4
Preface Version
Thereafter the chapters focus on security, and securely caching data offline, before delving into the more complex tasks, such
as using the camera, implementing social collaboration, and other fascinating etceteras. Finally it’s all wrapped up with an
invitation to join or Partner Program so you can list your mobile app on our AppExchange.
Version
This book was last revised on September 7th, 2012 and was verified to work with the Salesforce Winter ‘13 release and the
Mobile SDK version 1.3.
Sending Feedback
Questions or comments about anything you see in this book? Suggestions for topics that you'd like to see covered in future
versions? Go to the Force.com discussion boards at http://boards.developerforce.com and let us know what you
think! Or email us directly at developerforce@salesforce.com.
Keeping Up to Date
To keep up to date, you should know the following.
• Whenever a new version of Salesforce is released, the Mobile section of the release notes captures all of the important
details.
• This guide is updated frequently, and you can find the latest version online at
http://wiki.developerforce.com/page/Force.com_Books. If you’re reading a printed version of this guide,
see Version on page 5.
• You can always find the most current Mobile SDK release in the Mobile SDK GitHub Repository.
• The latest articles, blog posts, tutorials, and webinars are on http://wiki.developerforce.com/page/Mobile.
• Join the conversation on the message boards at http://boards.developerforce.com/t5/Mobile/bd-p/mobile.
You can always find the latest Mobile SDK releases in our public repositories:
• https://github.com/forcedotcom/SalesforceMobileSDK-iOS
• https://github.com/forcedotcom/SalesforceMobileSDK-Android
Note: You might want to bookmark the Mobile SDK home page
http://wiki.developerforce.com/page/Mobile_SDK, for the latest articles, blog posts, tutorials, and
webinars.
5
Chapter 1
Salesforce Platform Mobile Services Development
In this chapter ... The Force.com platform has proven itself as an easy, straightforward, and highly
productive platform for cloud computing. Developers can define application
• About Native, HTML5, and Hybrid components, such as custom objects and fields, workflow rules, Visualforce pages,
Development and Apex classes and triggers, using point-and-click tools of the Web interface,
• Multi-Device Strategy and assembling the components into killer apps. As a mobile developer, you
• Development Prerequisites might be wondering how you can leverage the power of the Force.com platform
• Supported Browsers to create sophisticated apps.
• Enough Talk; I’m Ready Salesforce Platform Mobile Services provide essential libraries for quickly building
native or hybrid mobile apps that seamlessly integrate with the Force.com cloud
architecture, and simplifies development by providing:
• Device access
• Enterprise container for hybrid applications
• Geo-location
• HTML5 development
• Native REST API wrappers
• OAuth access token management
• Secure offline storage
• Social and Mobile APIs
6
Salesforce Platform Mobile Services Development About Native, HTML5, and Hybrid Development
• Native apps are specific to a given mobile platform (iOS or Android) and use the development tools and language that
the platform supports (e.g., Xcode and Objective-C with iOS, Eclipse and Java with Android). Native apps look and
perform the best.
• HTML5 apps aren’t installed from an app store. Instead, they are delivered through a Web server and run in a mobile
Web browser. These apps use standard Web technologies, like HTML5, JavaScript and CSS to deliver apps to any device.
This write-once-run-anywhere approach to mobile development creates cross-platform mobile applications that work on
multiple devices. While developers can create sophisticated apps with HTML5 and JavaScript alone, some vital limitations
remain, specifically session management, secure offline storage, and access to native device functionality.
• Hybrid apps combine the ease of HTML5 development with the power of the native platform by wrapping a Web app
inside the Salesforce Mobile Container. This approach produces an application that can leverage the device’s native
capabilities and be delivered through the app store. You can also create hybrid apps using Visualforce pages.
7
Salesforce Platform Mobile Services Development About Native, HTML5, and Hybrid Development
Native Apps
Native apps provide the best usability, features, and overall mobile experience. There are some things you only get with native
apps:
• Multi touch — double taps, pinch-spread, and other compound UI gestures
• Fast graphics API — the native platform gives you the fastest graphics, which might not be a problem if you’re showing
a static screen with only a few elements, but might be an issue if you’re using a lot of data and require a fast refresh.
• Fluid animation — related to the fast graphics API is the ability to have fluid animation. This is especially important in
gaming, highly interactive reporting, or intensely computational algorithms for transforming photos and sounds.
• Built-in components — The camera, address book, geolocation, and other features native to the device can be seamlessly
integrated into mobile apps. Another important built-in component is encrypted storage, but more about that later.
• Ease of use — The native platform is what people are accustomed to, and so when you add that familiarity with all of the
native features they expect, you have an app that’s just plain easier to use.
Native apps are usually developed using an integrated development environment (IDE). IDEs provide tools for building
debugging, project management, version control, and other tools professional developers need. You need these tools because
native apps are more difficult to develop. Likewise, the level of experience required is higher than other development scenarios.
If you’re a professional developer, you don’t have to be sold on proven APIs and frameworks, painless special effects through
established components, or the benefits of having your code all in one place.
HTML5 Apps
An HTML5 mobile app is basically a web page, or series of Web pages, that are designed to work on a tiny screen. As such,
HTML5 apps are device agnostic and can be opened with any modern mobile browser. And because your content is on the
web, it's searchable, which can be a huge benefit depending on the app (shopping, for example).
If you're new to mobile development, the technological bar is lower for Web apps; it's easier to get started here than in native
or hybrid development. Unfortunately, every mobile device seems to have their own idea of what constitutes usable screen size
and resolution, and so there's an additional burden of testing on different devices. Browser incompatibility is especially rife
on Android devices, so browser beware.
An important part of the "write-once-run-anywhere" HTML5 methodology is that distribution and support is much easier
than for native apps. Need to make a bug fix or add features? Done and deployed for all users. For a native app, there are
longer development and testing cycles, after which the consumer typically must log into a store and download a new version
to get the latest fix.
If HTML5 apps are easier to develop, easier to support, and can reach the widest range of devices, where do these apps lose
out?
• Offline storage — You can implement a semblance of offline capability by caching files on the device. Even if the underlying
database is encrypted, this is not as secure or as well segmented as a native keychain encryption that protects each app with
a developer certificate.
• Security — In general, implementing even trivial security measures on a native platform can be complex tasks for a mobile
Web developer. It can also be painful for users. For example, if a web app with authentication is launched from the desktop,
it will require users to enter their credentials every time the app is sent to the background.
• Native features — the camera, address book, and other native features can’t be accessed.
• Native look and feel — HTML5 can only emulate the native look, while users won’t be able to use compound gestures
they are familiar with.
8
Salesforce Platform Mobile Services Development Multi-Device Strategy
Hybrid Apps
Hybrid apps are built using HTML5 and JavaScript wrapped inside a thin container that provides access to native platform
features. For the most part, hybrid apps provide the best of both worlds, being almost as easy to develop as HTML5 apps with
all the functionality of native.
You know that native apps are installed on the device, while HTML5 apps reside on a Web server, so you might be wondering
if hybrid apps store their files on the device or on a server? Yes. In fact there are two ways to implement a hybrid app.
• Local - You can package HTML and JavaScript code inside the mobile application binary, in a manner similar to the
structure of a native application. In this scenario you use REST APIs and Ajax to move data back and forth between the
device and the cloud.
• Server - Alternatively, you can implement the full web application from the server (with optional caching for better
performance). Your container app retrieves the full application from the server and displays it in a browser window.
Visualforce hybrid applications operate in this manner.
Both types of development are covered in this guide.
Multi-Device Strategy
With the proliferation of mobile devices in this post-PC era, applications now have to support a variety of platforms, form
factors, and device capabilities. Some of the key considerations and design options for Force.com developers looking to develop
such device-independent applications are:
9
Salesforce Platform Mobile Services Development Multi-Device Strategy
Client-Side Detection
The client-side detection approach uses JavaScript (or CSS media queries) running on the client browser to determine the
device type. Specifically, you can detect the device type in two different ways.
• Client-Side Device Detection with the User-Agent Header — This approach uses JavaScript to parse out the User-Agent
HTTP header and determine the device type based on this information. You could of course write your own JavaScript to
do this. A better option is to reuse an existing JavaScript. A cursory search of the Internet will result in many reusable
JavaScript snippets that can detect the device type based on the User-Agent header. The same cursory search, however,
will also expose you to some of the perils of using this approach. The list of all possible User-Agents is huge and ever
growing and this is generally considered to be a relatively unreliable method of device detection.
• Client-Side Device Detection with Screen Size and/or Device Features — A better alternative to sniffing User-Agent
strings in JavaScript is to determine the device type based on the device screen size and or features (e.g., touch enabled).
One example of this approach can be found in the open-source Contact Viewer HTML5 mobile app that is built entirely
in Visualforce. Specifically, the MobileAppTemplate.page includes a simple JavaScript snippet at the top of the page to
distinguish between phone and tablet clients based on the screen size of the device. Another option is to use a library
like Device.js or Modernizr to detect the device type. These libraries use some combination of CSS media queries and
feature detection (e.g., touch enabled) and are therefore a more reliable option for detecting device type. A simple example
that uses the Modernizr library to accomplish this can be found at
http://www.html5rocks.com/static/demos/cross-device/feature/index.html. A more complete example
that uses the Device.js library and integrates with Visualforce can be found in this GitHub repo:
https://github.com/sbhanot-sfdc/Visualforce-Device.js. Here is a snippet from the DesktopVersion.page in
that repo.
10
Salesforce Platform Mobile Services Development Multi-Device Strategy
<head>
<!-- Every version of your webapp should include a list of all
versions. -->
<link rel="alternate" href="/apex/DesktopVersion" id="desktop" media="only screen and
(touch-enabled: 0)"/>
<link rel="alternate" href="/apex/PhoneVersion" id="phone" media="only screen and
(max-device-width: 640px)"/>
<link rel="alternate" href="/apex/TabletVersion" id="tablet" media="only screen and
(min-device-width: 641px)"/>
<body>
<ul>
<li><a href="?device=phone">Phone Version</a></li>
<li><a href="?device=tablet">Tablet Version</a></li>
</ul>
<h1> This is the Desktop Version</h1>
</body>
</apex:page>
The snippet above shows how you can simply include a <link> tag for each device type that your application supports and the
Device.js library will take care of automatically redirecting users to the appropriate Visualforce page based on device type
detected. There is also a way to override the default Device.js redirect by using the ‘?device=xxx’ format shown above.
public ServerSideDeviceDetection() {
String userAgent =
System.currentPageReference().getHeaders().get('User-Agent');
isIPhone = userAgent.contains('iPhone');
}
Note that User-Agent parsing in the code snippet above is far from comprehensive and you should implement something
more robust that detects all the devices that you need to support based on regular expression matching. A good place to start
is to look at the RegEx included in the detectmobilebrowsers.com code snippets.
11
Salesforce Platform Mobile Services Development Multi-Device Strategy
How Should You Design a Force.com Application to Best Support Multiple Device Types?
Finally, once you know which devices you need to support and how to distinguish between them, what is the optimal application
design for delivering a customized user experiences for each device/form factor? Again, a couple of options to consider.
For simple applications where all you need is for the same Visualforce page to display well across different form factors, a
responsive design approach is an attractive option. In a nutshell, Responsive design uses CCS3 media queries to dynamically
reformat a page to fit the form factor of the client browser. You could even use a responsive design framework like Twitter
Bootstrap to achieve this.
Another option is to design multiple Visualforce pages, each optimized for a specific form factor and then redirect users to
the appropriate page using one of the strategies described in the previous section. Note that having separate Visualforce pages
does not, and should not, imply code/functionality duplication. A well architected solution can maximize code reuse both on
the client-side (by using Visualforce strategies like Components, Templates etc.) as well as the server-side (e.g., encapsulating
common business logic in an Apex class that gets called by multiple page controllers). An excellent example of such a design
can be found in the same open-source Contact Viewer application referenced before. Though the application has separate
pages for its phone and tablet version (ContactsAppMobile.page and ContactsApp.page respectively), they both share
a common template (MobileAppTemplate.page), thus maximizing code and artifact reuse. The figure below is a conceptual
representation of the design for the Contact Viewer application.
Lastly, it is also possible to service multiple form factors from a single Visualforce page by doing server-side device detection
and making use of the ‘rendered’ attribute available in most Visualforce components (or more directly, the CSS
‘display:none/block’ property on a <div> tag) to selectively show/hide page elements. This approach however can result in
bloated and hard-to-maintain code and should be used sparingly.
12
Salesforce Platform Mobile Services Development Development Prerequisites
Development Prerequisites
It’s helpful to have some experience with Database.com or Force.com. You'll need either a Database.com account or a Force.com
Developer Edition organization.
This guide also assumes you are familiar with the following platforms and technologies:
• To build iOS applications, you'll need Mac OS X Snow Leopard or Lion, and Xcode 4.2+.
• To build Android applications, you'll need the Java JDK 6, Eclipse, Android ADT plugin, and the Android SDK.
• To build hybrid applications, you’ll need an organization that has Visualforce.
• Most of our resources are on GitHub, a social coding community. You can access all of our files in our public repository,
but we think it’s a good idea to join. https://github.com/forcedotcom
Note: If you choose to use Database.com, you can’t develop Visualforce–driven apps.
13
Salesforce Platform Mobile Services Development Supported Browsers
7. Read and then select the checkbox for the Master Subscription Agreement and supplemental terms.
8. Click Sign Up.
9. After signing up, you’ll be sent an email with a link that you must click to verify your account. Click the link.
10. Now supply a password, and a security question and answer.
Supported Browsers
Salesforce supports these browsers.
Browser Comments
Microsoft® Internet Explorer® versions 7, 8, If you use Internet Explorer, we recommend using the latest version. Apply
9, and 10 all Microsoft software updates. Note these restrictions.
• The Compatibility View feature in Internet Explorer is not supported.
• The Metro version of Internet Explorer 10 is not supported.
• Internet Explorer 10 is not supported for the Service Cloud console.
14
Salesforce Platform Mobile Services Development Enough Talk; I’m Ready
15
Chapter 2
HTML5 Development
In this chapter ... HTML5 lets you create lightweight interfaces without installing software on the
mobile device; any mobile, touch or desktop device can access the same interface.
• HTML5 Development Requirements You can create an HTML5 application that uses Visualforce to deliver the HTML
• View Contacts Using Visualforce and content and fetches record data from Force.com. This section walks you through
jQuery Mobile a couple simple examples to get you started. The sample apps utilize the jQuery
• Create a Mobile Interface for the Mobile library for the user interface, and later delve into using JavaScript remoting
Warehouse App for Apex controllers.
• Accessing Data Using JavaScript
16
HTML5 Development HTML5 Development Requirements
Note: Since this development scenario uses Visualforce, you can’t use Database.com.
1. Log into your DE org and select the Sales app from the upper right corner.
2. Click the Contacts tab
3. In the View drop-down list, choose All, and then click Go.
Notice that you have a list of contacts. Now you’ll create a new page that’s optimized for viewing the same contacts on a mobile
device:
1. In the upper right corner click Your Name > Setup, and in the App Setup sidebar choose Develop > Pages.
2. Click New.
3. In the Label field enter ContactViewer and then click Quick Save.
The Visualforce standard page is optimized for large displays and includes elements you don't’ want to show on the mobile
device. So the first thing you’ll need to do is get rid of the standard style sheet (CSS) and specify one optimized for mobile.
Modify the page as follows:
1. Replace the <apex: page> tag with the following modified version: <apex:page standardStylesheets="false"
showHeader="false" sidebar="false">
2. Now add a reference to an external style sheet by adding the following line below the <apex: page> tag:
<apex:stylesheet
value="https://ajax.aspnetcdn.com/ajax/jquery.mobile/1.1.0/jquery.mobile-1.1.0.min.css"
/>
17
HTML5 Development View Contacts Using Visualforce and jQuery Mobile
3. In order to access Contacts, you need to add the controller for that. Go back to the <apex: page> tag and modify it to
add two more elements, one for the controller, and another to scroll through data: <apex:page
standardStylesheets="false" showHeader="false" sidebar="false" standardController="Contact"
recordSetVar="people">
4. Below the new stylesheet reference, add the following lines to reference the JQuery Mobile libraries:
<apex:includeScript value="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js"/>
<apex:includeScript
value="https://ajax.aspnetcdn.com/ajax/jquery.mobile/1.1.0/jquery.mobile-1.1.0.min.js"/>
<body>
<div data-role="page" data-theme="b" id="mainpage">
<div data-role="header">
<a href='#' id="link_logout" data-role="button" data-icon='delete'>
Log Out
</a>
<h2>List</h2>
</div>
<div id="#content" data-role="content">
<h2>Contacts</h2>
<div id="div_people">
<ul data-inset="true" data-role="listview" data-theme="a" data-dividertheme="a">
<body>
<div data-role="page" data-theme="b" id="mainpage">
<div data-role="header">
<a href='#' id="link_logout" data-role="button" data-icon='delete'>
Log Out
</a>
<h2>List</h2>
</div>
<div id="#content" data-role="content">
<h2>Contacts</h2>
<!-- list of people, links to detail pages -->
<div id="div_people">
<ul data-inset="true" data-role="listview" data-theme="a"
18
HTML5 Development View Contacts Using Visualforce and jQuery Mobile
data-dividertheme="a">
<apex:repeat value="{!people}" var="person">
<li>
<a href="#detailpage{!person.Id}">
<apex:outputField value="{!person.Name}"/>
</a>
</li>
</apex:repeat>
</ul>
</div>
</div>
</div>
</body>
</apex:page>
jQuery Mobile lets you use simple <div> elements to define multiple application pages using just one Visualforce/HTML
page. jQuery Mobile’s approach reduces the amount of traffic between the client and the server, which is perfect for mobile
application development. Additionally, jQuery Mobile’s approach automatically styles lists in a mobile-friendly way. For this
tutorial, you are simply outputting all Contacts on a page. This works here as the standard DE org doesn’t come with hundreds
of rows of data. However, if you are working with larger data sets, you can exert finer control by creating a custom controller
and adding a specific SOQL statement. For example, SOQL supports an OFFSET filter that makes it easier to get the next
100 records and use pagination in your app.
So far you can only view a list of contacts, and if you click on one you’ll notice you can’t drill into the details. To do that, you
need to create a detail component. Using the same <apex:repeat> component you used to create the list view, you’ll add
a series of detailpage <div> elements. Below the last <div> element, and just before the </body> tag, add the following
Visualforce component, then click Save.
Home
</a>
<h1>Edit</h1>
</div>
<div id="#content" data-role="content">
<h2 id="name">
<apex:outputField value="{!person.Name}"/>
</h2>
<label for="phone" class="ui-hidden-accessible">Phone #:</label>
<apex:outputField value="{!person.Phone}"/>
<br/>
<label for="email" class="ui-hidden-accessible">Email:</label>
<input type="text" id="quantity{!product.Id}"
value="{!ROUND(product.Quantity__c, 0)}"></input>
<br/>
<a href="#" data-role="button" data-id="{!product.Id}" class="updateButton"
data-theme="b">Update</a>
</div>
</div>
</apex:repeat>
You can do a lot more with Visualforce and open Javascript libraries, this was simply a quick tutorial to get you started.
19
HTML5 Development Create a Mobile Interface for the Warehouse App
1. Click Your Name > Setup > My Personal Information > Personal Information.
2. Click Edit.
3. Select the Development Mode checkbox and click Save.
Now create a very basic Visualforce page to get familiar with the process and experience the browser-based Visualforce editor.
1. In your browser, append /apex/MobileInventory to the URL for your Salesforce instance. For example, if your
Salesforce instance is https://na1.salesforce.com, enter
https://na1.salesforce.com/apex/MobileInventory
2. You should see an error message: “Page MobileInventory does not exist.”
3. Click the Create Page MobileInventory link to create the new page. When Development Mode is enabled, you can edit
the page directly by clicking on MobileInventory in the lower left corner.
4. Change the contents of the <h1> tag to <h1>Mobile Inventory<h1>.
5. Click the Save icon at the top of the Page Editor.
If you take a look at the source code, notice that it's a markup language that renders HTML in your Web browser. If you are
already familiar with Web development, Visualforceshould be easy to learn because it simply extends the power of standard
page markup. Pages can include Visualforce components like <apex:page> to define specific functionality (in this case, the
overall structure of the page itself), along with standard HTML tags such as <h1>.
20
HTML5 Development “Mobilize” the Visualforce Page
page to reference the jQuery framework files from a globally hosted CDN, as well as update the <apex:page> tag to remove
the default page styling.
Click the Save icon at the top of the Page Editor. Note how the page looks very different now that you are using a different
style sheet. The title is in a different font and location, and the standard header and sidebar are no longer present.
Note: The apex:includeScript and apex:stylesheet in this example demonstrates how simple it is to use
externally hosted JavaScript and CSS files. However, the platform itself can also host such files as well. You can upload
zips as static resources and then build pages that reference components within your static resources. It’s up to you on
how you’d like to serve these up.
The page you are building needs to display data from the Warehouse app. To do this, you need to add a controller to the page
so that you access the data of interest. Visualforce uses the Model-View-Controller (MVC) design pattern to make it easy to
separate the view from the underlying database and logic. In our case, the controller (typically an Apex class) serves as an
intermediary between the view (the Visualforce page) and the model (the object in the database). For example, the controller
might contain the logic that executes when a user clicks a button to retrieve data that the view can then display. By default,
all platform objects have standard controllers that you can use to interact with the data associated with the object. So, in many
cases, you don't need to write the code for the controller yourself. You can extend the standard controllers to add new
functionality, or create custom controllers from scratch.
1. Modify your code to enable the Merchandise__c standard controller by editing the first <apex:page> tag. The editor
ignores whitespace, so you can enter the text on a new line.
3. Save your work. You won't notice any change on the page, but because you've indicated that the page should use a controller,
and defined the variable products, the variable is available to you in the body of the page and it will represent a list of
Merchandise records.
The recordSetVar attribute enables a standard list controller, which provides additional controller support for listing a
number of records with pagination. You set it to products. This creates a new variable, products, that contains the set of
records that the Visualforce page can then display. Also note the reference to Merchandise__c this is the Merchandise
custom object and the “__c” portion denotes that as a custom object, different from the standard objects such as Contacts or
Accounts.
The controller you added lets you directly pull records into a list without requiring any additional logic. To create a mobile
interface with ease, add some HTML that leverages the CSS with jQuery Mobile to create an HTML page that is friendly
for mobile devices.
21
HTML5 Development “Mobilize” the Visualforce Page
1. Edit the MobileInventory page to replace <h1>Mobile Inventory</h1> with the following HTML body:
<body>
<!-- Main page, to display list of Merchandise once app starts -->
<div data-role="page" data-theme="b" id="mainpage">
<!-- page header -->
<div data-role="header">
<!-- button for logging out -->
<a href='#' id="link_logout" data-role="button" data-icon='delete'>
Log Out
</a>
<!-- page title -->
<h2>List</h2>
</div>
<!-- page content -->
<div id="#content" data-role="content">
<!-- page title -->
<h2>Mobile Inventory</h2>
<!-- list of merchandise, links to detail pages -->
<div id="div_merchandise_list">
<ul data-inset="true" data-role="listview" data-theme="a"
data-dividertheme="a">
</ul>
</div>
</div>
</div>
</body>
</apex:page>
2. In between the <ul> and </ul> tags, place an <apex:repeat> component, which loops through the current set of
Merchandise records to display a list, like so:
<body>
<!-- Main page, to display list of Merchandise once app starts -->
<div data-role="page" data-theme="b" id="mainpage">
<!-- page header -->
22
HTML5 Development Accessing Data Using JavaScript
<div data-role="header">
<!-- button for logging out -->
<a href='#' id="link_logout" data-role="button" data-icon='delete'>
Log Out
</a>
<!-- page title -->
<h2>List</h2>
</div>
<!-- page content -->
<div id="#content" data-role="content">
<!-- page title -->
<h2>Mobile Inventory</h2>
<!-- list of merchandise, links to detail pages -->
<div id="div_merchandise_list">
<ul data-inset="true" data-role="listview" data-theme="a"
data-dividertheme="a">
<apex:repeat value="{!products}" var="product">
<li>
<a href="#detailpage{!product.Id}">
<apex:outputField value="{!product.Name}"/>
</a>
</li>
</apex:repeat>
</ul>
</div>
</div>
</div>
</body>
</apex:page>
Using the preview above the Page Editor, try out the app. The page now uses the jQuery Mobile CSS to create a list of records.
Each row displays the Merchandise record's name.
• The jQuery static resource contains all the JavaScript and stylesheet files for the jQuery and jQuery Mobile libraries.
• You’ll also need a JavaScript file containing the methods that pull data from the Apex controller using JavaScript remoting.
This data is then wrapped into appropriate HTML elements and rendered on the Visualforce page.
function getAlbums(callback) {
$j('#albumlist').empty();
CloudtunesController.queryAlbums(function(records, e)
{ showAlbums(records, callback) }, {escape:true});
}
• In getAlbums(), calls such as $j('#albumlist').empty() are an indication of jQuery at work. In this case, jQuery
retrieves the HTML element identified by albumlist, and clears out the HTML, readying it for results.
• The method then makes a call to the Apex controller’s queryAlbums() method. This is where the JavaScript remoting
magic happens. Visualforce provides all the required plumbing to allow the call to the controller method directly from the
JavaScript.
• Finally, a callback function is passed as an argument to queryAlbums() that is automatically invoked once the records
are returned from the Apex controller. The showAlbums() function takes these records and displays them.
23
HTML5 Development Accessing Data Using JavaScript
$j.each(records, function() {
$j('<li></li>')
.attr('id',this.Id)
.hide()
.append('<h2>' + this.Name + '</h2>')
.click(function(e) {
e.preventDefault();
$j.mobile.showPageLoadingMsg();
$j('#AlbumName').html(currentAlbums[this.id].Name);
$j('#AlbumPrice').html('$'+currentAlbums[this.id].Price__c);
if($j('#AlbumPrice').html().indexOf(".") > 0
&& $j('#AlbumPrice').html().split(".")[1].length == 1) {
$j('#AlbumPrice').html($j('#AlbumPrice').html()+"0"); //add trailing zero
}
$j('#AlbumId').val(currentAlbums[this.id].Id);
var onTracksLoaded = function() {
$j.mobile.hidePageLoadingMsg();
$j.mobile.changePage('#detailpage', {changeHash: true});
}
getTracks(currentAlbums[this.id].Id, onTracksLoaded);
})
.appendTo('#albumlist')
.show();
});
$j('#albumlist').listview('refresh');
if(callback != null && typeof callback == 'function') { callback(); }
}
• This function gets the records from the callback, loops through them, and creates a new list of <li> HTML elements to
display within the albumlist div.
• Notice this function also dynamically attaches a new event to each list item so that when the user clicks the list item, they
can browse down to a list of tracks associated with the album. The list of those tracks is fetched using getTracks() .
Now let’s take a look at getTracks(). Functionally, this code is very similar to the getAlbums() and showAlbums()
code. The only significant difference to the code that handled albums is that a different Apex controller method is used, and
of course, a different callback function is provided for updating the page with the results.
Now anytime the album name is clicked, a new set of track data will be retrieved and the itemlist will be rewritten. Clicking
on the track name will rewrite the HTML of the elements displaying the track information and use jQuery Mobile to move
to that page. A real application can, of course, cache this information as well.
24
Chapter 3
Native iOS Development
In this chapter ... The two main things the iOS native SDK provides:
• iOS Native Quick Start • Automate the OAuth2 login process and make it easy to integrate this with
your app.
• Using the Mobile SDK in an Existing
Project • Access to the REST API with all the infrastructure classes (including
third-party libraries such as RestKit) for making that access as easy as possible.
• iOS RestAPIExplorer Sample
Application When you create a new project using the Salesforce Mobile SDK, a template
application is included automatically. This simple app allows you to connect to
an organization and run a simple query. It doesn’t do much, but it lets you know
things are working as designed, and gives you the foundation of your own app.
25
Native iOS Development iOS Native Quick Start
Note: If you have the GitHub app for Mac OS X, click Clone in Mac.
3. Open the OS X Terminal app in the directory where you installed the cloned repository and run the install script from the
command line: ./install.sh
4. You might also need to download the sample app from GitHub:
https://github.com/forcedotcom/SalesforceMobileSDK-Samples/tree/master/iOS/CloudTunesNative
Note: You might also need to enter a Company Identifier prefix if you haven’t used Xcode before.
4. Make sure the checkbox for Use Automatic Reference Counting is cleared.
26
Native iOS Development Using the Mobile SDK in an Existing Project
5. Click Next.
6. Specify a location for your new project and click Create.
1. Press Command-R and the default template app builds and then runs in the iOS simulator.
Note: If you get build errors, make sure Automatic Reference Counting (ARC) is turned off.
2. On startup, the application starts the OAuth authentication flow, which results in an authentication page. Enter your
credentials, and click Login.
3. Tap Allow when asked for permission
You should now be able to compile and run the sample project. It's a simple app that logs you into an org via OAuth2, issues
a 'select Name from User' query, and displays the result in a UITableView.
1. In Xcode, drag the folder native/dependencies into your project (select Create groups for any added folders).
2. Open the Build Settings tab for the project and set Other Linker Flags to -ObjC -all_load.
3. Open the Build Phases tab for the project main target and link against the following required frameworks:
• CFNetwork.framework
• CoreData.framework
• MobileCoreServices.framework
• SystemConfiguration.framework
• Security.framework
• libxml2.dylib
27
Native iOS Development iOS RestAPIExplorer Sample Application
28
Chapter 4
Native Android Development
In this chapter ... The two main things the Android native SDK provides are:
• Android Native Quick Start • Automation of the OAuth2 login process, making it easy to integrate the
process with your app.
• Setting Up Projects in Eclipse
• Access to the REST API, with infrastructure classes that simplify that access.
• Cleaning and Building From Eclipse
• Android RestExplorer Sample The Android Salesforce Mobile SDK includes several sample native applications.
Application We also provide an ant target to quickly create a new application.
29
Native Android Development Android Native Quick Start
Note: For best results, install all previous versions of the Android SDK as well as your target version.
The SalesforceSDK project is built with the Android 3.0 (Honeycomb) library. The primary reason for this is that we want
to be able to make a conditional check at runtime for file system encryption capabilities. This check is bypassed on earlier
Android platforms; thus, you can still use the salesforcesdk.jar in earlier Android application versions, down to the
mininum-supported Android 2.2.
30
Native Android Development Creating a New Android Project
2. SALESFORCE_SDK_DIR pointing to your clone of the Salesforce Mobile SDK repository, for example:
/home/jon/SalesforceMobileSDK-Android.
3. NATIVE_DIR pointing to $SALESFORCE_SDK_DIR/native
4. TARGET_DIR pointing to a location you’ve defined to contain your Android project.
Note: If you haven't set up these variables, make sure to replace $ANDROID_SDK_DIR, $SALESFORCE_SDK_DIR,
$NATIVE_DIR and $TARGET_DIR in the various code snippets in this guide with the actual paths.
1. Open a command prompt in the location where you installed the SDK (or $SALESFORCE_SDK_DIR if you created that
variable).
2. Enter ant create_native -Dapp.name={appName} -Dtarget.dir={targetDir}
-Dpackage.name={packageName}
The Android project contains a simple application you can build and run.
cd $TARGET_DIR
$ANDROID_SDK_DIR/tools/android update project -p . -t 1
ant clean debug
Note: The -t <id> parameter specifies the target Android version. Use android.bat list targets to
see the IDs for API versions installed on your system.
4. If your emulator is not running, use the Android AVD Manager to start it. If you are using a real device, connect it.
5. Enter ant installd.
31
Native Android Development Setting Up Projects in Eclipse
1. SalesforceSDK —The SalesforceSDK, which provides support for OAuth2 and REST API calls
2. SalesforceSDKTest —Tests for the SalesforceSDK project
3. TemplateApp — Template used when creating new native applications using SalesforceSDK
4. TemplateAppTest—Tests for the TemplateApp project
5. RestExplorer—App using SalesforceSDK to explore the REST API calls
6. RestExplorerTest —Tests for the RestExplorer project
7. SampleApps/CloudTunes — A sample native application using SalesforceSDK, used in the Mobile SDK Workbook
1. To run the application, right-click the RestExplorer project and choose Run As > Android Application.
32
Native Android Development Android RestExplorer Sample Application
2. To run the tests, right-click the RestExplorerTest project and choose Run As > Android JUnit Test.
33
Chapter 5
Hybrid Development
In this chapter ... Hybrid apps combine the ease of HTML5 Web app development with the power
and features of the native platform.
• Hybrid Apps Quick Start
Hybrid apps depend on HTML and JavaScript files. These files can be stored
• Create a Mobile Page to List
on the device or on the server.
Information
• Create a Mobile Page for Detailed • Device — Hybrid apps developed with forcetk JavaScript library wrap a
Information Web app inside the Salesforce Mobile Container. In this methodology, the
• Support Social Collaboration with JavaScript and HTML files are stored on the device.
Chatter • Salesforce Mobile Container — Hybrid apps developed using Visualforce
technology store the HTML and JavaScript files on the server and are
• iOS Hybrid Sample Application
delivered through the native container.
• Android Hybrid Sample Application
34
Hybrid Development Hybrid Apps Quick Start
1. Make sure you meet all of the Hybrid Apps Requirements on page 35.
2. Install the Mobile SDK.
When you’re done with the sample app you can add more functionality.
If you are developing apps for iOS devices, you will also need Xcode 4.2 or above.
If you are developing apps for Android devices, you will also need:
• Eclipse Classic
• Android SDK (r20 or above)
• ADT Plugin (r20 or above)
1. In Xcode, create a new "Hybrid Force.com App" project (Command-Shift-N in Xcode). These parameters are required.
• Consumer Public Key: The Consumer Key from your Remote Access app.
• OAuth Redirect URL: The Callback URL from your Remote Access app.
• Company Identifier: Something like com.mycompany.foo - this should correspond with an App ID you created in
your Apple iOS dev center account.
• Use Automatic Reference Counting: Uncheck.
35
Hybrid Development Hybrid Apps Requirements
At the time of writing, there is a bug in the Hybrid Force.com App template that causes the app to be incorrectly packaged.
If you try to run the app, it will fail with "ERROR: Start Page at 'www/bootstrap.html' was not found" in the output console in
Xcode.
To fix this:
1. Right-click the yellow www folder and delete it by clicking Delete, Remove References Only.
2. Right-click your project folder, select Add Files to "My Project" and navigate to the www directory inside the project
directory.
3. Ensure that Create folder references for any added folders is selected, then click Add. Notice that the www folder is now
shown in blue.
1. In Eclipse, select File > Import > General > Existing Projects into Workspace.
2. Locate the sample ContactExplorer project:
SalesforceMobileSDK-Android/hybrid/SampleApps/ContactExplorer and select it as the root directory.
Ensure that Copy projects into workspace is selected, and click Finish.
3. To avoid confusion with the standard ContactExplorer sample, right-click the ContactExplorer project and rename it.
Open res/values/strings.xml, and edit app_name to match the new project name.
4. To configure your app with its Remote Access parameters, open assets/www/bootconfig.js and edit the following
values:
36
Hybrid Development Running the Sample Hybrid App
5. You will need to create an Android Virtual Device, if you have not already done so. In Eclipse, select Window > AVD
Manager and click New. You can enable camera support in the device if you wish.
Log in with your DE username and password, and you will be prompted to allow your app access to your data in Salesforce.
Tap Allow and you should be able to retrieve lists of contacts and accounts from your DE account.
37
Hybrid Development Running the Sample Hybrid App
Notice the app can also retrieve contacts from the device - something that an equivalent web app would be unable to do. Let's
take a closer look at how the app can do this.
$j('#link_fetch_device_contacts').click(function() {
SFHybridApp.logToConsole("link_fetch_device_contacts clicked");
var options = new ContactFindOptions();
options.filter = ""; // empty search string returns all contacts
options.multiple = true;
var fields = ["name"];
navigator.contacts.find(fields, onSuccessDevice,
onErrorDevice, options);
});
38
Hybrid Development Create a Mobile Page to List Information
This handler calls find() on the navigator.contacts object to retrieve the contact list from the device. The
onSuccessDevice() function renders the contact list into the index.html page.
$j('#link_fetch_sfdc_contacts').click(function() {
SFHybridApp.logToConsole("link_fetch_sfdc_contacts clicked");
forcetkClient.query("SELECT Name FROM Contact",
onSuccessSfdcContacts, onErrorSfdc);
});
The #link_fetch_sfdc_contacts handler runs a query using the forcetkClient object. This object is set up during
the initial OAuth 2.0 interaction, and gives access to the Force.com REST API in the context of the authenticated user. Here
we retrieve the names of all the contacts in the DE account and onSuccessSfdcContacts() renders them as a list on
the index.html page.
$j('#link_fetch_sfdc_accounts').click(function() {
SFHybridApp.logToConsole("link_fetch_sfdc_accounts clicked");
forcetkClient.query("SELECT Name FROM Account",
onSuccessSfdcAccounts, onErrorSfdc);
});
The #link_fetch_sfdc_accounts handler is very similar to the previous one, fetching Account records via the Force.com
REST API. The remaining handlers, #link_reset and#link_logout, clear the displayed lists and log out the user
respectively.
// log message
SFHybridApp.logToConsole("Calling out for records");
// register click event handlers -- see inline.js
regLinkClickHandlers();
// retrieve Merchandise records, including the Id for links
forcetkClient.query("SELECT Id, Name, Price__c, Quantity__c
FROM Merchandise__c", onSuccessSfdcMerchandise, onErrorSfdc);
Notice that this JavaScript code leverages the forcetk library to query the Force.com database with a basic SOQL statement
and retrieve all records from the Merchandise custom object. On success, the function calls the JavaScript
function onSuccessSfdcMerchandise (which you build in a moment).
39
Hybrid Development Create a Mobile Page to List Information
<!-- Main page, to display list of Merchandise once app starts -->
<div data-role="page" data-theme="b" id="mainpage">
<!-- page header -->
<div data-role="header">
<!-- button for logging out -->
<a href='#' id="link_logout" data-role="button"
data-icon='delete'>
Log Out
</a>
<!-- page title -->
<h2>List</h2>
</div>
<!-- page content -->
<div id="#content" data-role="content">
<!-- page title -->
<h2>Mobile Inventory</h2>
<!-- list of merchandise, links to detail pages -->
<div id="div_merchandise_list">
<!-- built dynamically by function onSuccessSfdcMerchandise -->
</div>
</div>
</div>
Overall, notice that the updated view uses standard HTML tags and jQuery Mobile markup (e.g., data-role, data-theme,
data-icon) to format an attractive touch interface for your app. Developing hybrid-based mobile apps is straightforward if you
already know some basic standard Web development technology, such as HTML, CSS, JavaScript, and jQuery.
40
Hybrid Development Create a Mobile Page to List Information
});
The comments in the code explain each line. Notice the call to SFHybridApp.logToConsole(); the JavaScript outputs
rendered HTML to the console log so that you can see what the code creates. Here's an excerpt of some sample output.
41
Hybrid Development Create a Mobile Page for Detailed Information
...
</ul>
If you click any particular Merchandise record, nothing happens yet. The list functionality is useful, but even better when
paired with the detail view. The next section helps you build the detailpage that displays when a user clicks a specific Merchandise
record.
42
Hybrid Development Create a Mobile Page for Detailed Information
<!-- Detail page, to display details when user clicks specific Merchandise record -->
The comments explain each part of the HTML. Basically, the view is a form that lets the user see a Merchandise record's
Price and Quantity fields, and optionally update the record's Quantity.
Recall, the jQuery calls in the last part of the onSuccessSfdcMerchandise function (in inline.js) and updates the
detail page elements with values from the target Merchandise record. Review that code, if necessary.
43
Hybrid Development Support Social Collaboration with Chatter
The comments in the code explain each line. On success, the new handler calls the updateSuccess function, which is not
currently in place. Add the following simple function to inline.js.
function updateSuccess(message) {
alert("Item Updated");
}
Feel free to update a record's quantity, and then check that you see the same quantity when you log into your DE org and
view the record using the Force.com app UI (see above).
44
Hybrid Development Modify the App's View (index.html)
• Feed Item: Each feed item represents either a set of changes on a specific record or a post to a particular user or record.
When a user posts to a feed, the ParentId of the resulting feed item holds the user's UserId. Some queries and statements,
for example adding a comment, require the ID of a feed item.
• FeedComment: A FeedComment object stores comments and is a child object of an associated record feed item.
To access the Chatter data model, an app can use the Chatter REST API. The Chatter REST API provides access to Chatter
feeds and social data such as feed items and comments via a standard JSON/XML-based API.
A full discussion of the Chatter REST API is beyond the scope of this topic. For a quick preview, see the Chatter REST API
Cheat Sheet: http://wiki.developerforce.com/page/Cheat_Sheets.
45
Hybrid Development Modify the App's Controller (inline.js)
Notice that these new functions call the Chatter REST API to get a feed's items (and all related posts and comments), post
a new item to a feed, and post a new comment for an existing feed item.
Now append the following code to the regLinkClickHandlers() function to listen for clicks on a new button that you
will soon add to the detailpage. Go to https://gist.github.com/3644348 for the source code.
46
Hybrid Development Modify the App's Controller (inline.js)
Notice that the new code above calls the new forcetkClient chatterFeed() function. This call gets the feed items for the
current Merchandise record, including related posts and comments with just one call to the database, making this function
very efficient: an important design goal for mobile apps. This function call also yields to the updateChatterList()
function function, which you need to add next along with a related refreshChatterList() function.
Add the following code to inline.js to add the two new functions. Go to https://gist.github.com/3644332 for the source
code.
function refreshChatter(response) {
forcetkClient.chatterFeed($j("#detailpage").attr("data-id"), updateChatterList,
onErrorSfdc);
}
function updateChatterList(response) {
// output debug information to the log
SFHybridApp.logToConsole("Got Chatter");
SFHybridApp.logToConsole(response.items.length);
});
var newPostButtonDiv = $j("<a href='#' data-role='button' data-min='true' class='post'
data-theme='b' data-icon='plus' data-inline='true' class='post'>New Post</a>")
$j("#div_chatter_list").append(newPostButtonDiv);
47
Hybrid Development Try Out the App
var id = $j(this).attr('data-id');
var post = prompt('Enter New Comment');
if (post != null) {
forcetkClient.postChatterComment(id, post, refreshChatter, onErrorSfdc);
}
});
var id = $j("#detailpage").attr("data-id");
SFHybridApp.logToConsole('detailpage id.');
SFHybridApp.logToConsole(id);
var post = prompt('Enter New Post');
if (post != null) {
forcetkClient.postChatterItem(id, post, refreshChatter, onErrorSfdc);
}
});
48
Hybrid Development iOS Hybrid Sample Application
Tapping Collaborate takes you to the new chatterpage view of the mobile app, which displays all the Chatter feed items,
including related posts and comments. Feel free to add both a new post or comment on an existing post and see that your
work is reflected in the Warehouse app.
You've successfully made your mobile app social such that users can collaborate on Merchandise records!
49
Hybrid Development Android Hybrid Sample Application
You can find more detailed installation instructions, as well as documentation for working with the PhoneGap SDK, in
the Getting Started Guide.
The hybrid sample applications are configured to look for the PhoneGap iOS Framework in
/Users/Shared/PhoneGap/Frameworks/PhoneGap.framework, and might not load the framework properly if it is
located elsewhere. To find out if the PhoneGap framework is properly linked in the sample project, take the following action:
If you do not see the PhoneGap framework, or otherwise get compilation errors related to the PhoneGap Framework not
being found (e.g. Undefined symbols for architecture i386: "_OBJC_METACLASS_$_PhoneGapDelegate"), you will need
to add the PhoneGap Framework to the sample project:
The sample application project should now build and run cleanly.
• SampleApps/ContactExplorer: The ContactExplorer sample app uses PhoneGap (also known as Cordova) to retrieve
local device contacts. It also uses the forcetk.js toolkit to implement REST transactions with the Salesforce REST
API. The app uses the OAuth2 support in Salesforce SDK to obtain OAuth credentials, then propagates those credentials
to forcetk.js by sending a javascript event.
• SampleApps/ContactExplorerTest: Tests for the ContactExplorer sample app.
• SampleApps/SFDCAccount: A simple hybrid application that demonstrates how to take accounts and opportunities
offline using SmartStore and forcetk.
• SampleApps/SFDCAccountTest: Tests for the SFDCAccount sample app.
• SampleApps/VFConnector: The VFConnector sample app demonstrates how to wrap a Visualforce page in a native
container. This example assumes that your org has a Visualforce page called BasicVFTest. The app first obtains OAuth
login credentials using the Salesforce SDK OAuth2 support, then uses those credentials to set appropriate webview cookies
for accessing Visualforce pages.
• SampleApps/VFConnectorTest: Test for the VFConnector sample app.
• SmartStorePluginTest: Tests for the SmartStore phonegap plugin.
The sample applications contained under the hybrid/ folder are designed around the PhoneGap SDK. Before you can work
with those applications, you need to download and install the 1.8.1 (or later) version of the PhoneGap SDK, which you can
get from the PhoneGap website. You can find more detailed installation instructions, as well as documentation for working
with the PhoneGap SDK, in the Getting Started Guide.
50
Hybrid Development Android Hybrid Sample Application
The hybrid sample applications are configured to look for the PhoneGap Android Framework in
/Users/Shared/PhoneGap/Frameworks/PhoneGap.framework, and might not load the framework properly if it is located
elsewhere. To find out if the PhoneGap framework is properly linked in the sample project, take the following action:
If you do not see the PhoneGap framework, or otherwise get compilation errors related to the PhoneGap Framework not
being found (for example, 'Undefined symbols for architecture i386: "_OBJC_METACLASS_$_PhoneGapDelegate"'), you
will need to add the PhoneGap Framework to the sample project.
51
Chapter 6
Hybrid Development with Mobile Components for Visualforce
In this chapter ... The flexible component infrastructure of Visualforce makes it possible to wrap
low-level code into reusable components for developing custom apps on the
• Mobile Components for Force.com platform. You can leverage Visualforce to create hybrid mobile
VisualforceArchitecture applications.
• Visualforce Mobile Open
The open-source Mobile Components for Visualforce library contains lightweight
Components UI components that generate cross-platform HTML5 output. These apps can
• Installing the Components be deployed in the browser or embedded inside the hybrid Mobile SDK container.
• Creating Your First Tablet Page The source code for this library is available on Github:
• Creating a Mobile Component for https://github.com/forcedotcom/MobileComponents/
Visualforce tree/master/Visualforce
The component library enables any Visualforce developer to quickly and easily
build mobile applications without having to dig deep into complex mobile
frameworks and design patterns. This library includes the frameworks and best
practices of mobile development that can be used with simple component
interfaces.
52
Hybrid Development with Mobile Components for Visualforce Mobile Components for VisualforceArchitecture
• App Component — This component provides all the settings and architecture pieces (including jQuery and jQuery Mobile)
for mobile app development.
• Navigation Component — Navigation Component can be used to create hooks for navigation between various jQuery
Mobile pages.
• SplitView Template — This template provides the split view components on the page. In landscape mode, it provides a
left menu section and a broad main section. In portrait mode, it turns the left menu into a popover.
• List Component — List Component provides a quick and easy way to render a record list for any sObject. One can easily
manage the behavior of the component by using the various attributes, or the JavaScript hooks, on this component.
• Detail Component — Detail Component provides a quick and easy way to render the details for any sObject. One can
easily manage the behavior by using the various attributes or the JavaScript hooks.
• Page Component — Page Component provides a jQuery Mobile wrapper with data-role="page".
• Header Component — Header Component provides a jQuery Mobile wrapper with data-role="header" for header
sections inside a Page component.
• Content Component — Content Component provides a jQuery Mobile wrapper with data-role="content" for
content sections inside a Page component.
• Footer Component — Footer Component provides a jQuery Mobile wrapper with data-role="footer" for footer
sections inside a Page component.
53
Hybrid Development with Mobile Components for Visualforce Visualforce App Component
Note: These Visualforce components are open-source and are not officially supported by Salesforce.
<c:App debug="true"></c:App>
<apex:composition template="SplitViewTemplate"></apex:composition>
• “menu” is the left section of the split view in landscape mode. This section becomes a popover when a user rotates the
tablet to switch to the portrait mode.
• “main” is the right wide section of the split view. This section is always visible on the tablet in both portrait and landscape
modes.
<apex:define name="menu">
<c:Page name="list">
<c:Header >
<h1 style="font-size: 20px; margin: 0px;">All Contacts</h1>
</c:Header>
<c:Content >
<c:List sobject="Contact" labelField="Name" subLabelField="Account.Name"
sortByField="FirstName" listFilter="true"/>
</c:Content>
</c:Page>
</apex:define>
• The Header component is used to define the fixed title of the section.
• The Content component describes the scrollable content section.
54
Hybrid Development with Mobile Components for Visualforce Visualforce Page Component
• Within the body of Content component, the List component is used to fetch and display the contact list.
<apex:define name="main">
<c:Page name="main">
<c:Header >
<h1 style="font-size: 22px; margin: 0px;">Contact Details</h1>
</c:Header>
<c:Content >
<c:Detail sobject="Contact"/>
</c:Content>
</c:Page>
</apex:define>
55
Hybrid Development with Mobile Components for Visualforce Installing the Components
Next you’ll need to deploy the Force.com metadata found in the MobileComponents/Visualforce/src folder to your
destination org with Force.com Workbench using following steps:
Finally you need to configure a remote access point in your Salesforce org,
1. Log into your org and cick Setup > Administration Setup > Security Controls > Remote Site Settings.
2. Click New Remote Site, then create a new site by specifying your org's instance URL for the Remote Site URL. For
example, if your org is on instance NA1, the Remote Site URL will be https://na1.salesforce.com.
You should now be all set and ready to use Mobile Components for Visualforce. To see the sample Contact viewer app in
action, navigate to the following page: https://<remote site url>/apex/MobilePage
56
Hybrid Development with Mobile Components for Visualforce Creating Your First Tablet Page
<c:App debug="true"</c:App>
Inside the App component, you can specify the body of the mobile app. In this case, you build a split view page, which provides
a slim left section for list view, and a wider right section to show the record details. To do this, you compose the page by using
the SplitViewTemplate which is part of this component library.
<apex:composition template="SplitViewTemplate"</apex:composition>
• menu — The left section of the split view in landscape mode. This section becomes a popover when user rotates the tablet
to switch to the portrait mode.
57
Hybrid Development with Mobile Components for Visualforce Creating Your First Tablet Page
• main — The right, wide section of the split view. This section is always visible on the tablet in both portrait and landscape
modes.
Now define the content inside these sections of the split view. Here’s how to define the content for the left menu section:
<apex:define name="menu">
<c:Page name="list">
<c:Header>
<h1 style="font-size: 20px; margin: 0px;">All Contacts</h1>
</c:Header>
<c:Content>
<c:List sobject="Contact" labelField="Name"
subLabelField="Account.Name" sortByField="FirstName"
listFilter="true"/>
</c:Content>
</c:Page>
</apex:define
While defining the content of the left menu section, you use the Page component, which provides an important wrapper to
define the fixed header and footer components with a scrollable content section in between. Within the Page component,
you use the Header component to define the fixed title of the section. Following the header, you use the Content component
to describe the scrollable content section. Within the body of Content component, you use the List component to fetch
and display the Contact list. Use the sObject attribute on the List component to specify the sObject type for creating
the list view. Use other attributes such as labelField, subLabelField, sortByField, and listFilter to specify the
behavior and display properties of this list (hopefully, the attribute names are self-explanatory).
Now take a look at the content inside the main section of the split view.
<c:Page name="main">
<c:Header >
<h1 style="font-size: 22px; margin: 0px;">Contact Details</h1>
</c:Header>
<c:Content >
<c:Detail sobject="Contact"/>
</c:Content>
</c:Page>
</apex:define>
Similar to menu section, you use the Page component to define the contents of main section and to enable the use
of Header, Footer, and Content components. Using the Header component, you specify the title to this section. Following
the Header component, use the Content component to specify the Detail component. The Detail component takes the
sObject type as an attribute and generates the mobile layout with details of the associated record. The Page layout associated
to the current user profile and associated record type drives the mobile layout of the record. This gives administrators the
flexibility to update the mobile layout by using the standard Salesforce Page layout manager and avoids a requirement for
code modifications.
<c:Detail sobject="Contact"/>
58
Hybrid Development with Mobile Components for Visualforce Easy Integration
Easy Integration
The List and Detail components respect your org's Object, Field, and Record visibility settings. Consequently, you
can develop apps using these components without having to modify existing security settings. Also, you can easily override
the CSS styles of these components to give them a look and feel as required by your project.
If you already know jQuery Mobile, notice that the Page, Header, Footer, and Content components actually use the
jQuery Mobile properties to enable the mobile user experience. So, while using this component library, you can easily leverage
other features of jQuery Mobile too.
59
Hybrid Development with Mobile Components for Visualforce Creating a Mobile Component for Visualforce
framework searches the document for these elements and takes control of them, adding behavior and styles that brands it as
a mobile app. For example, an element with a data-role value of page defines it as the most basic building block of a jQuery
Mobile application -- a single mobile-optimized page. When the page is parsed, jQuery Mobile fills the screen with its contents,
treating it as a single page in the mobile app.
There are other data-role attributes, which are designed to be used together to create a mobile app. A page section looks best
when it has a header section on top, a content section in the middle, and a footer section on the bottom. When elements with
these data-role values are nested inside a page, the framework ensures that it looks as it should and that it looks consistent
across devices. Besides nesting elements, you can combine app sections horizontally as well. If a page section
has sibling page sections, jQuery Mobile displays only the first page section when loading the app, and removes the others
from the DOM to keep it lean and responsive. Don’t worry, those pages are cached, and can be displayed by hash-linking to
them by page ID, complete with page load and transition animations.
<div data-role="content">
<p>Hello world</p>
</div><!-- /content -->
</div><!-- /page -->
60
Hybrid Development with Mobile Components for Visualforce Creating a Mobile Component for Visualforce
A Visualforce page contains a variety of components, including mobile components provided by Mobile Components for
Visualforce. A mobile component relies on a JavaScript controller, a JavaScript Remoting bridge, and a Visualforce controller
to interact with the Force.com database.
jQuery Mobile has this type of list, called a Thumbnails List, which gives us a good head-start. In this section, we're going
to walk through the code that builds such a component, both high-level in justifying the responsibility of each code snippet
and low-level by showing and explaining implementation details. With such an approach, this section is intended to be useful
as an introduction and reference for readers who may wish to create other types of components.
61
Hybrid Development with Mobile Components for Visualforce Creating a Mobile Component for Visualforce
Following Along
If you would like to have a working example to follow along:
1. Create a new, free Developer Edition (DE) org.
2. Install the example managed package to build everything related to a new ThumbnailsList component.
This package includes:
• A custom fork of the Mobile Components for Visualforce framework that includes some modified versions of provided
components, such as Page.
• The ThumbnailList component with a demo page named ThumbnailList.
<apex:component controller="ThumbnailListController">
<!-- Content -->
<apex:attribute name="sObjectType" type="String" required="true"
assignTo="{!config.sObjectType}" description=""/>
<apex:attribute name="filter" type="String" required="false" assignTo="{!config.filter}"
description="owner|recent|follower"/>
<apex:attribute name="filterClause" type="String" required="false"
assignTo="{!config.filterClause}"
description="SOQL WHERE clause to use to filter list records."/>
<!-- UI -->
<apex:attribute name="imageUrlField" type="String" required="true"
assignTo="{!config.imageUrlField}" description=""/>
<apex:attribute name="labelField" type="String" required="true"
assignTo="{!config.labelField}" description=""/>
<apex:attribute name="subLabelField" type="String" required="true"
assignTo="{!config.subLabelField}" description=""/>
<apex:attribute name="listItemStyleClass" type="String"
assignTo="{!config.listItemStyleClass}" description=""/>
<apex:attribute name="sortByField" type="String" required="true"
assignTo="{!config.sortByField}" description=""/>
<apex:attribute name="listDividerStyleClass" type="String"
assignTo="{!config.listDividerStyleClass}" description=""/>
<apex:attribute name="listDividerStyleClass" type="String"
assignTo="{!config.listDividerStyleClass}" description=""/>
<apex:attribute name="listFilter" type="Boolean" default="false" description=""/>
<!-- Behaviour -->
<apex:attribute name="nextPage" type="String" assignTo="{!config.nextPage}" description=""/>
<script>$V.App.registerComponent('{!$Component.list}', {!configAsJson});</script>
</apex:component>
62
Hybrid Development with Mobile Components for Visualforce Creating a Mobile Component for Visualforce
• Line 1: Notice that the component uses a custom Visualforce controller ThumbnailListController. We'll examine this
controller soon.
• Lines 3-20: These are run-time parameters that the component accepts. When a Visualforce page utilizes this component,
the component passes the associated attribute values to its controller, which in turn passes them on to its JavaScript controller
to reference. Note that the assignTo parameters of each attribute reference the config object, which is defined on the
Visualforce controller. We'll review both of these controllers in subsequent sections.
• Line 23: This line includes the custom JavaScript controller, which is stored in the database as a static resource. We'll
review this controller soon.
• Line 24: The example Visualforce page in the next section includes a list item template that uses Mustache tags, which is
a well-known logic-less template tool. Therefore, we'll need a JavaScript library that can parse the tags and fill the template
with data. The Mustache-supporting template tool that we are using for this component is called ICanHaz, which is freely
available as open source code. This line includes ICanHaz, which is also stored in our database as a static resource.
• Lines 26-28: A standard outputPanel to which the list items we generate will be appended.
• Line 30: All components must register with the framework before they can render on page requests, which is what this
line is doing. For future discussions, note that this is where the JavaScript controller receives the config object that is stored
in the Visualforce controller. This config object is used by both Visualforce and JavaScript controllers, as it communicates
essential information between them, such as the Visualforce controller's name, the root element of the list, and whether
the mobile app is in debug mode and permits debug messages. This function parameter is expecting a JSON string, so
there's a method in the Visualforce controller, getConfigAsJson, that serializes the config object into JSON.
63
Hybrid Development with Mobile Components for Visualforce Creating a Mobile Component for Visualforce
<c:Header >
<h1 style="font-size: 20px; margin: 0px;">All Users</h1>
</c:Header>
<c:Content >
<c:ThumbnailList sObjectType="User"
imageUrlField="FullPhotoUrl"
labelField="Name"
subLabelField="Phone"
sortByField="Name"
listFilter="true"
filter="recent"
debug="true"/>
</c:Content>
</c:Page>
</c:App>
<style>
[data-role="panel"][data-id="main"] [data-role="page"].ui-page .ui-content {
background: white;
}
.ui-body-touch, .ui-overlay-touch {
font-family: Helvetica, Arial, sans-serif
}
</style>
</apex:page>
First, let's discuss the HTML template defined by the <script id="rowItemTempl"> tag, Lines 3-28. This template is an extension
of the HTML for the example Thumbnail List on the jQuery Mobile site. At the beginning of this article, we described how
jQuery Mobile reads elements that have specific properties. We need to use this array of properties on the li tags to ensure
they are styled properly by jQuery Mobile when they are added to the page's DOM.
Also, notice that the rowItemTempl template uses Mustache tags - ({{records}}, {{Id}}, {{FullPhotoURL}}, and {{Phone}}) -
as placeholders for field values to simplify the process of transforming JSON data into HTML elements. After parsing this
template with ICanHaz (discussed previously), we can push JSON data into it, which we receive from our JavaScript Remoting
requests to the Visualforce controller. This quickly and easily creates a list of li tags, each with data specific to each record
retrieved, and each with particular attributes that jQuery Mobile can parse and handle. With this complete, we now have a
complete way of getting Salesforce data and rendering it to the page such that it looks like a native mobile app.
In the body of the page, review Lines 38-45. All that's necessary is a reference to the custom ThumbnailList component
(discussed previously), providing values for each of the component's attributes.
(function($) {
$V.ThumbnailListController = $V.Component.extend({
init: function(config) {
this._super(config);
},
prepare: function() {
this._super();
},
render: function() {
this._super();
// Load records from the server, and give it a function to handle the response.
$.mobile.showPageLoadingMsg();
var serverRecords = this.requestRecords(this.requestRecordsHandler);
$.mobile.hidePageLoadingMsg();
},
requestRecords: function(responseHandler) {
64
Hybrid Development with Mobile Components for Visualforce Creating a Mobile Component for Visualforce
Line 2 demonstrates the syntax to use when inheriting the framework's $V.Component class. How to implement this JavaScript
controller, even though it is noted in the documentation, needs more clarification. When extending this framework class, we
need to fulfill the implied contract, which is to implement the init, prepare, and render methods, and call the this._super() method
before any of their implementation logic. You can see this in Lines 3-25.
Let's look deeper at the significance of these methods. Why are they necessary, and how should they be implemented? These
methods are called from the framework, and the framework expects them to perform specific actions. The framework will call
a component's init method when the object is first created, the prepare method right before rendering the component, and
the render method when the user requests the component to be rendered. With a simple implementation like ours, we don’t
need to do anything to setup this object, so we can leave the init method empty. For the same reason, we can also leave
the prepare method empty. Our efforts are focused on the render method, in which we generate the list items by using the
HTML template in our page (see previous section). This render method:
• Fetches records from the server by calling the JavaScript Remoting method in our Visualforce controller, getRecordsForConfig.
We'll take a look at this method in the next section.
• Handles the server response with the requestRecordsHandler method, which translates the record data into HTML strings,
using therowItemTempl template, and appends it to the ul element in the DOM.
65
Hybrid Development with Mobile Components for Visualforce Creating a Mobile Component for Visualforce
// constructor
public ThumbnailListController() {
this.config = new ThumbnailListConfig();
}
@RemoteAction
public static List<Sobject> getRecordsForConfig(ThumbnailListConfig config) {
System.debug('--- config: ' + config);
Set<String> fieldsToQuerySet = new Set<String>();
fieldsToQuerySet.add(config.imageUrlField);
fieldsToQuerySet.add(config.labelField);
fieldsToQuerySet.add(config.subLabelField);
fieldsToQuerySet.add(config.sortByField);
return recordList;
}
public static List<Sobject> getRecords(
String sObjectType,
Set<String> fieldsToQuerySet,
Id userId) {
66
Hybrid Development with Mobile Components for Visualforce Creating a Mobile Component for Visualforce
recordList = Database.query(queryString);
return recordList;
}
• Lines 3-27: These methods set up the config object. Remember, both the JavaScript controller and Visualforce controller,
discussed earlier, rely on the config object to communicate essential information back and forth.
• Lines 76-80: A method to serialize the config object as JSON, meant to be passed to the $V.App.registerComponent method,
in Line 30 of the component.
• Lines 29-32: A script include tag in the ThumbnailList component itself (Line 23) relies on this getThumbnailListJS method
to get the name of the JavaScript controller's file name. By allowing a method to supply the name of this file, we can inject
logic that returns either the full source code version or a minified version. A minified version would be more suitable when
deploying this code to production, since it is a smaller filesize and a user can load the script faster.
• Lines 34-50: The getRecordsForConfig method is the JavaScript Remoting method that links together the JavaScript and
Visualforce controllers. When called by the JavaScript controller's requestRecords function, getRecordsForConfig does some
setup and calls thegetRecords method in the Visualforce controller to fetch and return the requested records.
• Lines 51-74: The getRecords method in the Visualforce controller fetches and returns the requested records.
Wrapping Up
You can see the fruits of your labor and open the example page that uses the component you just looked at. In your DE org,
navigate to<pod>.salesforce.com/apex/ThumbnailList to see the demo page that uses the new component. These components
will help bring mobile app development to a wider audience, enabling the thousands of Visualforce developers out there to
easily create mobile apps.
67
Chapter 7
Authentication, Security, and Identity in Mobile Apps
In this chapter ... Secure authentication is essential for enterprise applications running on mobile
devices. OAuth2 is the industry-standard protocol that allows secure
• OAuth2 Authentication Flow authentication for access to a user's data, without handing out the username and
• Creating a Remote Access password. It is often described as the valet key of software access: a valet key only
Application allows access to certain features of your car: you cannot open the trunk or glove
compartment using a valet key.
The Salesforce OAuth2 implementation can quickly and easily be embedded by
mobile app developers. The implementation uses an HTML view to collect the
username and password, which are then sent to the server. A session token is
returned and securely stored on the device for future interactions.
68
Authentication, Security, and Identity in Mobile Apps OAuth2 Authentication Flow
Ongoing Authentication
1. User opens a mobile application.
2. If the session ID is active, the app starts immediately. If the session ID is stale, the app uses the refresh token from its
initial authorization to get an updated session ID.
3. App starts.
Warning: Because the access token is encoded into the redirection URI, it might be exposed to the end-user and
other applications residing on the computer or device.
If you are authenticating using JavaScript, call window.location.replace(); to remove the callback from the
browser’s history.
69
Authentication, Security, and Identity in Mobile Apps OAuth 2.0 Refresh Token Flow
1. The client application directs the user to Salesforce to authenticate and authorize the application.
2. The user must always approve access for this authentication flow. After approving access, the application receives the
callback from Salesforce.
After a consumer has an access token, they can use the access token to access data on the end-user’s behalf and receive a refresh
token to get a new access token if it becomes invalid for any reason.
1. The consumer uses the existing refresh token to request a new access token.
2. After the request is verified, Salesforce sends a response to the client.
Value Description
api Allows access to the current, logged-in user’s account over the APIs, such as REST API or
Bulk API. This also includes chatter_api, allowing access to Chatter API resources.
70
Authentication, Security, and Identity in Mobile Apps Using Identity URLs
Value Description
chatter_api Allows access to only the Chatter API resources.
full Allows access to all data accessible by the logged-in user. full does not return a refresh
token. You must explicitly request the refresh_token scope to get a refresh token.
id Allows access only to the identity URL service.
refresh_token Allows a refresh token to be returned if you are eligible to receive one.
visualforce Allows access to Visualforce pages.
web Allows the ability to use the access_token on the Web. This also includes visualforce,
allowing access to Visualforce pages.
Parameter Description
Access token See “Using the Access Token” in the online help.
Format This parameter is optional. Specify the format of the returned
output. Valid values are:
• urlencoded
• json
• xml
Instead of using the format parameter, the client can also
specify the returned format in an accept-request header using
one of the following:
• Accept: application/json
• Accept: application/xml
• Accept: application/x-www-form-urlencoded
71
Authentication, Security, and Identity in Mobile Apps Using Identity URLs
Parameter Description
Note the following:
• Wildcard accept headers are allowed. */* is accepted and
returns JSON.
• A list of values is also accepted and is checked left-to-right.
For example:
application/xml,application/json,application/html,*/*
returns XML.
• The format parameter takes precedence over the accept
request header.
◊ created_date:xsd datetime value of the creation date of the last post by the user, for example,
2010-05-08T05:17:51.000Z
◊ body: the body of the post
72
Authentication, Security, and Identity in Mobile Apps Using Identity URLs
Note: Accessing these URLs requires passing an access token. See “Using the Access Token” in the online help.
◊ picture
◊ thumbnail
• urls—A map containing various API endpoints that can be used with the specified user.
Note: Accessing the REST endpoints requires passing an access token. See “Using the Access Token” in the
online help.
◊ enterprise (SOAP)
◊ metadata (SOAP)
◊ partner (SOAP)
◊ profile
◊ feeds (Chatter)
◊ feed-items (Chatter)
◊ groups (Chatter)
◊ users (Chatter)
◊ custom_domain—This value is omitted if the organization doesn’t have a custom domain configured and propagated
73
Authentication, Security, and Identity in Mobile Apps Using Identity URLs
<rest>http://na1.salesforce.com/services/data/v{version}/
</rest>
<sobjects>http://na1.salesforce.com/services/data/v{version}/sobjects/
</sobjects>
<search>http://na1.salesforce.com/services/data/v{version}/search/
</search>
<query>http://na1.salesforce.com/services/data/v{version}/query/
</query>
<profile>http://na1.salesforce.com/005x0000001S2b9
</profile>
</urls>
<active>true</active>
<user_type>STANDARD</user_type>
<language>en_US</language>
<locale>en_US</locale>
<utcOffset>-28800000</utcOffset>
<last_modified_date>2010-06-28T20:54:09.000Z</last_modified_date>
</user>
{"id":"http://na1.salesforce.com/id/00Dx0000001T0zk/005x0000001S2b9",
"asserted_user":true,
"user_id":"005x0000001S2b9",
"organization_id":"00Dx0000001T0zk",
"nick_name":"admin1.2777578168398293E12foofoofoofoo",
"display_name":"Alan Van",
"email":"admin@2060747062579699.com",
"status":{"created_date":null,"body":null},
"photos":{"picture":"http://na1.salesforce.com/profilephoto/005/F",
"thumbnail":"http://na1.salesforce.com/profilephoto/005/T"},
"urls":
{"enterprise":"http://na1.salesforce.com/services/Soap/c/{version}/00Dx0000001T0zk",
"metadata":"http://na1.salesforce.com/services/Soap/m/{version}/00Dx0000001T0zk",
"partner":"http://na1.salesforce.com/services/Soap/u/{version}/00Dx0000001T0zk",
"rest":"http://na1.salesforce.com/services/data/v{version}/",
"sobjects":"http://na1.salesforce.com/services/data/v{version}/sobjects/",
"search":"http://na1.salesforce.com/services/data/v{version}/search/",
"query":"http://na1.salesforce.com/services/data/v{version}/query/",
"profile":"http://na1.salesforce.com/005x0000001S2b9"},
"active":true,
"user_type":"STANDARD",
"language":"en_US",
"locale":"en_US",
"utcOffset":-28800000,
"last_modified_date":"2010-06-28T20:54:09.000+0000"}
After making an invalid request, the following are possible responses from Salesforce:
74
Authentication, Security, and Identity in Mobile Apps Revoking OAuth Tokens
Revoking Tokens
To revoke OAuth 2.0 tokens, use the revocation endpoint:
https://login.salesforce.com/services/oauth2/revoke
Construct a POST request that includes the following parameters using the application/x-www-form-urlencoded
format in the HTTP request entity-body. For example:
token=currenttoken
If an access token is included, we invalidate it and revoke the token. If a refresh token is included, we revoke it as well as any
associated access tokens.
The authorization server indicates successful processing of the request by returning an HTTP status code 200. For all error
conditions, a status code 400 is used along with one of the following error responses.
• unsupported_token_type—token type not supported
• invalid_token—the token was invalid
75
Authentication, Security, and Identity in Mobile Apps Creating a Remote Access Application
3. Click New.
4. For Application, enter a name, such as Test Client
5. For Callback URL, enter sfdc://success
Note: The Callback URL does not have to be a valid URL; it only has to match what the app expects in this
field. You can use any custom prefix, such as sfdc:///.
Tip: The detail page for your remote access configuration displays a consumer key. It’s a good idea to copy the key,
as you'll need it later. Mobile apps do not use the Consumer Secret, so you can just ignore this value.
76
Chapter 8
Connected Apps
In this chapter ... A Connected App is an application that can connect to salesforce.com over
Identity and Data APIs. Connected Apps use the standard OAuth 2.0 protocol
• Developing and Managing to authenticate, provide Single Sign-On, and acquire access tokens for use with
Connected Apps Salesforce APIs. In addition to standard OAuth capabilities, Connected Apps
• Developer Tasks add additional levels of control, allowing administrators explicit control over who
• Administrator Tasks may use the application, and various security policies which should be enforced.
Connected Apps are enabled in all new Developer Edition organizations. Existing
Developer Edition organizations and all other Salesforce organizations can request
to have Connected Apps enabled as part of a pilot program.
Note: The Connected Apps feature is currently available through a
pilot program. For information on enabling it for your organization,
contact your salesforce.com representative. Any unreleased services or
features referenced in this or other press releases or public statements
are not currently available and might not be delivered on time or at all.
Customers who purchase our services should make their purchase
decisions based upon features that are currently available.
77
Connected Apps Developing and Managing Connected Apps
In return, the developer is provided an OAuth client Id and client secret, as well as an install URL for the Connected App.
The developer can then provide this URL to a Salesforce administrator.
The administrator can install the Connected App into their organization and use profiles, permission sets, and IP range
restrictions to control which users can access the application. Management is done from a detail page for the Connected App.
The administrator can also uninstall the Connected App and install a newer version. When the app is updated, the developer
can notify administrators that there is a new version available for the app — their existing installation URL installs the new
version.
Developer Tasks
The lifecycle of a Connected App is made up of these steps:
• Creating a Connected App
• Publishing a Connected App
• Deleting a Connected App
• Updating a Connected App
The information required to create a Connected App is divided into these parts:
78
Connected Apps Creating a Connected App
• Basic Information describes your application, its appearance in the list of available applications, and how someone can
contact you about the application.
• API Integration specifies how your application communicates with Salesforce.
• Mobile Integration specifies PIN length and session timeout values available for mobile applications.
• IP Ranges are the list of IP addresses that can access the app without requiring the user to authenticate. You set these after
creating the app.
When you’ve finished entering the information, click Save to save your new app. You can now publish your app, make further
edits, or delete it. Saving your app gives you the Consumer Key and Consumer Secret the app uses to communicate with
Salesforce.
2. In Description, enter an optional description for your application. This also displays in the list of Connected Apps.
3. Optionally enter the Logo Image URL for your application logo. The URL must use HTTPS and the logo cannot be
larger than 125 pixels high or 200 pixels wide. The default logo is a cloud.
4. You can optionally enter an Info URL if you have a Web page for more information about your application.
5. Enter a phone number in Contact Phone for salesforce.com to use in case we need to contact you. This number is not
provided to administrators installing the app.
6. In Contact Email, enter the email address salesforce.com should use for contacting you or your support team. This address
is not provided to administrators installing the app.
79
Connected Apps Publishing a Connected App
If your organization had the No user approval required for users in this organization option selected on
your remote access prior to the Spring ’12 release, users in the same organization as the one the app was created in still have
automatic approval for the app. The read-only No user approval required for users in this organization
checkbox is selected to show this condition. For Connected Apps, the recommended procedure after you’ve created an app is
for administrators to install the app and then set Permitted Users to Admin-approved users. If the remote access
option was not checked originally, the checkbox doesn’t display.
80
Connected Apps Deleting a Connected App
When you click Publish, you are asked to confirm that you want to publish the Connected App. Confirm by clicking Publish.
The Version is incremented by 1 and new values are created:
• Installation URL – Administrators use this URL to install the Connected App in their organizations.
• Consumer Key – A value used by the consumer to identify itself to Salesforce. Referred to as client_id in OAuth 2.0.
• Consumer Secret – A secret used by the consumer to establish ownership of the consumer key. Referred to as
client_secret in OAuth 2.0.
Note: Any OAuth approvals done for an unpublished Connected App, for example during testing, will be valid
against the first published version as well. The approvals will not transfer to subsequently published versions.
81
Connected Apps Administrator Tasks
Administrator Tasks
Administrators perform these tasks with Connected Apps:
• Installing a Connected App
• Managing a Connected App
• Uninstalling a Connected App
• Upgrading a Connected App
If you are logged into more than one Salesforce organization, the installation will select one. Check the username shown in
the upper right corner to make sure that the app will be installed in the correct organization. If the username shown isn’t the
correct one, click Not you? to log out and stop the installation.
If any version of the Connected App is already installed in your organization you’ll see an error message telling you this.
Uninstall your current version and then install the new version.
After installing a Connected App, you’re shown the detail page for the app. You can edit the app policies from this page.
82
Connected Apps Managing a Connected App
◊ IP Restrictions refers to the IP restrictions that the users of this Connected App are subject to. An administrator
can choose to either enforce or bypass these restrictions by choosing one of the following options.
- Enforce IP Restrictions – Default. A user running this app is subject to the organization’s IP restrictions,
such as IP ranges set in the user’s profile.
- Relax IP Restrictions with Second Factor – A user running this app bypasses the organization’s IP
restrictions if either of these conditions are true:
- The app has IP ranges whitelisted and is using the Web server OAuth authentication flow. Only requests coming
from the whitelisted IPs are allowed.
- The app has no IP range whitelist, is using the Web server or user-agent OAuth authentication flow, and the
user successfully completes Identity Confirmation.
- Relax IP Restrictions – A user running this app is not subject to any IP restrictions.
◊ Start URL is used if the Connected App uses single sign-on. In this case, set the URL to the page the user goes to
to start the authentication process.
◊ Mobile Integration settings are available for any Connected App that’s a mobile application.
- Session Timeout specifies how much time can pass while the app is idle before the app locks itself and requires
the PIN before continuing. Allowable values are 1, 5, 10, and 30 minutes.
- Pin Length sets the length of the identification number sent for authentication confirmation. The length can be
from 4 to 8 digits, inclusive.
83
Connected Apps About PIN Security
• Uninstall the Connected App by clicking Uninstall. Click OK to confirm the uninstallation. You have to uninstall an
app before you can install a new version.
• Click the app’s name to review the Connected App on the Detail page. You can click Edit or Uninstall from this page
to make changes after reviewing the app. This is also where you assign profiles and permission sets to the app.
◊ Click Manage Permission Sets to select the permission sets for the profiles for this app from the Application
Permission Set Assignment page. Select the permission sets to have access to the app.
◊ Click Manage Profiles to select the profiles for this app from the Application Profile Assignment page. Select the
profiles to have access to the app.
Only the users belonging to at least one of the selected profiles or permission sets can run the app if you have selected
Admin-approved users for the Permitted Users value. If you selected All Users instead, profiles and permission
sets are ignored.
• If the app has been deleted by its developer, Remove is the only action available, and removes the app from the list.
Note: Because PIN security is implemented in the mobile device’s operating system, only native and hybrid mobile
apps can use PIN protection; HTML5 Web apps can’t use PIN protection.
In practice, PIN protection can be used so that the mobile app locks up if it isn’t used for a specified number of minutes. Note
that when a mobile app is sent to the background, the clock continues to tick.
To illustrate how PIN protection works:
84
Connected Apps Uninstalling a Connected App
85
Chapter 9
Securely Storing Data Offline
In this chapter ... Mobile devices can lose connection at any time, and environments such as
hospitals and airplanes often prohibit connectivity. To handle these situations,
• Accessing SmartStore in Hybrid it’s important that your mobile apps continue to function when they go offline.
Apps
The Mobile SDK uses SmartStore, a secure offline storage solution on your
• Offline Hybrid Development
device. SmartStore allows you to continue working even when the device is not
• Using the Mock SmartStore connected to the Internet. SmartStore stores data as JSON documents in a data
• Registering a Soup structure called a soup. A soup is a simple one-table database of “entries” which
• Retrieving Data From a Soup can be indexed in different ways and queried by a variety of methods.
• Working With Cursors Note: Pure HTML5 apps store offline information in a browser cache.
• Manipulating Data Browser caching isn’t part of the Mobile SDK, and we don’t document
• SmartStore Extensions it here. SmartStore uses storage functionality on the device. This strategy
requires a native or hybrid development path.
Sample Objects
The code snippets in this chapter use two objects, Account and Opportunity,
which come predefined with every Salesforce organization. Account and
Opportunity have a master-detail relationship; an Account can have more than
one Opportunity.
86
Securely Storing Data Offline Accessing SmartStore in Hybrid Apps
You store your offline data in SmartStore in one or more soups. A soup, conceptually speaking, is a logical collection of data
records—represented as JSON objects—that you want to store and query offline. In the Force.com world, a soup will typically
map to a standard or custom object that you wish to store offline, but that is not a hard and fast rule. You can store as many
soups as you want in an application, but remember that soups are meant to be self-contained data sets; there is no direct
correlation between them. In addition to storing the data itself, you can also specify indices that map to fields within the data,
for greater ease and customization of data queries.
Note:
SmartStore data is inherently tied to the authenticated user. When the user logs out of the app, SmartStore deletes
soup data associated with that user.
Note: The MockSmartStore doesn't encrypt data and is not meant to be used in production applications.
Inside the PhoneGap directory, there’s a local directory containing the following files:
• MockCordova.js—A minimal implementation of Cordova functions meant only for testing plugins outside the container.
87
Securely Storing Data Offline Registering a Soup
• MockSmartStore.js—A JavaScript implementation of the SmartStore meant only for development and testing outside
the container.
• MockSmartStorePlugin.js—A JavaScript helper class that intercepts SmartStore Cordova plugin calls and handles
them using a MockSmartStore.
• CordovaInterceptor.js — A JavaScript helper class that intercepts Cordova plugin calls.
When writing an application using SmartStore, make the following changes to test your app outside the container:
Same-origin Policies
Same-origin policy permits scripts running on pages originating from the same site to access each other's methods and properties
with no specific restrictions; it also blocks access to most methods and properties across pages on different sites. Same-origin
policy restrictions are not an issue when your code runs inside the container, because the container disables same-origin policy
in the webview. However, if you call a remote API, you need to worry about same-origin policy restrictions.
Fortunately, browsers offer ways to turn off same-origin policy, and you can research how to do that with your particular
browser. If you want to make XHR calls against Force.com from JavaScript files loaded from the local file system, you should
start your browser with same-origin policy disabled. The following article describes how to disable same-origin policy on
several popular browsers: Getting Around Same-Origin Policy in Web Browsers.
Authentication
For authentication with MockSmartStore, you will need to capture access tokens and refresh tokens from a real session and
hand code them in your JavaScript app. You’ll also need these tokens to initialize the ForceTk JavaScript toolkit.
Registering a Soup
In order to access a soup, you first need to register it. Provide a name, index specifications, and names of callback functions
for success and error conditions:
If the soup does not already exist, this function creates it. If the soup already exists, registering gives you access to the existing
soup. To find out if a soup already exists, use:
A soup is indexed on one or more fields found in its entries. Insert, update, and delete operations on soup entries are tracked
in the soup indices. Always specify at least one index field when registering a soup. For example, if you are using the soup as
a simple key/value store, use a single index specification with a string type.
indexSpecs
The indexSpecs array is used to create the soup with predefined indexing. Entries in the indexSpecs array specify how
the soup should be indexed. Each entry consists of a path:type pair. path is the name of an index field; type is either
“string” or “integer”. Index paths are case-sensitive and can include compound paths, such as Owner.Name.
88
Securely Storing Data Offline Registering a Soup
Note: Performance can suffer if the index path is too deep. If index entries are missing any fields described in a
particular indexSpec, they will not be tracked in that index.
"indexSpecs":[
{
"path":"Name",
"type":"string"
}
{
"path":"Id",
"type":"string"
}
{
"path":"ParentId",
"type":"string"
}
{
"path":"lastModifiedDate",
"type":"integer"
}
]
Note: Currently, the Mobile SDK supports two index types: “string” and “integer.” These types apply only to the
index itself, and not to the way data is stored or retrieved. It’s OK to have a null field in an index column.
successCallback
The success callback function for registerSoup takes one argument (the soup name).
A successful creation of the soup returns a successCallback that indicates the soup is ready. Wait to complete the transaction
and receive the callback before you begin any activity. If you register a soup under the passed name, the success callback function
returns the soup.
errorCallback
The error callback function for registerSoup takes one argument (the error description string).
During soup creation, errors can happen for a number of reasons, including:
• An invalid or bad soup name
• No index (at least one index must be specified)
• Other unexpected errors, such as a database error
89
Securely Storing Data Offline Retrieving Data From a Soup
Parameter Description
indexPath This is what you’re searching for; for example a name, account number, or date.
beginKey Optional. Used to define the start of a range query.
endKey Optional. Used to define the end of a range query.
order Optional. Either “ascending” or “descending.”
pageSize Optional. If not present, the native plugin can return whatever page size it sees fit in the
resulting Cursor.pageSize.
Note:
All queries are single-predicate searches. Queries don’t support joins.
Query Everything
buildAllQuerySpec(indexPath, order, [pageSize]) returns all entries in the soup, with no particular order. Use
this query to traverse everything in the soup.
order and pageSize are optional, and default to ascending and 10, respectively. You can specify:
• buildAllQuerySpec(indexPath)
• buildAllQuerySpec(indexPath, order)
• buildAllQuerySpec(indexPath, order, [pageSize])
Query by Exact
buildExactQuerySpec(indexPath, matchKey, [pageSize]) finds entries that exactly match the given matchKey
for the indexPath value. Use this to find child entities of a given ID. For example, you can find Opportunities by Status.
However, you can’t specify order in the results.
Sample code for retrieving children by ID:
90
Securely Storing Data Offline Retrieving Data From a Soup
Query by Range
buildRangeQuerySpec(indexPath, beginKey, endKey, [order, pageSize]) finds entries whose indexPath
values fall into the range defined by beginKey and endKey. Use this function to search by numeric ranges, such as a range
of dates stored as integers.
order and pageSize are optional, and default to ascending and 10, respectively. You can specify:
Query by Like
buildLikeQuerySpec(indexPath, likeKey, [order, pageSize]) finds entries whose indexPath values are
like the given likeKey. You can use “foo%” to search for terms that begin with your keyword, “%foo” to search for terms that
end with your keyword, and “%foo%” to search for your keyword anywhere in the indexPath value. Use this function for
general searching and partial name matches. order and pageSize are optional, and default to ascending and 10, respectively.
Note: Query by Like is the slowest of the query methods.
navigator.smartstore.querySoup(soupName,querySpec,successCallback,errorCallback);
91
Securely Storing Data Offline Working With Cursors
Note: For advanced users: Cursors are not snapshots of data; they are dynamic. If you make changes to the soup and
then start paging through the cursor, you will see those changes. The only data the cursor holds is the original query
and your current position in the result set. When you move your cursor, the query runs again. Thus, newly created
soup entries can be returned (assuming they satisfy the original query).
Note: successCallback for those functions should expect one argument (the updated cursor).
Manipulating Data
In order to track soup entries for insert, update, and delete, the SmartStore adds a few fields to each entry:
• _soupEntryId—This field is the primary key for the soup entry in the table for a given soup.
• _soupLastModifiedDate—The number of milliseconds since 1/1/1970.
When inserting or updating soup entries, SmartStore automatically sets these fields. When removing or retrieving specific
entries, you can reference them by _soupEntryId.
92
Securely Storing Data Offline Manipulating Data
Note: You must not manipulate the _soupEntryId or _soupLastModifiedDate value yourself.
where soupName is the name of the target soup, and entries is an array of one or more entries that match the soup’s data
structure. The successCallback and errorCallback parameters function much like the ones for registerSoup.
However, the success callback for upsertSoupEntries indicates that either a new record has been inserted, or an existing
record has been updated.
93
Securely Storing Data Offline SmartStore Extensions
Removing a Soup
To remove a soup, call removeSoup(). Note that once a user signs out, the soups get deleted automatically.
navigator.smartstore.removeSoup(soupName,successCallback,errorCallback);
SmartStore Extensions
Some apps might profit by extending the SmartStore API in various ways.
• Secure localStorage—W3C's localStorage is a simple key-value storage that can be readily implemented on top of
SmartStore. For instance, a single localStorage soup can be created by the SmartStore plugin on each platform, and
the matchKey can be the key passed to the localStorage methods. This is a convenience layer for developers who are
already familiar with localStorage and comfortable with its limitations. The main difference in our implementation is
the need to rely on Cordova-style JavaScript callbacks, so all localStorage methods are asynchronous.
• Files and Large Binary Objects—Some apps require the ability to store large binary objects, such as video, PDF, and PPT
files. For these apps, there is currently no consistent secure storage mechanism in Cordova.
94
Chapter 10
Advanced Topics
In this chapter ... The previous chapters focused on getting your basic app built, with some
additional tweaks that show you how to get the sample applications do what you
• Customize the Hybrid Sample App want. By this time you can probably create projects, build apps, and modify the
to Use the Camera sample apps to work with your own organization and its data. The following
• Bar Code and QR Code Scanning sections help you continue to build out your app by adding additional functionality
• Geolocation and Mobile Apps in the device.
• Utilizing Near Field Communication
(NFC) in Hybrid Apps
95
Advanced Topics Customize the Hybrid Sample App to Use the Camera
1. Point your browser to GitHub and download the GlueCon 2012 Salesforce Mobile SDK Demo project into a new directory:
2. Copy the files and images from GlueCon2012-Salesforce-Mobile-SDK-Demo/www directory into your hybrid
app's www directory, overwriting forcetk.js, index.html and inline.js, and creating a new images folder.
Before you run the app, you’ll need to make a couple of customizations to the Contact standard object in your DE org. You’ll
need to create one custom field to hold the image ID, and another to display the image on the Contact Page Layout. The app
uploads images to ContentVersion records, and updates the Contact record with the new ContentVersion record's ID.
1. Log in to your DE account and select Your Name > Setup > App Setup > Customize > Contacts > Fields.
2. Scroll down to Contact Custom Fields & Relationships and click New.
3. Select Text as the field type and click Next.
4. On the following screen, enter:
5. Click Next, then click Next again to accept the field-level security defaults. On the next screen, deselect all of the page
layouts and click Save & New.
Note: The image field should be visible to the user, but the image ID... not so much. By deseleting the ID field
here, it won’t be added to the page layout.
You’re going to create another field, but this one is based on a formula.
4. Click Next, then click Next again to accept the field-level security defaults, and click Save to accept the page layout defaults.
Note: This time the image field should be displayed on all page layouts.
96
Advanced Topics Run the App
Note: There is no camera in the iOS simulator, so you’ll need to run this on a physical device.
1. Launch the app, login if necessary, and click Fetch SFDC contacts.
2. In the demo app, you can click a contact in the list to access a contact detail page, including a placeholder for a photo of
the contact.
97
Advanced Topics How the Demo App Works
6. Click the Contacts tab, you’ll see the contact in the Recent Contacts list.
7. Click on the contact and you’ll see the photo alongside the standard Contact data.
function onSuccessSfdcContactList(response) {
var $j = jQuery.noConflict();
$j("#div_sfdc_contact_list").html("")
var ul = $j('<ul data-role="listview" data-inset="true" data-theme="a"
data-dividertheme="a"></ul>');
$j("#div_sfdc_contact_list").append(ul);
$j("#div_sfdc_contact_list").trigger( "create" )
}
98
Advanced Topics How the Demo App Works
For each record passed in, within the response we create a list item with its name, and set up a click handler on the list item
to retrieve the contact's name, account name, phone number, and image.
The query callback, onSuccessSfdcSingleContact(), populates the contact detail page. Notice the code to display the
contact image.
//Set up image
$j('#Image').attr('data-id', contact.Id);
$j('#Image').attr('data-name', contact.Name);
if (contact.Image_ID__c) {
// Load image data
$j('#Image').attr('src', "images/loading.png");
$j.mobile.changePage('#jqm-detail');
forcetkClient.retrieveBlobField("ContentVersion",
contact.Image_ID__c, "VersionData", function(response) {
var base64data = base64ArrayBuffer(response);
$j('#Image').attr('src', "data:image/png;base64,"+base64data);
$j.mobile.hidePageLoadingMsg();
}, onErrorSfdc);
} else {
// Display a default image
$j.mobile.hidePageLoadingMsg();
$j('#Image').attr('src', "images/blank.png");
$j.mobile.changePage('#jqm-detail');
}
The contact ID and name are set as attributes on the image element, and, if there is an ID in the Image_ID__c custom
field, a 'loading' image is displayed, and the image data is retrieved via retrieveBlobField().
The base64ArrayBuffer() utility function converts the JavaScript ArrayBuffer object to base64-encoded data as a
string, and the callback sets the image data as a data URI.
Looking at regLinkClickHandlers(), this function loses the #link_fetch_device_contacts and
#link_fetch_sfdc_accountshandlers, but gains a new one:
$j('#Image').click(function() {
getPhotoAndUploadToContact($j(this).attr('data-name'),
$j(this).attr('data-id'));
});
Clicking the image calls the getPhotoAndUploadToContact() function, passing in the contact name and ID attributes
from the image element.
$j('#Image').attr('data-old-src', $j('#Image').attr('src'));
$j('#Image').attr('src', "images/camera.png");
navigator.camera.getPicture(function(imageData){
onPhotoDataSuccess(imageData, name, contactId);
}, function(errorMsg){
// Most likely error is user cancelling out of camera
$j('#dialog-text').html(errorMsg);
$j.mobile.changePage('#jqm-dialog');
$j('#Image').attr('src', $j('#Image').attr('data-old-src'));
$j('#Image').removeAttr('data-old-src');
}, {
quality: 50,
99
Advanced Topics Bar Code and QR Code Scanning
sourceType: Camera.PictureSourceType.CAMERA,
destinationType: Camera.DestinationType.DATA_URL
});
}
getPhotoAndUploadToContact() really shows the power of the hybrid approach. The getPicture() function
onnavigator.camera provides easy access to the device camera. The options passed to getPicture() specify the required
image quality, source (camera in this case, as opposed to the device's photo library), and the format in which the picture should
be returned. Camera.DestinationType.DATA_URL returns the image as a base64–encoded string, while
Camera.DestinationType.FILE_URI returns a URI to a file on the device.
After updating the on-screen image, a ContentVersion record is created. Note that we indicate the type of the data via the
extension on the PathOnClient field. On successful creation, the contact is updated with the ID of the
new ContentVersion record.
100
Advanced Topics Bar Code and QR Code Scanning
So how does one go about adding support for bar code scanning in a Hybrid mobile application? This is where the beauty of
the PhoneGap (aka Apache Cordova) hybrid framework shines through. PhoneGap has a rich ‘plugin’ library of open source
components built by the community to support advanced use cases like push notification, mobile payments (using PayPal)
and yes, bar code and QR Code scanning. In fact, the Salesforce Mobile SDK itself uses PhoneGap plugins to support our
OAuth login process and our secure offline storage (aka SmartStore).
Let’s say we wanted to enhance our MerchandiseMobile Visualforce page to allow users to search for Merchandise records by
scanning a bar code or QR Code. You can peruse the final codebase for this application in GitHub, but here are the step-by-step
instructions for adding bar code scanning to your Hybrid mobile application.
1. Convert your Visualforce page into a Hybrid application using the Salesforce Mobile SDK. Detailed instructions on how
you can do this can be found in Tutorials 5 (iOS) and 6 (Android) of the Mobile SDK workbook.
2. Download the GitHub repo for the PhoneGap plugins to your local machine (using git clone or clicking the ‘Downloads’
link on the top right). Depending on which mobile platform you’re developing for, follow the instructions in the readme
file to import the bar code scanner plugin in your Android or iOS project.
3. Import the barcodescanner.js file that is included in the PhoneGap plugin Git repo into your Visualforce page. For example,
here is a small snippet from my MerchandiseMobile VF page.
<apex:includeScript value="{!URLFOR($Resource.BarCodeScanner)}"/>
Note: You also need to import the core PhoneGap JS file in your Visualforce page.
4. We’re now ready to initiate bar code scanning from our Visualforce page. The great thing about PhoneGap is that you can
access all device functions via JavaScript – no iOS/Android specific coding required. Here is how to invoke the Bar Code
scanner PhoneGap plugin in the Visualforce page.
function scanBarCode() {
window.plugins.barcodeScanner.scan(onBarcodeScanSuccess, onBarcodeScanFailure);
}
function onBarcodeScanSuccess(result) {
MerchandiseMobileController.getMerchandiseRecByBarCode(
result.text,
function(res,event){
if (res != null){
$j.mobile.showPageLoadingMsg();
$j('#merchandiseName').html(res.Name);
$j('#description').html(res.Description__c);
101
Advanced Topics Geolocation and Mobile Apps
$j('#inventory').html(res.Total_Inventory__c);
$j('#price').html('$'+res.Price__c);
$j('#merchandiseId').val(res.Id);
$j.mobile.hidePageLoadingMsg();
function onBarcodeScanFailure(error) {
console.log("Barcode scanning failed: " + error);
}
Line 2 shows how simple it is to use bar code scanning using the custom PhoneGap plugin. If the bar code/QR code scan
is successful, the success callback function gets invoked with the scanned text or string (‘result.text’ above). The plugin also
passes along the format of the bar code scanned (e.g. ‘QR_CODE’, ‘UPC_A’, ‘DATA_MATRIX’ etc.) via the ‘result.format’
variable. Then simply use JavaScript Remoting to invoke a method on the Apex controller attached to this VF page (line
6) to search for any Merchandise records that match the scanned bar code value.
In addition to using the hybrid approach described above, you can also implement bar code scanning in a native mobile
application if you’re comfortable with native Android or iOS development.
Note: This is a beta release of geolocation and its functionality has known limitations, outlined here. To provide
feedback on geolocation, go to IdeaExchange.
102
Advanced Topics Utilizing Near Field Communication (NFC) in Hybrid Apps
Decimal
Expresses the value as degrees, and converts the minutes and seconds to a decimal fraction of the degree. Decimal
notation does not use cardinal points. North and East are positive values; South and West are negative values.
5. Follow the steps to complete the wizard.
103
Advanced Topics Requirements
NFC stands for Near Field Communication. It allows devices to exchange data wirelessly at very short ranges (less than a few
centimeters). Devices that can transmit data via NFC are called "tags." Tags can come in varying physical shapes and sizes,
such as round stickers, business cards, credit cards, or nametags. They also come in a variety of data sizes, holding as little as
a few bytes to up to four Kilobytes or more. As you might expect, the data on tags can be encoded in a variety of formats. That
being said, there is one format that is widely used called NDEF (NFC Data Exchange Format). Formatting a tag in NDEF
format allows an easy exchange of the tag data with systems that leverage the format. For example, Android devices support
the NDEF format and are the easiest format to get started with.
Requirements
You need to ensure you have a mobile device that supports NFC if you want to execute this application in the wild. You can
get a list of Android NFC phones online by searching for “NFC Smartphones.” You'll also need some NFC tags to work with.
Again, you can Google for NFC tags and get a list of retailers who sell blank or NDEF-formatted tags. Getting the tags
NDEF formatted from the retailer makes it somewhat easier to encode your data. Also, ensure you review the size of data the
NFC tag can hold. Depending on your needs, you might want a tag with more data capacity.
Note that there are some software NFC emulators available for downloading if you don’t have the hardware. Software emulators
are not covered here.
<script type="text/javascript"
src="[view-source:https://dl-web.dropbox.com/get/SalesforceMobileSDK-Android/
hybrid/SampleApps/ContactExplorer/assets/www/phonegap-nfc-0.2.0.js
phonegap-nfc-0.2.0.js] script>
5. Update your PhoneGap plugin xml file (plugins.xml) to include the plugin class:
104
Advanced Topics Invoking the NFC Plugin via JavaScript
6. Update your Android Manifest file to allow the application device permission to use NFC:
7. Optional – Android has a special notification system for NFC tags. The NFC Tag Dispatcher runs in the background of
Android and can be configured to automatically start an application once a device scans an NFC tag. This allows your
application to instantly fire when an NFC tag is read. To do this, update your Android Manifest with the proper intent
tags:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<data android:mimeType="text/pg" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
That is everything you need to do to configure your workspace and application for NFC. Now, let’s take a look at the application
code.
//enable buttons
regLinkClickHandlers();
//Use the NFC Plugin to configure the NFC Tag Reader Listener
nfc.addNdefListener(
onNfcRead,
successNFCRegisterListener,
errorNFCRegisterListener
);
regLinkNFCClickHandlers();
As you can see above, you specify the callback handler (onNfcRead) to process the tag data returned from the NFC tag. You
also have two additional callback methods specified: successNFCRegisterListener and errorNFCRegisterListener.
Those methods execute once the listener is successfully register in our JavaScript.
105
Advanced Topics Invoking the NFC Plugin via JavaScript
You can specify in the JavaScript how to handle the results of a NFC tag. The code below displays the NFC tag data on the
screen when it’s scanned. Then parse the tag data, formatted in vCard format, and store it in a contact variable. This contact
variable eventually passes to the Mobile SDK to be inserted into Salesforce.
function onNfcRead(nfcEvent) {
console.log(JSON.stringify(nfcEvent.tag)); // Debug in Console
clearScreen(); // Clear Previosly Display Tag Info
var tag = nfcEvent.tag;
var records = tag.ndefMessage || [],
//Tag Content HTML Div
display = document.getElementById("tagContents");
display.appendChild(
document.createTextNode(
"Scanned an NDEF tag with " + records.length +
" record" + ((re-cords.length === 1) ? "": "s")
)
);
if (device.platform.match(/Android/i)) {
if (tag.id) {
showProperty(meta, "Id", nfc.bytesToHexString(tag.id));
}
var hcard = document.createElement("div");
hcard.innerHTML =
vCard.initialize(nfc.bytesToString(tag.ndefMessage[0].payload)).to_html();
display.appendChild(hcard);
var vCardVal = vCard.initialize(nfc.bytesToString(tag.ndefMessage[0].payload));
//parse the Tag formatted vCard data into a Javascript Object
var names = vCardVal.fn.split(" ");//Take Fullname from vCard
contact.firstName = names[0]; //Put in Firstname for SFDC
contact.lastName = names[1]; //Put in LastName for SFDC
for(type in vCardVal.email)
{
for(n in vCardVal.email['home'])
{
//Store email in contact variable for SFDC Upsert
contact.email = vCardVal.email['home'][n];
contact.vCard_Email__c = contact.email;
}
}
for(type in vCardVal.tel)
{
for(n in vCardVal.tel[type])
{
//Store Telephone Info in variable for SFDC Upsert
contact.phone = vCardVal.tel[type][n];
}
}
meta.appendChild(hcard);
}
navigator.notification.vibrate(100);
}
As you can see in the above code, the JavaScript processes the returned NDEF tag payload from the NFC plugin. You then
parse the tag information, format in vCard format, and append it to the DOM. The information then renders on the screen
to the user. If you are unfamiliar with vCard formatted data, it is basically a way to electronically represent widely-used business
card data.
106
Advanced Topics Upserting the Information into Force.com with Mobile SDK
$j('#insert_lead_from_nfc_tag').click(function(){
SFHybridApp.logToConsole("Upsert vCard Contact to SFDC " +
contact.vCard_Email__c + contact.lastName + contact.phone);
forcetkCli-ent.upsert("Contact","Contact_Ext_ID__c",
contact.contactextid,contact,onSuccessSfdcUpsertContact,onErrorSfdc);
});
After following this use case through completely, if you navigate to the Contacts tab in Force.com and view the recently-added
Contacts, you can see the newly-created contact from our NFC tag!
107
Chapter 11
Distributing Mobile AppExchange Apps
In this chapter ... Apps have completely redefined the mobile experience. When selecting a new
smartphone or a tablet, consumers consistently rate app availability as the most
• AppExchange for Mobile: Enterprise import factor in their decision. So naturally, after you’ve developed your mobile
Mobile Apps app, you’ll want to make it available so customers or staff can easily find, buy it,
• Joining the AppExchange Partner and install it. Android and iOS have proprietary stores that list and distribute
Program mobile apps, which won’t be covered in this guide. Salesforce also has a
• Get a Publishing Org marketplace called the AppExchange, where partners can list mobile apps and
consulting services for Salesforce.
• Create a Provider Profile
• The AppExchange Security Review
108
Distributing Mobile AppExchange Apps AppExchange for Mobile: Enterprise Mobile Apps
• Salesforce users can discover brand new mobile apps that are trusted, work with an existing account, and leverage data
that’s already in the cloud.
• ISVs can list their native, hybrid, and HTML5 applications that work on Android, iOS, and other platforms in a central
repository. It doesn’t matter whether the app is free, has a fixed price, or is sold with a subscription model.
Whether you’re a developer that is working on a special purpose app that brings a unique mobile perspective for solving a
specific problem, or a complete solution for a specific role, the space is completely open.
In order to distribute your commercial mobile app on AppExchange, you’ll need to become a Salesforce partner.
109
Distributing Mobile AppExchange Apps Joining the AppExchange Partner Program
Note: If you’re a Salesforce admin creating mobile apps for distribution within your organization, you don’t need a
public listing on the AppExchange.
In the Partner Portal you’ll see quick links to some of the most used resources, and docs and video to get you started quickly.
Most of this information is targeted at ISVs who create add-ons or services for Salesforce users. As a mobile ISV, you’ll want
to work closely with an AppExchange Partner Program representative.
1. In the Partner Portal, in the Quick Links section, click Create a Case.
110
Distributing Mobile AppExchange Apps Create a Provider Profile
8. In the Description field, tell us if you have an existing org or if you need a new one. If you have an existing Salesforce org,
you can provide the Org ID in the Description field and two additional CRM licenses will be added to your org. If you
don't have an existing org, we'll provide a new one for you. In either case, make sure to enter your business address and
then click Save.
9. Shortly, you'll receive another email prompting you to log in and change your password. Do that, and then bookmark the
page as before.
1. On the login page, use your username and password for your AppExchange Publishing Organization (APO).
2. Fill out the information in the Provider Profile and then click Save.
1. Click Start Review on the Offering tab when editing the listing.
2. Select whether you charge for your application or if your application is free. Free applications must complete the review,
but the review fee is waived.
111
Distributing Mobile AppExchange Apps The AppExchange Security Review
3. If you charge for your application, Partner Operations will email you information within two business days on how to pay
for the review. This is an annual payment.
4. Indicate if your application integrates with any web services outside of Force.com, including your own servers.
5. If your application integrates with other web services, list all of them in the Webservices Used box. You can enter up
to 1000 characters.
6. If your application integrates with other web services, select how your application authenticates with those services. Enter
any helpful comments in the box provided. You can enter up to 1000 characters.
7. Indicate if your application stores salesforce.com user credentials outside of Force.com.
8. Indicate if your application stores salesforce.com customer data outside of Force.com.
9. If your application stores salesforce.com customer data outside of Force.com, list all salesforce.com objects accessed in the
Objects Accessed box. You can enter up to 255 characters.
10. Indicate if your application requires that customers install any client components, such as software or plug-ins.
11. If your application requires client components, enter the details in the Requirements box. You can enter up to 1000
characters.
12. Click Start Security Review to start the AppExchange Security Review. To discard your changes and return to the previous
page, click Cancel.
Note: After collecting payment, the security team will send the partner a survey to collect detailed information
on how to test their app. This will include information like install links, test credentials etc. that are mentioned
in the next section.
13. You are contractually required to keep this information current. For example, if you upgrade your app to use a new web
service, you must edit the information in your security review submission. To edit your submission information, click Edit
Review on the Offering tab when editing the listing. Apps are reviewed again periodically.
Mobile apps have additional security steps, and you’ll need to provide the following, depending on the phone type:
• iOS Mobile app — Provide the install link if the application is free and already published to the Appstore. If the application
is not yet approved or is not free, please either provide an ad-hoc installation (contact us for device UDIDs), or a Testflight
link for the app. (no UDID required). More information about Testflight is available at: https://testflightapp.com/. If
credentials other than the Salesforce account login, or related external application credentials are required or optional for
the mobile application, please provide them as well. If sample data is required for the application to function, please include
a logical set of sample data.
• Android app — Provide the .APK for the android application and the target device. If credentials other than the Salesforce
account login, or related external application credentials are required or optional for the mobile application, please provide
them as well. If sample data is required for the application to function, please include a logical set of sample data.
112
Chapter 12
Reference
In this chapter ... The Mobile SDK reference documentation is hosted on GitHub.
113
Reference REST API Resources
114
Reference iOS Architecture
iOS Architecture
At a high level, the current facilities that the native SDK provides to consumers are:
Note: This is not currently exposed to native template apps, but is included in the binary distribution.
The Salesforce native SDK is essentially one library, with dependencies on (and providing exposure to) the following additional
libraries:
◊ RestKit in turn depends on libxml2.dylib, which is part of the standard iOS development environment
Note: This is not currently exposed to native template apps, but exposed in the binary distribution.
• SFRestAPI
• SFRestAPI (Blocks)
• SFRestRequest
SFRestAPI
SFRestAPI is the entry point for making REST requests, and is generally accessed as a singleton, via SFRestAPI
sharedInstance.
You can easily create many standard canned queries from this object, such as:
objectId:contactId
fields:updatedFields];
115
Reference Android Architecture
SFRestAPI (Blocks)
This is a category extension of the SFRestAPI class that allows you to specify blocks as your callback mechanism. For example:
SFRestRequest
In addition to the canned REST requests provided by SFRestAPI, you can also create your own:
Other Objects
Though you won't likely leverage these objects directly, their purpose in the SDK is worth noting.
• RKRequestDelegateWrapper—The intermediary between SFRestAPI and the RestKit libraries.
RKRequestDelegateWrapper wraps the functionality of RestKit communications, providing convenience methods
for determining the type of HTTP post, handling data transformations, and interpreting responses.
• SFSessionRefresher—Tightly-coupled with SFRestAPI, providing an abstraction around functionality for automatically
refreshing a session if any REST requests fail due to session expiration.
Android Architecture
The SalesforceSDK is provided as a JAR file of java classes that works in conjunction with a set of libraries and resource files
in the native/SalesforceSDK directory.
Java Code
Java sources are under /src.
116
Reference Android Architecture
Libraries
Libraries are under /libs.
Resources
Resources are under /res.
File Use
edit_icon.png Server picker screen
glare.png Login screen
icon.png Application icon
117
Reference Android Architecture
118
Reference Java Code
Java Code
Java sources are under /src.
Java Code
com.salesforce.androidsdk.app
Class Description
ForceApp Abstract subclass of application; you must supply a concrete subclass in your
project.
com.salesforce.androidsdk.auth
Class Description
AuthenticatorService Service taking care of authentication
HttpAccess Generic HTTP access layer
119
Reference Java Code
Class Description
OAuth2 Helper class for common OAuth2 requests
com.salesforce.androidsdk.phonegap
Class Description
SalesforceOAuthPlugin PhoneGap plugin for Salesforce OAuth
SmartStorePlugin PhoneGap plugin for SmartStore
TestRunnerPlugin PhoneGap plugin to run javascript tests in container
com.salesforce.androidsdk.rest
Class Description
ClientManager Factory of RestClient, kicks off login flow if needed
RestClient Authenticated client to talk to a Force.com server
RestRequest Force.com REST request wrapper
RestResponse REST response wrapper
com.salesforce.androidsdk.security
Class Description
Encryptor Helper class for encryption/decryption/hash computations
PasscodeManager Inactivity timeout manager, kicks off passcode screen if needed
com.salesforce.androidsdk.store
Class Description
Database Encrypted/regular sqlite database wrapper
DBOpenHelper Helper class to manage regular database creation and version management
DBOperations DBOpenHelper/EncryptedDBOpenHelper wrapper
com.salesforce.androidsdk.ui
Class Description
CustomServerUrlEditor Custom dialog allowing user to pick a different login host
120
Reference Libraries
Class Description
LoginActivity Login screen
OAuthWebviewHelper Helper class to manage a WebView instance that is going
through the OAuth login process
PasscodeActivity Passcode (PIN) screen
SalesforceDroidGapActivity Main activity for hybrid applications
SalesforceGapViewClient WebView client used in hybrid applications
SalesforceR Class that allows references to resources defined outside the SDK
ServerPickerActivity Choose login host screen
com.salesforce.androidsdk.util
Class Description
EventsObservable Used to register and receive events generated by the SDK
(used primarily in tests)
EventsObserver Observer of SDK events
UriFragmentParser Helper class for parsing URI's query strings
Libraries
Libraries are under /libs.
Resources
Resources are under /res.
121
Reference Resources
drawable-hdpi, drawable-ldpi
File Use
edit_icon.png Server picker screen
glare.png Login screen
icon.png Application icon
drawable
File Use
header_bg.png Login screen
progress_spinner.xml Login screen
toolbar_background.xml Login screen
drawable-xlarge, drawable-xlarge-port
File Use
header_bg.png Login screen (tablet)
header_drop_shadow.xml Login screen (tablet)
header_left_border.xml Login screen (tablet)
header_refresh.png Login screen (tablet)
header_refresh_press.png Login screen (tablet)
header_refresh_states.xml Login screen (tablet)
header_right_border.xml Login screen (tablet)
login_content_header.xml Login screen (tablet)
nav_shadow.png Login screen (tablet)
oauth_background.png Login screen (tablet)
oauth_container_dropshadow.9.png Login screen (tablet)
oauth_background.png Login screen (tablet)
progress_spinner.xml Login screen (tablet)
refresh_loader.png Login screen (tablet)
toolbar_background.xml Login screen (tablet)
layout
File Use
custom_server_url.xml Server picker screen
122
Reference Resources
File Use
login.xml Login screen
passcode.xml Pin screen
server_picker.xml Server picker screen
layout-xlarge
File Use
login_header.xml Login screen (tablet)
login.xml Login screen (tablet)
server_picker_header.xml Server picker screen (tablet)
server_picker.xml Server picker screen (tablet)
menu
File Use
clear_custom_url.xml Add connection dialog
login.xml Login menu (phone)
values
File Use
sdk.xml Localized strings for login, server picker, and pin screens
strings.xml Other strings (app name)
values-xlarge
File Use
styles.xml Styles (tablet)
xml
File Use
authenticator.xml Preferences for account used by application
plugins.xml Plugin configuration file for PhoneGap. Required for hybrid.
123
Glossary
A
Access Token
A value used by the consumer to gain access to protected resources on behalf of the user, instead of using the user’s
Salesforce credentials. The access token is a session ID, and can be used directly.
Account
An account is an organization, company, or consumer that you want to track—for example, a customer, partner, or
competitor.
Apex
Apex is a strongly typed, object-oriented programming language that allows developers to execute flow and transaction
control statements on the Force.com platform server in conjunction with calls to the Force.com API. Using syntax that
looks like Java and acts like database stored procedures, Apex enables developers to add business logic to most system
events, including button clicks, related record updates, and Visualforce pages. Apex code can be initiated by Web service
requests and from triggers on objects.
Apex Controller
See Controller, Visualforce.
App
Short for “application.” A collection of components such as tabs, reports, dashboards, and Visualforce pages that address
a specific business need. Salesforce provides standard apps such as Sales and Call Center. You can customize the standard
apps to match the way you work. In addition, you can package an app and upload it to the AppExchange along with
related components such as custom fields, custom tabs, and custom objects. Then, you can make the app available to other
Salesforce users from the AppExchange.
AppExchange
The AppExchange is a sharing interface from salesforce.com that allows you to browse and share apps and services for
the Force.com platform.
AppExchange Listing
An AppExchange listing is a description of your app or service on the AppExchange. It is your primary marketing tool
for promoting your app or service to the AppExchange community.
124
Glossary
AppExchange Upgrades
Upgrading an app is the process of installing a newer version.
Authorization Code
A short-lived token that represents the access granted by the end user. The authorization code is used to obtain an access
token and a refresh token.
C
Chatter Feed
A list of recent activities in Salesforce. Chatter feeds display:
• On the Chatter or Home tab, where you can see your posts, posts from people you follow, and updates to records you
follow, and posts to groups you're a member of
• On profiles, where you can see posts made by the person whose profile you're viewing
• On records, where you can see updates to the record you're viewing
• On Chatter groups, where you can see posts to the group you're viewing
Chatter Mobile
A free mobile application that lets you collaborate in Chatter from your mobile device. Use Chatter Mobile to post and
comment in Chatter, and receive updates about the people, records, and files you follow and your groups.
Child Relationship
A relationship that has been defined on an sObject that references another sObject as the “one” side of a one-to-many
relationship. For example, contacts, opportunities, and tasks have child relationships with accounts.
See also sObject.
Class, Apex
A template or blueprint from which Apex objects are created. Classes consist of other classes, user-defined methods,
variables, exception types, and static initialization code. In most cases, Apex classes are modeled on their counterparts in
Java.
Client App
An app that runs outside the Salesforce user interface and uses only the Force.com API or Bulk API. It typically runs on
a desktop or mobile device. These apps treat the platform as a data source, using the development model of whatever tool
and platform for which they are designed.
125
Glossary
Cloud Computing
A model for software development and distribution based on the Internet. The technology infrastructure for a service,
including data, is hosted on the Internet. This allows consumers to develop and use services with browsers or other thin
clients instead of investing in hardware, software, or maintenance.
Component, Visualforce
Something that can be added to a Visualforce page with a set of tags, for example, <apex:detail>. Visualforce includes
a number of standard components, or you can create your own custom components.
Consumer Key
A value used by the consumer to identify itself to Salesforce. Referred to as client_id.
Controller, Visualforce
An Apex class that provides a Visualforce page with the data and business logic it needs to run. Visualforce pages can use
the standard controllers that come by default with every standard or custom object, or they can use custom controllers.
Custom Field
A field that can be added in addition to the standard fields to customize Salesforce for your organization’s needs.
Custom Object
Custom records that allow you to store information unique to your organization.
D
Database
An organized collection of information. The underlying architecture of the Force.com platform includes a database where
your data is stored.
Dependent Field
Any custom picklist or multi-select picklist field that displays available values based on the value selected in its corresponding
controlling field.
Developer Edition
A free, fully-functional Salesforce organization designed for developers to extend, integrate, and develop with the Force.com
platform. Developer Edition accounts are available on developer.force.com.
Developer Force
The Developer Force website at developer.force.com provides a full range of resources for platform developers, including
sample code, toolkits, an online developer community, and the ability to obtain limited Force.com platform environments.
Development Environment
A Salesforce organization where you can make configuration changes that will not affect users on the production
organization. There are two kinds of development environments, sandboxes and Developer Edition organizations.
126
Glossary
E
Enterprise Edition
A Salesforce edition designed for larger, more complex businesses.
Enterprise WSDL
A strongly-typed WSDL for customers who want to build an integration with their Salesforce organization only, or for
partners who are using tools like Tibco or webMethods to build integrations that require strong typecasting. The downside
of the Enterprise WSDL is that it only works with the schema of a single Salesforce organization because it is bound to
all of the unique objects and fields that exist in that organization's data model.
F
Feed Attachment, Chatter
A feed attachment is a file or link that is attached to a post in a Chatter feed.
Field
A part of an object that holds a specific piece of information, such as a text or currency value.
Field Dependency
A filter that allows you to change the contents of a picklist based on the value of another field.
Field-Level Security
Settings that determine whether fields are hidden, visible, read only, or editable for users. Available in Enterprise, Unlimited,
and Developer Editions only.
Field Sets
A field set is a grouping of fields. For example, you could have a field set that contains fields describing a user's first name,
middle name, last name, and business title. Field sets can be referenced on Visualforce pages dynamically. If the page is
added to a managed package, administrators can add, remove, or reorder fields in a field set to modify the fields presented
on the Visualforce page without modifying any code.
Force.com
The salesforce.com platform for building applications in the cloud. Force.com combines a powerful user interface, operating
system, and database to allow you to customize and deploy applications in the cloud for your entire enterprise.
Force.com IDE
An Eclipse plug-in that allows developers to manage, author, debug and deploy Force.com applications in the Eclipse
development environment.
127
Glossary
G
Group
A groups is a set of users. Groups can contain individual users, other groups, or the users in a role. Groups can be used to
help define sharing access to data or to specify which data to synchronize when using Connect for Outlook or Connect
for Lotus Notes.
Users can define their own personal groups. Administrators can create public groups for use by everyone in the organization.
Group Edition
A product designed for small businesses and workgroups with a limited number of users.
I
Import Wizard
A tool for importing data into your Salesforce organization, accessible from Setup.
Instance
The cluster of software and hardware represented as a single logical server that hosts an organization's data and runs their
applications. The Force.com platform runs on multiple instances, but data for any single organization is always consolidated
on a single instance.
Integration User
A Salesforce user defined solely for client apps or integrations. Also referred to as the logged-in user in a SOAP API
context.
M
Managed Package
A collection of application components that is posted as a unit on the AppExchange and associated with a namespace and
possibly a License Management Organization. To support upgrades, a package must be managed. An organization can
create a single managed package that can be downloaded and installed by many different organizations. Managed packages
differ from unmanaged packages by having some locked components, allowing the managed package to be upgraded later.
Unmanaged packages do not include locked components and cannot be upgraded. In addition, managed packages obfuscate
certain components (like Apex) on subscribing organizations to protect the intellectual property of the developer.
Metadata
Information about the structure, appearance, and functionality of an organization and any of its parts. Force.com uses
XML to describe metadata.
Metadata-Driven Development
An app development model that allows apps to be defined as declarative “blueprints,” with no code required. Apps built
on the platform—their data models, objects, forms, workflows, and more—are defined by metadata.
Metadata WSDL
A WSDL for users who want to use the Force.com Metadata API calls.
128
Glossary
MVC (Model-View-Controller)
A design paradigm that deconstructs applications into components that represent data (the model), ways of displaying
that data in a user interface (the view), and ways of manipulating that data with business logic (the controller).
N
Namespace
In a packaging context, a one- to 15-character alphanumeric identifier that distinguishes your package and its contents
from packages of other developers onAppExchange, similar to a domain name. Salesforce automatically prepends your
namespace prefix, followed by two underscores (“__”), to all unique component names in your Salesforce organization.
O
Object
An object allows you to store information in your Salesforce organization. The object is the overall definition of the type
of information you are storing. For example, the case object allow you to store information regarding customer inquiries.
For each object, your organization will have multiple records that store the information about specific instances of that
type of data. For example, you might have a case record to store the information about Joe Smith's training inquiry and
another case record to store the information about Mary Johnson's configuration issue.
Organization
A deployment of Salesforce with a defined set of licensed users. An organization is the virtual space provided to an
individual customer of salesforce.com. Your organization includes all of your data and applications, and is separate from
all other organizations.
Organization-Wide Defaults
Settings that allow you to specify the baseline level of data access that a user has in your organization. For example, you
can set organization-wide defaults so that any user can see any record of a particular object that is enabled via their object
permissions, but they need extra permissions to edit one.
P
Package
A group of Force.com components and applications that are made available to other organizations through the
AppExchange. You use packages to bundle an app along with any related components so that you can upload them to
AppExchange together.
Permission
A permission is a setting that allows a user to perform certain functions in Salesforce. Permissions can be enabled in
permission sets and profiles. Examples of permissions include the “Edit” permission on a custom object and the “Modify
All Data” permission.
Permission Set
A collection of permissions and settings that gives users access to specific tools and functions.
Production Organization
A Salesforce organization that has live users accessing data.
Profile
Defines a user’s permission to perform different functions within Salesforce. For example, the Solution Manager profile
gives a user access to create, edit, and delete solutions.
129
Glossary
R
Record
A single instance of a Salesforce object. For example, “John Jones” might be the name of a contact record.
Record-Level Security
A method of controlling data in which you can allow a particular user to view and edit an object, but then restrict the
records that the user is allowed to see.
Refresh Token
A token used by the consumer to obtain a new access token, without having the end user approve the access again.
REST API
REST is a simple, lightweight API that uses HTTP GET, POST and PUT methods to update resources on the server.
S
IdeaExchange
A forum where salesforce.com customers can suggest new product concepts, promote favorite enhancements, interact
with product managers and other customers, and preview what salesforce.com is planning to deliver in future releases.
Visit IdeaExchange at ideas.salesforce.com.
Sandbox Organization
A nearly identical copy of a Salesforce production organization. You can create multiple sandboxes in separate environments
for a variety of purposes, such as testing and training, without compromising the data and applications in your production
environment.
Session ID
An authentication token that is returned when a user successfully logs in to Salesforce. The Session ID prevents a user
from having to log in again every time he or she wants to perform another action in Salesforce. Different from a record
ID or Salesforce ID, which are terms for the unique ID of a Salesforce record.
Session Timeout
The period of time after login before a user is automatically logged out. Sessions expire automatically after a predetermined
length of inactivity, which can be configured in Salesforce by clicking Your Name > Setup > Security Controls. The
default is 120 minutes (two hours). The inactivity timer is reset to zero if a user takes an action in the Web interface or
makes an API call.
Setup
An administration area where you can customize and define Force.com applications. Access Setup through the Your
Name > Setup link at the top of Salesforce pages.
Sharing
Allowing other users to view or edit information you own. There are different ways to share data:
• Sharing Model—defines the default organization-wide access levels that users have to each other’s information and
whether to use the hierarchies when determining access to data.
130
Glossary
• Role Hierarchy—defines different levels of users such that users at higher levels can view and edit information owned
by or shared with users beneath them in the role hierarchy, regardless of the organization-wide sharing model settings.
• Sharing Rules—allow an administrator to specify that all information created by users within a given group or role is
automatically shared to the members of another group or role.
• Manual Sharing—allows individual users to share records with other users or groups.
• Apex-Managed Sharing—enables developers to programmatically manipulate sharing to support their application’s
behavior. See Apex-Managed Sharing.
Sharing Model
Behavior defined by your administrator that determines default access by users to different types of records.
Standard Object
A built-in object included with the Force.com platform. You can also build custom objects to store information that is
unique to your app.
System Log
Part of the Developer Console, a separate window console that can be used for debugging code snippets. Enter the code
you want to test at the bottom of the window and click Execute. The body of the System Log displays system resource
information, such as how long a line took to execute or how many database calls were made. If the code did not run to
completion, the console also displays debugging information.
T
Test Method
An Apex class method that verifies whether a particular piece of code is working properly. Test methods take no arguments,
commit no data to the database, and can be executed by the runTests() system method either through the command
line or in an Apex IDE, such as the Force.com IDE.
Translation Workbench
The Translation Workbench lets you specify languages you want to translate, assign translators to languages, create
translations for customizations you’ve made to your Salesforce organization, and override labels and translations from
managed packages. Everything from custom picklist values to custom fields can be translated so your global users can use
all of Salesforce in their language.
Trigger
A piece of Apex that executes before or after records of a particular type are inserted, updated, or deleted from the database.
Every trigger runs with a set of context variables that provide access to the records that caused the trigger to fire, and all
triggers run in bulk mode—that is, they process several records at once, rather than just one record at a time.
131
Glossary
U
Unit Test
A unit is the smallest testable part of an application, usually a method. A unit test operates on that piece of code to make
sure it works correctly. See also Test Method.
Unlimited Edition
Unlimited Edition is salesforce.com's flagship solution for maximizing CRM success and extending that success across
the entire enterprise through the Force.com platform.
Unmanaged Package
A package that cannot be upgraded or controlled by its developer.
V
Visualforce
A simple, tag-based markup language that allows developers to easily define custom pages and components for apps built
on the platform. Each tag corresponds to a coarse or fine-grained component, such as a section of a page, a related list,
or a field. The components can either be controlled by the same logic that is used in standard Salesforce pages, or developers
can associate their own logic with a controller written in Apex.
W
Web Service
A mechanism by which two applications can easily exchange data over the Internet, even if they run on different platforms,
are written in different languages, or are geographically remote from each other.
WebService Method
An Apex class method or variable that can be used by external systems, like a mash-up with a third-party application.
Web service methods must be defined in a global class.
X
XML (Extensible Markup Language)
A markup language that enables the sharing and transportation of structured data. All Force.com components that are
retrieved or deployed through the Metadata API are represented by XML definitions.
132
Index
Index
A Create Visualforce tablet page 57
creating a Connected App 78
About 4 Creating Visualforce components 59
access control in Connected Apps 82 Cross-device strategy 9
administrator tasks for Connected Apps 82
Advanced topics 95
Android architecture 116, 119, 121
D
Android development 29, 32 Database.com 13
Android hybrid project 36 Delete soups 88, 90, 92
Android hybrid sample app 50 deleting a Connected App 81
Android NFC 103 Describe global 114
Android project 31 Detail component 53, 55
Android requirements 13, 30 Detail page 42
Android sample 50 Developer Edition 13
Android sample app 31–32 developer tasks for Connected Apps 78
Ant version 35 Developer.force.com 13
API, social 44 Developing HTML apps 16
App component 53–54 Developing HTML5 apps 17
AppExchange 108–111 Development 13
Apple Safari 14 Development environments 13
Architecture of mobile Visualforce 53 Development requirements, Android 30
Architecture, Android 116, 119, 121 Development scenarios 7
Audience 4 Development, Android 29, 32
Authentication 68 Development, hybrid 34
Authentication flow 69 Device access 95
Authorization 84 Device camera 96
Distributing apps 108
B Dreamforce app 3
C F
Caching data offline 86 Feed 44
Callback URL 75 Feedback 5
callback URL in Connected Apps 79 Firefox browser 14
Camera 96 Flow 69–70
Chapter organization 4 Footer component 53–55
Chatter 44 Force.com 13
Chrome browser 14 Force.com for Touch 2
Client-side detection 9
Collaboration 44
Comments and suggestions 5
G
Comparison of development scenarios 7 Geolocation 2, 102
Comparison of mobile and PC 1 Getting started 14
Connected apps 68, 77–78 GitHub 5
Consumer key 75 Google Chrome 14
Consumer secret 75
contact information for Connected Apps 79
Container 34
H
Content component 53–55 Header component 53–55 133
Coordinates 102 HTML5 16–17, 20, 23
Index
HTML5 development 7, 9, 14, 95 Mobile Development 26
Hybrid development 7, 9, 14, 34–36, 39, 42, 95–96 Mobile inventory app 39, 42
Hybrid iOS sample 49 Mobile policies 77–78
Hybrid offline development 87 Mobile policy 2
Hybrid project for Android 36 Mobile SDK 2
Hybrid project for iOS 35 Mobile SDK installation 26, 30
Hybrid quick start 35 Mobile SDK Repository 5
Hybrid requirements 35 Mobile SDK Workbook 14
Hybrid sample app 37 MobileComponents.git 56–57
Hybrid Visualforce development 52–53, 56–57, 59 Mock SmartStore 87
Mozilla Firefox 14
I
N
Identity services 2
Identity URLs 71 Native development 7, 9, 14, 95
installing a Connected App 82 Native iOS application 26–27
Installing the SDK 26, 30 Native iOS architecture 26, 30, 115
Installing Visualforce components 56 Native iOS development 25
integrating Connected Apps with mobile apps 80 Native iOS project template 27
integrating Connected Apps with Salesforce 79 Navigation component 54
Internet Explorer 14 Navigation Component 53
Inventory 39, 42 Near-field communication 103
iOS application, creating 26–27 New features 5
iOS architecture 26, 30, 115 NFC 103
iOS development 25
iOS hybrid project 35 O
iOS Hybrid sample app 49
iOS requirements 13 OAuth 69–70
iOS sample app 27–28 OAuth tokens, revoking 75
iOS Xcode template 27 OAuth2 68–69
IP ranges 77–78 Offline storage 86–87
IP ranges with Connected Apps 80 Online documentation 4
IP restrictions for Connected Apps 82 Open mobile components 52–53
ISV 110–111 Organization of this guide 4
J P
JavaScript 17, 20, 23, 34 Page component 53–54
Parameters, scope 70
L Partner Program 110–111
Password 114
List component 53, 55 PIN protection 84
List objects 114 Preface 1
List page 39 Prerequisites 13
List resources 114 Printed date 5
Local storage 87 Project, Android 31
localStorage 94 publishing Connected Apps 80
Location 102
Location services 2 Q
logo images in Connected Apps 79
QR scanning 100
M Query 114
Querying a soup 88, 90, 92
managing a Connected App 82 querySpec 88, 90, 92
Message boards 5 Quick start 14
Metadata 114 Quick start, hybrid 35
Mobile components for Visualforce 52–53, 56–57, 59
Mobile Conatiner 2 R
Mobile container 34
Mobile Container 26 Reference documentation 113
134
Mobile development 6 Refresh token flow 70
Index
registerSoup 88, 90, 92 Storing files 87
Release notes 5 Supported browsers 14
Releases 5
Remote access 68 T
Remote access application 75
Requirements, hybrid 35 Tablet page in Visualforce 57
Responsive design 3, 9 Tokens, revoking 75
REST 114
REST Resources 114 U
RestAPIExplorer 28
Restricting user access 77–78 uninstalling a Connected App 85
Revoking tokens 75 updating a Connected App 81
upgrading a Connected App 85
S upsertSoupEntries 88, 90, 92
URLs, indentity 71
Safari browser 14 User-agent flow 69
Salesforce Mobile Services 2, 6
Sample app, Android 31–32 V
Sample app, iOS 28
Sample hybrid app 37 Version 114
Sample iOS app 27 versioning a Connected App 81
Scanning 100 Versions 5
Scope parameters 70 Visualforce 52–53
SDK prerequisites 13 Visualforce App component 54
Search 114 Visualforce archtiecture 53
Secure storage 86 Visualforce components 52–53
Security 68 Visualforce Content component 55
Security review 111 Visualforce Detail component 55
Security, PIN 84 Visualforce Footer component 55
Send feedback 5 Visualforce Header component 55
Server-side detection 9 Visualforce List component 55
Sign up 13 Visualforce Navigation component 54
SmartStore 86–87 Visualforce Page component 54
SmartStore extensions 87, 94 Visualforce SplitView template 54
SmartStore functions 88, 90, 92
SObject information 114 W
Social API 44
Social collaboration 44 Warehouse schema 39, 42
Soups 88, 90, 92 What’s new in this release 5
Source code 5 whitelisting IP ranges in Connected Apps 80
specifying basic information for Connected Apps 79 Workbook, Mobile SDK 14
SplitView template 54
SplitView Template 53 X
start URL in Connected Apps 82
Store 108–109 Xcode project 26–27
storing files 94 Xcode project template 27
135