Example RubyMotion Salesforce App

Today I released Mobile Admin Tools, a RubyMotion based Salesforce app allowing Admins to manage their Salesforce users on their iPhones. Mobile Admin Tools specifically allows Admins to:

  1. See a list of all users in their Org
  2. See a particular users’ login history
  3. See the detail of that users’ account such as mobile #
  4. Initiate a password reset (Salesforce will reset the password and email a new, temporary password to the users’ listed email)
  5. Deactivate or (re)Activate users
  6. Toggle various permissions such as Visualforce Developer mode

Additionally, the app gives admins the ability to tweet their experience after resetting a password with some suggested messages and hash tags like “Just reset another password with Mobile Admin Tools #atTheBar #whySFDCAdminsDrinkLess”

You can find the source code (it’s open source) and more details here: http://noeticpenguin.github.io/MobileAdminTools/

Developing Salesforce Mobile apps with RubyMotion

RubyMotion is a revolutionary new toolchain for native iOS development from HipByte. Using RubyMotion developers can now write iOS apps in Ruby, rather than Objective-C. RubyMotion statically compiles the ruby code to run on the Objective-C runtime. Because of this, RubyMotion apps have full access to all the public API’s, and Frameworks available to traditional Objective-C developers. This includes not only the basic UIKit framework for application development but also hardware specific bits like coreLocation.  Additionally, The wealth of open source control and libraries available through Cocoapods are fully available to RubyMotion developers.

SalesForce provides iOS mobile developers a rich SDK that handles Authentication (via Oauth2), query building and execution and json deserialization, amongst many other things. Developers eager to get started can find the SDK here: Salesforce Mobile SDK (iOS)

Ideally all third-party libraries, frameworks and sdk’s would be available as cocoa pods; however the Salesforce SDK consists of multiple individual libraries and is not available as a cocoapd (yet, see this issue)

Instead, the various pieces and parts of the SDK must be incorporated into your rubymotion project via the rakefile’s vendor and libs directives.
Here is an annotated rakefile detail the what, how and why of incorporating the Salesforce Mobile SDK(iOS) into your RubyMotion project. With this rakefile as a starting point and guide, you can create apps that interact with Salesforce with Rubymotion!

Some Important notes:

  1. This rakefile assumes you have placed your salesforce sdk in: «ProjectRoot»/vendor/Salesforce
  2. Note how some of the Salesforce SDK pieces are included via the app.libs « directive. These are precompiled, distribution ready .a files that Salesforce provides.
  3. However, not all of the Salesforce SDK pieces can be utilized by RubyMotion when incorporated via app.libs. Specifically, any piece of the SDK your application will be directly calling must be compiled by RubyMotion. RubyMotion exposes Obj-c methods by generating a .bridgeSupport file. These files are generated from the .h header files included with the source. These pieces are incorporated via the app.vendor_project directive.
  4. Please note that RestKit, SalesforceOAuth, and SalesforceSDK must all be included via app.vendor_project. When including other vendor projects always be sure to include the :headers => hash element so that the bridgesupport file is created.

A note on translating example Objective-C code to RubyMotion specific to the Salesforce SDK.

The example code for querying the Salesforce RestAPI looks something like this:

[[SFRestAPI sharedInstance] performSOQLQuery:”QueryString” failBlock:^{stuff} completeBlock:^{Other stuff}]

This Objective-C code is translated to RubyMotion thusly:

SFRestAPI.sharedInstance.performSOQLQuery(“query string”, failBlock: lambda {|e| stuff }, completeBlock:lambda{|c| otherStuff} )

Note that RubyMotion is expecting Lambdas as the blocks for failBlock and completeBlock.

Protip: The Ruby method named “method” (i kid you not) operates as a lambda, thus you can say: completeBlock: method(:some_method_name) and when the completeBlock is run, it will execute your method. Very handy.