Date post: | 08-May-2015 |
Category: |
Technology |
Upload: | kevin-poorman |
View: | 152 times |
Download: | 0 times |
Connecting with the Enterprise
The how and why of Enterprise integrations with RubyMotion
Who the heck is this guy?Kevin Poorman, Architect at West Monroe Partners
@codefriar -- Hey, I just met you, And this is crazy, But here's my twitter, So follow me, maybe!
Boring corporate bio here.-- West Monroe Partners.
#MyBabyDaughterTessa!, #Homebrew(beer), #Ruby, #AngularJS, #Iot, #Salesforce, #!Java, #!Eclipse, #FriendsDontLetFriendsUseEclipse #!boringCorporateness
Agenda
1. Why Enterprise software?
2. Challenges - We'll need a Young priest and an Old priest
3. Tools - We can do it!
4. A Salesforce Example
Why Enterprise Software?
Flappy birds versus Email.
This is an interactive bit.
Why Enterprise Software?so chart. much up and to the right. wow.
Why Enterprise Software?
Enterprise Software Stinks.
Design is not simply art, it is the elegance of function.-- F. Porsche
ChallengesLies, Damn Lies, and SDK's
1. Rest Apis Rest "ish" Apis, Soap Apis and SDKs
2. Authentication - Oauth or else
3. Data Integrity and Security
ToolsTime for the how
1. Cocoapods
— ZKsForce
2. Gems
— AFMotion
3. Rakefile!
An example with Enterprise CRM Software vendor Salesforce.
Resetting passwords like a Boss.
Talk is cheap, Show me the Code.
— Linus Torvald
Enter the Rakefile: Frameworks
### Application Frameworks# You can *add* to this as neccessary but this is the minimum required# for Salesforce iOS SDK Use.app.frameworks += %w(CFNetwork CoreData MobileCoreServices SystemConfiguration Security)app.frameworks += %w(MessageUI QuartzCore OpenGLES CoreGraphics sqlite3)
— How do you know which ones you need?
(lucky) ? Docs : Build Errors
Enter the Rakefile: Libraries
### Additional libraries needed for Salesforce iOS SDK# You can generally add just about any dylib or static .a lib this way# These are system dylibsapp.libs << "/usr/lib/libxml2.2.dylib"app.libs << "/usr/lib/libsqlite3.0.dylib"app.libs << "/usr/lib/libz.dylib"# These are provided by Salesforces' iOS SDK.app.libs << "vendor/openssl/libcrypto.a"app.libs << "vendor/openssl/libssl.a"# app.libs << "vendor/RestKit/libRestKit.a"# app.libs << "vendor/SalesforceCommonUtils/libSalesforceCommonUtils.a"# app.libs << "vendor/SalesforceNativeSDK/libSalesforceNativeSDK.a"# app.libs << "vendor/SalesforceOAuth/libSalesforceOAuth.a"app.libs << "vendor/sqlcipher/libsqlcipher.a"# app.libs << "vendor/SalesforceSDKCore/libSalesforceSDKCore.a"app.libs << "vendor/sqlcipher/libsqlcipher.a"
Enter the Rakefile: Vendor'd Projects
# RestKitapp.vendor_project "vendor/RestKit", :static, :headers_dir => "RestKit"
# Salesforce Common Utilsapp.vendor_project "vendor/SalesforceCommonUtils",:static,:headers_dir => "Headers/SalesforceCommonUtils"
Enter the RakeFile: When good vendors go bad
# Salesforce Native SDKapp.vendor_project "vendor/SalesforceNativeSDK",:static,:headers_dir => "include/SalesforceNativeSDK"
Warning, a wall of boring, soulless, corporate code is coming.
class AppDelegate
attr_accessor :window, :initialLoginSuccessBlock, :initialLoginFailureBlock
# def OAuthLoginDomain() # # You can manually override and force your app to use # # a sandbox by changing this to test.salesforce.com # "login.salesforce.com" # end
def RemoteAccessConsumerKey() # Specify your connected app's consumer key here "3MVG9A2kN3Bn17hsUZHiKXv6UUn36wtG7rPTlcsyH8K4jIUB2O2CU4dHNILQ_6lD_l9uDom7TjTSNEfRUE6PU" end
def OAuthRedirectURI() # This must match the redirect url specified in your # connected app settings. This is a fake url scheme # but for a mobile app, so long as it matches you're good. "testsfdc:///mobilesdk/detect/oauth/done" end
def dealloc() NSNotificationCenter.defaultCenter.removeObserver(self, name:"kSFUserLogoutNotification", object:SFAuthenticationManager.sharedManager) NSNotificationCenter.defaultCenter.removeObserver(self, name:"kSFLoginHostChangedNotification", object:SFAuthenticationManager.sharedManager) end
def application(application, didFinishLaunchingWithOptions:launchOptions) if self SFLogger.setLogLevel(SFLogLevelDebug) SFAccountManager.setClientId(RemoteAccessConsumerKey()) SFAccountManager.setRedirectUri(OAuthRedirectURI()) SFAccountManager.setScopes(NSSet.setWithObjects("api", nil)) NSNotificationCenter.defaultCenter.addObserver(self, selector: :logoutInitiated, name: "kSFUserLogoutNotification", object:SFAuthenticationManager.sharedManager) NSNotificationCenter.defaultCenter.addObserver(self, selector: :loginHostChanged, name: "kSFLoginHostChangedNotification", object:SFAuthenticationManager.sharedManager)
@weakSelf = WeakRef.new(self) self.initialLoginSuccessBlock = lambda { |info| @weakSelf.setupRootViewController }
self.initialLoginFailureBlock = lambda { |info,error| SFAuthenticationManager.sharedManager.logout }
end self.window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds) self.initializeAppViewState SFAuthenticationManager.sharedManager.loginWithCompletion(self.initialLoginSuccessBlock, failure:self.initialLoginFailureBlock) true end
def initializeAppViewState() @window.rootViewController = InitialViewController.alloc.initWithNibName(nil, bundle:nil) @window.makeKeyAndVisible end
def setupRootViewController() navVC = UINavigationController.alloc.initWithRootViewController(HomeScreen.new) @window.rootViewController = navVC end
def logoutInitiated(notification) self.log.SFLogLevelDebug(msg:"Logout Notification Recieved. Resetting App") self.initializeAppViewState SFAuthenticationManager.sharedManager.loginWithCompletion(self.initialLoginSuccessBlock, failure:self.initialLoginFailureBlock) end
def loginHostChanged(notification) self.log.SFLogLevelDebug(msg:"Login Host Changed Notification Recieved. Resetting App") self.initializeAppViewState SFAuthenticationManager.sharedManager.loginWithCompletion(self.initialLoginSuccessBlock, failure:self.initialLoginFailureBlock) end
end
And now for the actually useful bit in all that
def setupRootViewController() # Yeah, if you could just replace the root view controller with a ProMotion # Screen, that'd be great. navVC = UINavigationController.alloc.initWithRootViewController(HomeScreen.new) @window.rootViewController = navVC end
Using the SDK Functions
def query_sf_for_users results = SFRestAPI.sharedInstance.performSOQLQuery( # Salesforce has a fun variant on Sql called # "SOQL" or Salesforce Object Query Language. # First Argument is the Query we want to run. "SELECT id, Name, LastName FROM user", failBlock: lambda {|e| ap e }, # Method is a fun Method that invokes the named # method as a lambda. completeBlock: method(:sort_results) ) end
Using the SDK functions
def reset_password args UIAlertView.alert("Reset Users Password?", buttons: ["Cancel", "OK"], message: "Salesforce will reset their password!") { |button| if button == "OK" results = SFRestAPI.sharedInstance.requestPasswordResetForUser( @id, # id of user to invoke password reset. failBlock: lambda {|e| ap e }, completeBlock: method(:password_reset_complete) ) end }end
def password_reset_complete response if(Twitter.accounts.size > 0) UIAlertView.alert("Password Reset!", buttons: ["OK", "Tweet"]) { |button| tweet if button == "Tweet" } endend
ObjC2RubyMotion
Turns this:
RootViewController *rootVC = [[RootViewController alloc] initWithNibName:nil bundle:nil]; UINavigationController *navVC = [[UINavigationController alloc] initWithRootViewController:rootVC]; self.window.rootViewController = navVC;
Into this:
rootVC = RootViewController.alloc.initWithNibName(nil, bundle:nil) navVC = UINavigationController.alloc.initWithRootViewController(rootVC) self.window.rootViewController = navVC
Q & AWhere we A some Q's
Comments? Snide Remarks?
Thank You!
Everything should be as simple as possible, but no simpler.-- A. Einstein
Ps: Investigative reporters have discovered that RM 3.5, will include a third new Ruby Compiler -- for Windows and Windows Phone 8.1, this will, of course, be the only redeeming feature of Windows*.