SlideShare ist ein Scribd-Unternehmen logo
1 von 20
Downloaden Sie, um offline zu lesen
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
Challenges
Lies, 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
Tools
Time 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 dylibs
app.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
# RestKit
app.vendor_project "vendor/RestKit",
:static,
:headers_dir => "RestKit"
# Salesforce Common Utils
app.vendor_project "vendor/SalesforceCommonUtils",
:static,
:headers_dir => "Headers/SalesforceCommonUtils"
Enter the RakeFile: When good vendors go bad
# Salesforce Native SDK
app.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"
}
end
end
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 & A
Where 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*.

Weitere ähnliche Inhalte

Was ist angesagt?

Testing Native iOS Apps with Appium
Testing Native iOS Apps with AppiumTesting Native iOS Apps with Appium
Testing Native iOS Apps with Appium
Sauce Labs
 
Best Practices in apps development with Titanium Appcelerator
Best Practices in apps development with Titanium Appcelerator Best Practices in apps development with Titanium Appcelerator
Best Practices in apps development with Titanium Appcelerator
Alessio Ricco
 

Was ist angesagt? (20)

Agility Requires Safety
Agility Requires SafetyAgility Requires Safety
Agility Requires Safety
 
Selenium, Appium, and Robots!
Selenium, Appium, and Robots!Selenium, Appium, and Robots!
Selenium, Appium, and Robots!
 
selenium-2-mobile-web-testing
selenium-2-mobile-web-testingselenium-2-mobile-web-testing
selenium-2-mobile-web-testing
 
Calabash Andoird + Calabash iOS
Calabash Andoird + Calabash iOSCalabash Andoird + Calabash iOS
Calabash Andoird + Calabash iOS
 
Intro to Silex
Intro to SilexIntro to Silex
Intro to Silex
 
Testing Native iOS Apps with Appium
Testing Native iOS Apps with AppiumTesting Native iOS Apps with Appium
Testing Native iOS Apps with Appium
 
The Power of a Great API
The Power of a Great APIThe Power of a Great API
The Power of a Great API
 
Titanium appcelerator best practices
Titanium appcelerator best practicesTitanium appcelerator best practices
Titanium appcelerator best practices
 
Building Rich Applications with Appcelerator
Building Rich Applications with AppceleratorBuilding Rich Applications with Appcelerator
Building Rich Applications with Appcelerator
 
Travis and fastlane
Travis and fastlaneTravis and fastlane
Travis and fastlane
 
Best Practices in apps development with Titanium Appcelerator
Best Practices in apps development with Titanium Appcelerator Best Practices in apps development with Titanium Appcelerator
Best Practices in apps development with Titanium Appcelerator
 
E2E testing Single Page Apps and APIs with Cucumber.js and Puppeteer
E2E testing Single Page Apps and APIs with Cucumber.js and PuppeteerE2E testing Single Page Apps and APIs with Cucumber.js and Puppeteer
E2E testing Single Page Apps and APIs with Cucumber.js and Puppeteer
 
YAPC::NA 2007 - Epic Perl Coding
YAPC::NA 2007 - Epic Perl CodingYAPC::NA 2007 - Epic Perl Coding
YAPC::NA 2007 - Epic Perl Coding
 
End to end testing Single Page Apps & APIs with Cucumber.js and Puppeteer (Em...
End to end testing Single Page Apps & APIs with Cucumber.js and Puppeteer (Em...End to end testing Single Page Apps & APIs with Cucumber.js and Puppeteer (Em...
End to end testing Single Page Apps & APIs with Cucumber.js and Puppeteer (Em...
 
Joomla! Day Chicago 2011 Presentation - Steven Pignataro
Joomla! Day Chicago 2011 Presentation - Steven PignataroJoomla! Day Chicago 2011 Presentation - Steven Pignataro
Joomla! Day Chicago 2011 Presentation - Steven Pignataro
 
Rick Blalock: Your Apps are Leaking - Controlling Memory Leaks
Rick Blalock: Your Apps are Leaking - Controlling Memory LeaksRick Blalock: Your Apps are Leaking - Controlling Memory Leaks
Rick Blalock: Your Apps are Leaking - Controlling Memory Leaks
 
Titanium - Making the most of your single thread
Titanium - Making the most of your single threadTitanium - Making the most of your single thread
Titanium - Making the most of your single thread
 
Put an end to regression with codeception testing
Put an end to regression with codeception testingPut an end to regression with codeception testing
Put an end to regression with codeception testing
 
Jasmine with JS-Test-Driver
Jasmine with JS-Test-DriverJasmine with JS-Test-Driver
Jasmine with JS-Test-Driver
 
Composer at Scale, Release and Dependency Management
Composer at Scale, Release and Dependency ManagementComposer at Scale, Release and Dependency Management
Composer at Scale, Release and Dependency Management
 

Ähnlich wie Connecting with the enterprise - The how and why of connecting to Enterprise Software Systems with RubyMotion

Baruco 2014 - Rubymotion Workshop
Baruco 2014 - Rubymotion WorkshopBaruco 2014 - Rubymotion Workshop
Baruco 2014 - Rubymotion Workshop
Brian Sam-Bodden
 
Behavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWestBehavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWest
Joshua Warren
 
Appium mobile web+dev conference
Appium   mobile web+dev conferenceAppium   mobile web+dev conference
Appium mobile web+dev conference
Isaac Murchie
 

Ähnlich wie Connecting with the enterprise - The how and why of connecting to Enterprise Software Systems with RubyMotion (20)

Baruco 2014 - Rubymotion Workshop
Baruco 2014 - Rubymotion WorkshopBaruco 2014 - Rubymotion Workshop
Baruco 2014 - Rubymotion Workshop
 
Crossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkCrossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end Framework
 
Mobile App Feature Configuration and A/B Experiments
Mobile App Feature Configuration and A/B ExperimentsMobile App Feature Configuration and A/B Experiments
Mobile App Feature Configuration and A/B Experiments
 
TorqueBox
TorqueBoxTorqueBox
TorqueBox
 
Javaland 2017: "You´ll do microservices now". Now what?
Javaland 2017: "You´ll do microservices now". Now what?Javaland 2017: "You´ll do microservices now". Now what?
Javaland 2017: "You´ll do microservices now". Now what?
 
Become a webdeveloper - AKAICamp Beginner #1
Become a webdeveloper - AKAICamp Beginner #1Become a webdeveloper - AKAICamp Beginner #1
Become a webdeveloper - AKAICamp Beginner #1
 
Behavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWestBehavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWest
 
Mobile Development integration tests
Mobile Development integration testsMobile Development integration tests
Mobile Development integration tests
 
Atmosphere Conference 2015: The 10 Myths of DevOps
Atmosphere Conference 2015: The 10 Myths of DevOpsAtmosphere Conference 2015: The 10 Myths of DevOps
Atmosphere Conference 2015: The 10 Myths of DevOps
 
Paris Web - Javascript as a programming language
Paris Web - Javascript as a programming languageParis Web - Javascript as a programming language
Paris Web - Javascript as a programming language
 
Cocoapods and Most common used library in Swift
Cocoapods and Most common used library in SwiftCocoapods and Most common used library in Swift
Cocoapods and Most common used library in Swift
 
I Love APIs - Oct 2015
I Love APIs - Oct 2015I Love APIs - Oct 2015
I Love APIs - Oct 2015
 
Appium mobile web+dev conference
Appium   mobile web+dev conferenceAppium   mobile web+dev conference
Appium mobile web+dev conference
 
Appium workship, Mobile Web+Dev Conference
Appium workship,  Mobile Web+Dev ConferenceAppium workship,  Mobile Web+Dev Conference
Appium workship, Mobile Web+Dev Conference
 
Testing Big in JavaScript
Testing Big in JavaScriptTesting Big in JavaScript
Testing Big in JavaScript
 
Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4
 
Practical WebAssembly with Apex, wasmRS, and nanobus
Practical WebAssembly with Apex, wasmRS, and nanobusPractical WebAssembly with Apex, wasmRS, and nanobus
Practical WebAssembly with Apex, wasmRS, and nanobus
 
"I have a framework idea" - Repeat less, share more.
"I have a framework idea" - Repeat less, share more."I have a framework idea" - Repeat less, share more.
"I have a framework idea" - Repeat less, share more.
 
Using Ruby in Android Development
Using Ruby in Android DevelopmentUsing Ruby in Android Development
Using Ruby in Android Development
 
Intro to Rails
Intro to RailsIntro to Rails
Intro to Rails
 

Mehr von Kevin Poorman (8)

10 Principles of Apex Testing
10 Principles of Apex Testing10 Principles of Apex Testing
10 Principles of Apex Testing
 
10 principles of apex testing
10 principles of apex testing10 principles of apex testing
10 principles of apex testing
 
Mac gyver df14 - final
Mac gyver   df14 - finalMac gyver   df14 - final
Mac gyver df14 - final
 
Ionic on visualforce and sf1 df14
Ionic on visualforce and sf1   df14Ionic on visualforce and sf1   df14
Ionic on visualforce and sf1 df14
 
Finding a good development partner
Finding a good development partnerFinding a good development partner
Finding a good development partner
 
Ci of js and apex using jasmine, phantom js and drone io df14
Ci of js and apex using jasmine, phantom js and drone io   df14Ci of js and apex using jasmine, phantom js and drone io   df14
Ci of js and apex using jasmine, phantom js and drone io df14
 
Apex for humans
Apex for humansApex for humans
Apex for humans
 
Apex 10 commandments df14
Apex 10 commandments df14Apex 10 commandments df14
Apex 10 commandments df14
 

Kürzlich hochgeladen

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Kürzlich hochgeladen (20)

Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 

Connecting with the enterprise - The how and why of connecting to Enterprise Software Systems with RubyMotion

  • 1. Connecting with the Enterprise The how and why of Enterprise integrations with RubyMotion
  • 2. 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
  • 3. 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
  • 4. Why Enterprise Software? Flappy birds versus Email. This is an interactive bit.
  • 5. Why Enterprise Software? so chart. much up and to the right. wow.
  • 6. Why Enterprise Software? Enterprise Software Stinks. Design is not simply art, it is the elegance of function. -- F. Porsche
  • 7. Challenges Lies, 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
  • 8. Tools Time for the how 1. Cocoapods — ZKsForce 2. Gems — AFMotion 3. Rakefile!
  • 9. An example with Enterprise CRM Software vendor Salesforce. Resetting passwords like a Boss. Talk is cheap, Show me the Code. — Linus Torvald
  • 10. 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
  • 11. 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 dylibs app.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"
  • 12. Enter the Rakefile: Vendor'd Projects # RestKit app.vendor_project "vendor/RestKit", :static, :headers_dir => "RestKit" # Salesforce Common Utils app.vendor_project "vendor/SalesforceCommonUtils", :static, :headers_dir => "Headers/SalesforceCommonUtils"
  • 13. Enter the RakeFile: When good vendors go bad # Salesforce Native SDK app.vendor_project "vendor/SalesforceNativeSDK", :static, :headers_dir => "include/SalesforceNativeSDK" Warning, a wall of boring, soulless, corporate code is coming.
  • 14. 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
  • 15. 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
  • 16. 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
  • 17. 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" } end end
  • 18. 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
  • 19. Q & A Where we A some Q's Comments? Snide Remarks?
  • 20. 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*.