SlideShare a Scribd company logo
1 of 53
How We Built a Mobile Electronic Health Record App
Using Xamarin, Angular, and Web API
About Matt Spradley
• Sr. Product Manager at Aprima
• Co-founded 3 software companies
• Used to write code
• Tinkers every now and then
• linkedin.com/in/mattspradley
• mattspradley.com
• matt.spradley@gmail.com
• 214-403-6749
How Should we Build a Cross Platform Mobile
App?
http://imgs.xkcd.com/comics/efficiency.png
Requirements
• Tablet 90% functional parity with desktop
EHR
• Work on iOS and Android phones and
tablets
• Integrate with on-premise servers
• No control over network (DNS, Firewall, etc.)
• Multiple versions of REST API
Test (POC) Don’t Guess
…And the Results
Score 66 64 63 53
Factor Weight HTML/Steroids HTML/Titanium Native/Xamarin Native
UX 3 2 2 3 3
Code Reuse 3 3 3 2 1
Special UI 1 1 2 3 3
Control 1 2 2 3 3
Effort 3 3 2 2 1
Maintenance 3 2 2 3 2
Cloud Reuse 1 3 3 1 1
OS Integration 2 2 2 3 3
Deployment Options 1 3 3 1 1
Existing Dev Skills 1 2 2 3 1
Hiring 2 2 2 3 2
Vendor Stability 3 2 2 2 3
UTDesign Decision 1 2 2 1 1
UI Testability 3 3 3 1 1
Winner???
Web UI with Angular Is Easy
<ul id="appointments" class="list-group list-group-fixed-height“
collapse="tileState.isCollapsed">
<li class="list-group-item" ng-show="!loading && appointments.length == 0">
<div class="col-xs-12 text-center-vert text-center">
<span translate>No appointments</span>
</div>
</li>
<li ng-repeat="appt in appointments | orderBy:'date'"
data-transition-to="{ appRoute: 'patientDashboard',
opts: {id: appt.PatientId}}"
class="list-group-item"
ng-class="{'active': (!!appt.clicked)}">
<ap-appointment-list-item
data-appt="appt"
data-context-menu-id="appt-context-menu-{{$index}}">
</ap-appointment-list-item>
</li>
</ul>
<div class="panel-body panel-flush" collapse="tileState.isCollapsed"
ng-if="!loading && !httpError">
<table class="table table-striped ap-table">
<thead>
<tr>
<th translate>Name</th>
<th ng-repeat="column in vitals.Columns | limitTo:observationLimit">
<ap-date-formatter date="{{column.ObservationDateTime}}“
format="short-date"></ap-date-formatter>
</th>
</tr>
</thead>
<tbody>
<tr ng-show="vitalsExist" ng-repeat="observations in vitals.Rows |
filter:hasValueForColumns">
<td>{{observations.Name}}</td>
<td ng-repeat="observation in observations.Observations |
limitTo:observationLimit"
ng-class="{danger: !observation.IsInRange && observation.Value}"
class="vital-value">
{{observation.Value}}
</td>
</tr>
<tr ng-if="!vitalsExist">
<td>
<span id="no-vital-results" translate>
No known vitals.
</span>
</td>
</tr>
</tbody>
</table>
</div>
Web UI with Angular Is Easy, Really
Code and Build
• Web UI
• Code in HTML, Less, AngularJS
• Build
• Grunt
• Less
• Template process
• JsHint
• Uglify
• Unit Tests w/ Jasmine and Karma
• Deploy
• Translate
• Images to Less
Chocolate and Peanut Butter
Our Customers LOVE Aprima NOW
Go Native with Xamarin for Hard Stuff
• For
• Taking Pictures
• Image Annotation
• PDF Viewer
• Why
• Flexibility
• C#
• Performance
• Custom UI
• Look and Feel
• Services
• Hiring
Xamarin Forms
Demo
Aprima NOW Hybrid Architecture
Javascript/HTML JS <--> Xamarin(C#) Bridge Xamarin(C#)
AngularJS App JS Bridge
Common
(portable class
library)
Xamarin.Android
Xamarin.iOS
Fire Event
Subscribe
SubscribeHandle Events
Handle Events
Fire Event or Subscribe
Invoke Callback from Subscription
AppServer
Javascript Bridge
Angular Service,
Ctrl etc
iOS JS Bridge
Android JS
Bridge
WinForms JS
Bridge
Fire Events to C#.
Subscribe to Events from C#
iOS C# Bridge
Android C#
Bridge
WinForms C#
Bridge
XHR to app:// window.AndrApp.Event(eventData); window.external.HandleEvent(eventData)
C# Objects
Fire Events to JS
Subscribe to Events from JS
webview.EvaluateJavascript(jsToFireEvent); Webview.LoadUrl( javascript:{jsToFireEvent} );
Webview.Document.InvokeScript( eval , jsToFireEvent );
Handle events from C#
Handle events from JS
Jsbridge.js
• JS object provides bridging capabilities to JS code
• Fire events to C#
• Add event handlers in JS to be called when event is fired from C#
• Bridge implementations for iOS, Android, and WinForms
• Normalizes event structure for consistency:
app://{module}/fireEvent?data={jsEventDataJson}&_={random}
C# -> JS event Firing
• To fire an event, call the following. BridgeContext is a bridge which is scoped to the UI WebView
component (iOS: UIWebView; Android: WebView; WinForms: Form/Control/etc)
this.BridgeContext.FireEvent(eventName, data);
• Which calls the following within the BridgeContext instance and actually dispatches the event to
javascript. ExecuteScript is implemented differently by each platform.
ExecuteScript(string.Format("bridge.app._dispatchEvent('{0}', {1});",
eventName, json));
iOS Jsbridge.js
• To send an event from JS to C#, iOS uses a custom NSUrlProtocol implementation
which listens for XHR traffic on a custom protocol (“app://”).
• To send event from JS to C#, an XHR request is made to custom protocol with
event data in the url.
function (url) {
var x1 = new bridge.app.CustomXhr();
x1.onerror = function (e) {
console.log('XHR error:' + JSON.stringify(e));
};
x1.open('GET', url);
x1.send();
}
iOS C# Bridge
• Registers global NSUrlProtocol handler, takes an instance of
UIWebView and bind global events to specific UIWebViews.
• To send event from C# to JS, executes dynamically generated JS which
calls into jsbridge.js component.
public override void ExecuteScript(string javascript)
{
webView.BeginInvokeOnMainThread(() => _webView.EvaluateJavascript(javascript));
}
iOS JavaScript Bridge Demo
Android jsbridge.js
• To send an event from JS to C#, Android uses a Java object which is made
accessible as a JavaScript object by adding the object instance to the Webview as
a JavaScript Interface.
• To send event from JS to C#, a method on the Java object instance is invoked from
JavaScript.
function (url){
var result = window.AndrApp.Event(url);
result = JSON.parse(result);
if (!result.Success) {
console.log('Android bridge error: ' + JSON.stringify(result));
}
}
Android C# bridge
• Instantiates and adds java object with [Export] or [JavascriptInterface] members. Members are
accessible from javascript.
webView.AddJavascriptInterface(new JsBridgeExports(this), "AndrApp");
• To execute a script, it loads a url which contains javascript to be executed:
public override void ExecuteScript(string javascript)
{
activity.RunOnUiThread(() => _webView.LoadUrl(string.Format("javascript: {0}", javascript)));
}
WinForms jsbridge.js
• To send an event from JS to C#, WinForms uses a C# object which is made accessible as a
Javascript object by adding the object instance to the WebView as the ObjectForScripting.
• To send event from JS to C#, a method on the C# object instance is invoked from javascript.
function (url) {
var result = window.external.HandleEvent(url);
result = JSON.parse(result);
if (!result.Success) {
console.log('PRM bridge error: ' + JSON.stringify(result));
}
}
WinForms C# bridge
• Instantiates and adds C# object to the WebBrowser instance as the ObjectForScripting.
ObjectForScripting must be have[ComVisible(true)]
this._browser.ObjectForScripting = new JsBridgeWindowExternalHandler(this);
To fire event from C# to JS, eval function is invoked from C# with a IIFE (Immediately Invoked Function Expression)
public override void ExecuteScript(string javascript)
{
_browser.Invoke(new Action(() =>
{
if (_browser.Document != null)
{
var script = string.Format("(function() {{ {0}; }})();", javascript);
_browser.Document.InvokeScript("eval", new object[] { script });
}
}));
}
JS Code to fire and listen for events
angular.module('amodule').controller('SomeCtrl',
['$scope', 'Bridge', function ($scope, Bridge){
//fire event
Bridge.navigate('aRoute', { id : 0 });
//listen for event
Bridge.on('someEvent', function (data) {
$scope.data = data;
});
}]
);
C# code to fire and listen for events
//Fire Event
this.BridgeContext.FireEvent("navigate", new { id = 0});
//listen to event
this.BridgeContext.AddEventListener("someEvent", (SomeType data) =>
{
//do something with data
});
Notes
• Bridge lifetimes vary by platform.
• iOS has a singleton bridge because NSProtocolHandler is added for an entire
application instead of for a specific UIWebView. iOS bridge has logic to broker
events to the correct bridge context which isassociated with a specific
UIWebView.
• Android bridges are instantiated per WebView instances
• WinForms bridges are instantiated per WebBrowser instance
• Native components must tell JS bridge which native implementation
is used. This can happen AFTER events have already been fired from
JS. This required queuing of events until the bridge was finished being
setup.
Notes
• Majority of code is in a PCL library and reused by all platforms
• Dll exists for each platform that contains platform specific code
• Very little platform specific code
• Bridge behavior consistent across the platforms
Frontend Tech Stack
• Xamarin
• Angular
• Bootstrap
• lodash
• Less
• Hammer.JS
Testing
http://www.idyllic-software.com/blog/category/ruby-on-rails/page/5/
Web UI is Easy to Test and Debug
Grunt Jasmine Protractor Webdriver E2E
Device Testing with Xamarin Test Cloud
Xamarin Test Cloud
Testing [Test]
public void PinchToZoom()
{
LoginPage.Login(app);
app.WaitForElement(x => x.Css("#dashboard"));
app.Screenshot("Then I am logged in at my home screen");
app.GoToPatients();
QuicksearchPage.SearchForPatient(app, "Anderson");
QuicksearchPage.SelectPatient(app, "e2ab0790-f271-471a-bdc2-e6bca0889dad");
app.WaitForElement(x => x.Css("#patient-widgets"), "Timed out waiting for patient
dashboard to load", new TimeSpan(0, 0, 3));
app.Screenshot("Then I see Jeff's profile");
PatientDashboardPage.ExpandWidget(app, PatientDashboardWidget.ObservationResults);
PatientDashboardPage.TapObservationResult(app, "3f39a0fa-99e9-494b-a234-170f3ff824ba");
Thread.Sleep(5000);
app.Screenshot("Now I should see the images");
//Scroll down to view first image
app.ScrollDownEnough(x => x.WebView().Css(".image-viewer"));
var rect = app.Query(x => x.WebView().Css(".image-viewer"))[0].Rect;
app.Zoom(rect.CenterX, rect.CenterY, 100);
app.Screenshot("Now I zoom in on the image");
}
Not All Web Browsers are Equal
iOS and Android Webview Update Differences
Inertial Scroll or EasyScroller
• Safari: Fixed DIVs Bad
• https://github.com/zynga/scroller
Xamarin Issues
• Constant updates
• Things break
• Universal API kerfuffle
• IDE lockups
• They’re still awesome and smart
http://www.doomsteaddiner.net/blog/wp-content/uploads/2013/04/wheels-off-hummer.png
Backend
• Web API
• OWIN
• Azure Relay
• SQL Server
• Feature List for Versions
• NEO (home brew ORM)
REST
Facade
App
Server
UI 1
UI 2
DBEF
Other
Aprima Mobile Application Architecture
Decoupled deployment from Aprima Main
On-Premise Server
Azure Relay WebHttpBinding
A Developer’s Guide to Service Bus in Windows Azure Platform
Service Bus Relay Web API Host
https://pfelix.wordpress.com/tag/asp-net-web-api/
Relay Demo
• By pass on-premise issues
• … and pesky IT road blocks
http://imgs.xkcd.com/comics/security.png
Azure Relay Performance
-100
0
100
200
300
400
500
600
700
800
Azure Ping1
(ms)
Relay Ping1
(ms)
Azure Ping2
(m2)
Relay Ping2
(m2)
Azure 5K (ms) Relay 5K (ms) Azure 10k
(ms)
Relay 10k
(ms)
Azure 50K
(ms)
Relay 50K
(ms)
Azure 500K
(ms)
Relay 500K
(ms)Average
Code Metrics
• Backend ≈ 50K lines
• 87% C#
• 10% Build scripts
• 3% Other
• Frontend ≈ 100K lines
• 59% JavaScript
• 30% HTML (HTML, CSS, Less)
• 8% C# (90% in common PCL)
• 3% Build scripts
It Works
Thanks to a Great Team
• Mobile Team
• Ryan Cady
• Kenneth Crawford
• Mike Duran
• Jeff Lott
• Contributors
• Doug Jost
• Chris Mojica
• Karl Shearer
• Design
• More Simple
Top Ten Rules of Software Development
1. Order the T-shirts for the Development team
2. Announce availability
3. Write the code
4. Write the manual
5. Hire a Product Manager
6. Spec the software (writing the specs after the code helps to ensure that
the software meets the specifications)
7. Ship
8. Test (the customers are a big help here)
9. Identify bugs as potential enhancements
10. Announce the upgrade program
http://www.nullskull.com/a/722/the-top-ten-rules-of-software-development.aspx
Links
• http://xamarin.com/
• https://angularjs.org/
• https://github.com/crdeutsch/MonoTouch-JsBridge
• http://zynga.github.io/scroller/
• https://pfelix.wordpress.com/tag/asp-net-web-api/
• Designing Evolvable Web APIs with ASP.NET
• https://github.com/pmhsfelix/WebApi.Explorations.ServiceBusRel
ayHost
• www.moresimple.com

More Related Content

What's hot

C# everywhere - Building Cross-Platform Apps with Xamarin and MvvmCross
C# everywhere - Building Cross-Platform Apps with Xamarin and MvvmCrossC# everywhere - Building Cross-Platform Apps with Xamarin and MvvmCross
C# everywhere - Building Cross-Platform Apps with Xamarin and MvvmCrossFlavius-Radu Demian
 
Cross Platform Development with Xamarin
Cross Platform Development with XamarinCross Platform Development with Xamarin
Cross Platform Development with Xamarinbryan costanich
 
MS Experiences 17 - Xamarin: Future of Mobile Development
MS Experiences 17 - Xamarin: Future of Mobile DevelopmentMS Experiences 17 - Xamarin: Future of Mobile Development
MS Experiences 17 - Xamarin: Future of Mobile DevelopmentJames Montemagno
 
AnDevCon - Android and iOS Apps in C# with Xamarin
AnDevCon - Android and iOS Apps in C# with XamarinAnDevCon - Android and iOS Apps in C# with Xamarin
AnDevCon - Android and iOS Apps in C# with XamarinJames Montemagno
 
Introduction to CocosSharp
Introduction to CocosSharpIntroduction to CocosSharp
Introduction to CocosSharpJames Montemagno
 
C# everywhere: Xamarin and cross platform development
C# everywhere: Xamarin and cross platform developmentC# everywhere: Xamarin and cross platform development
C# everywhere: Xamarin and cross platform developmentGill Cleeren
 
Cross platform development
Cross platform developmentCross platform development
Cross platform developmentdftaiwo
 
Xamarin.forms Shell + Navigation
Xamarin.forms Shell + NavigationXamarin.forms Shell + Navigation
Xamarin.forms Shell + NavigationJames Montemagno
 
Native Mobile Apps, Xamarin, and PhoneGap
Native Mobile Apps, Xamarin, and PhoneGapNative Mobile Apps, Xamarin, and PhoneGap
Native Mobile Apps, Xamarin, and PhoneGapSasha Goldshtein
 
Xamarin Cross-Platform with Xamarin.Form, MvvmCross
Xamarin Cross-Platform with Xamarin.Form, MvvmCrossXamarin Cross-Platform with Xamarin.Form, MvvmCross
Xamarin Cross-Platform with Xamarin.Form, MvvmCrossTri Nguyen
 
COMAQA Conf #2. Никита Мещаненко. Xamarin test cloud
COMAQA Conf #2. Никита Мещаненко. Xamarin test cloudCOMAQA Conf #2. Никита Мещаненко. Xamarin test cloud
COMAQA Conf #2. Никита Мещаненко. Xamarin test cloudCOMAQA.BY
 
Hybrid Mobile Development
Hybrid Mobile DevelopmentHybrid Mobile Development
Hybrid Mobile DevelopmentShai Raiten
 
.Net Standard Libraries and Xamarin
.Net Standard Libraries and Xamarin.Net Standard Libraries and Xamarin
.Net Standard Libraries and XamarinJames Montemagno
 
Building hybrid apps with Xamarin, Ryan Paul
Building hybrid apps with Xamarin, Ryan PaulBuilding hybrid apps with Xamarin, Ryan Paul
Building hybrid apps with Xamarin, Ryan PaulXamarin
 
Mobile development with xamarin
Mobile development with xamarinMobile development with xamarin
Mobile development with xamarinMatthew Soucoup
 
PhoneGap Introduction
PhoneGap IntroductionPhoneGap Introduction
PhoneGap IntroductionWen-Kai Huang
 
Developing for the GeoWeb: Notes From The Field Dev Summit 2009
Developing for the GeoWeb: Notes From The Field Dev Summit 2009Developing for the GeoWeb: Notes From The Field Dev Summit 2009
Developing for the GeoWeb: Notes From The Field Dev Summit 2009Dave Bouwman
 

What's hot (20)

C# everywhere - Building Cross-Platform Apps with Xamarin and MvvmCross
C# everywhere - Building Cross-Platform Apps with Xamarin and MvvmCrossC# everywhere - Building Cross-Platform Apps with Xamarin and MvvmCross
C# everywhere - Building Cross-Platform Apps with Xamarin and MvvmCross
 
Xamarin microsoft graph
Xamarin microsoft graphXamarin microsoft graph
Xamarin microsoft graph
 
Cross Platform Development with Xamarin
Cross Platform Development with XamarinCross Platform Development with Xamarin
Cross Platform Development with Xamarin
 
MS Experiences 17 - Xamarin: Future of Mobile Development
MS Experiences 17 - Xamarin: Future of Mobile DevelopmentMS Experiences 17 - Xamarin: Future of Mobile Development
MS Experiences 17 - Xamarin: Future of Mobile Development
 
AnDevCon - Android and iOS Apps in C# with Xamarin
AnDevCon - Android and iOS Apps in C# with XamarinAnDevCon - Android and iOS Apps in C# with Xamarin
AnDevCon - Android and iOS Apps in C# with Xamarin
 
Introduction to CocosSharp
Introduction to CocosSharpIntroduction to CocosSharp
Introduction to CocosSharp
 
Xamarin DevOps
Xamarin DevOpsXamarin DevOps
Xamarin DevOps
 
Azure mobile services
Azure mobile servicesAzure mobile services
Azure mobile services
 
C# everywhere: Xamarin and cross platform development
C# everywhere: Xamarin and cross platform developmentC# everywhere: Xamarin and cross platform development
C# everywhere: Xamarin and cross platform development
 
Cross platform development
Cross platform developmentCross platform development
Cross platform development
 
Xamarin.forms Shell + Navigation
Xamarin.forms Shell + NavigationXamarin.forms Shell + Navigation
Xamarin.forms Shell + Navigation
 
Native Mobile Apps, Xamarin, and PhoneGap
Native Mobile Apps, Xamarin, and PhoneGapNative Mobile Apps, Xamarin, and PhoneGap
Native Mobile Apps, Xamarin, and PhoneGap
 
Xamarin Cross-Platform with Xamarin.Form, MvvmCross
Xamarin Cross-Platform with Xamarin.Form, MvvmCrossXamarin Cross-Platform with Xamarin.Form, MvvmCross
Xamarin Cross-Platform with Xamarin.Form, MvvmCross
 
COMAQA Conf #2. Никита Мещаненко. Xamarin test cloud
COMAQA Conf #2. Никита Мещаненко. Xamarin test cloudCOMAQA Conf #2. Никита Мещаненко. Xamarin test cloud
COMAQA Conf #2. Никита Мещаненко. Xamarin test cloud
 
Hybrid Mobile Development
Hybrid Mobile DevelopmentHybrid Mobile Development
Hybrid Mobile Development
 
.Net Standard Libraries and Xamarin
.Net Standard Libraries and Xamarin.Net Standard Libraries and Xamarin
.Net Standard Libraries and Xamarin
 
Building hybrid apps with Xamarin, Ryan Paul
Building hybrid apps with Xamarin, Ryan PaulBuilding hybrid apps with Xamarin, Ryan Paul
Building hybrid apps with Xamarin, Ryan Paul
 
Mobile development with xamarin
Mobile development with xamarinMobile development with xamarin
Mobile development with xamarin
 
PhoneGap Introduction
PhoneGap IntroductionPhoneGap Introduction
PhoneGap Introduction
 
Developing for the GeoWeb: Notes From The Field Dev Summit 2009
Developing for the GeoWeb: Notes From The Field Dev Summit 2009Developing for the GeoWeb: Notes From The Field Dev Summit 2009
Developing for the GeoWeb: Notes From The Field Dev Summit 2009
 

Viewers also liked

Custom HTML5-Native Bridge for Android
Custom HTML5-Native Bridge for AndroidCustom HTML5-Native Bridge for Android
Custom HTML5-Native Bridge for Androidmhant
 
Xamarin.Forms or Write Once, Run Anywhere
Xamarin.Forms or Write Once, Run AnywhereXamarin.Forms or Write Once, Run Anywhere
Xamarin.Forms or Write Once, Run AnywhereTom Walker
 
салтыков
салтыковсалтыков
салтыковnatacha0304
 
2010 NZJEL Appreciative Inquiry In Action
2010 NZJEL Appreciative Inquiry In Action2010 NZJEL Appreciative Inquiry In Action
2010 NZJEL Appreciative Inquiry In ActionSmartNet
 
Elizabeth calleja cuadro
Elizabeth calleja cuadroElizabeth calleja cuadro
Elizabeth calleja cuadroelizabeth2017
 
Paul Mueller_Resume
Paul Mueller_ResumePaul Mueller_Resume
Paul Mueller_ResumePaul Mueller
 
Qui és qui?
Qui és qui?Qui és qui?
Qui és qui?Victoria
 
Bryly - projekt eukacyjny
Bryly - projekt eukacyjnyBryly - projekt eukacyjny
Bryly - projekt eukacyjnyAnna Wołoszyn
 
Final FaceView Mask Presentation
Final FaceView Mask PresentationFinal FaceView Mask Presentation
Final FaceView Mask PresentationAlison Lillie
 
The State of Email and Marketing Automation in South-East Asia
The State of Email and Marketing Automation in South-East AsiaThe State of Email and Marketing Automation in South-East Asia
The State of Email and Marketing Automation in South-East AsiaEconsultancy
 
Meaningful Use of Electronic Health Records (October 16, 2016)
Meaningful Use of Electronic Health Records (October 16, 2016)Meaningful Use of Electronic Health Records (October 16, 2016)
Meaningful Use of Electronic Health Records (October 16, 2016)Nawanan Theera-Ampornpunt
 
BlueButton on FHIR at HIMSS'17 HL7 API Symposium
BlueButton on FHIR at HIMSS'17 HL7 API SymposiumBlueButton on FHIR at HIMSS'17 HL7 API Symposium
BlueButton on FHIR at HIMSS'17 HL7 API SymposiumMark Scrimshire
 
Getting started with FHIR by Ewout Kramer
Getting started with FHIR by Ewout KramerGetting started with FHIR by Ewout Kramer
Getting started with FHIR by Ewout KramerFHIR Developer Days
 
Operating System Chapter 3
Operating System Chapter 3Operating System Chapter 3
Operating System Chapter 3Nuth Otanasap
 

Viewers also liked (20)

Custom HTML5-Native Bridge for Android
Custom HTML5-Native Bridge for AndroidCustom HTML5-Native Bridge for Android
Custom HTML5-Native Bridge for Android
 
Xamarin.Forms or Write Once, Run Anywhere
Xamarin.Forms or Write Once, Run AnywhereXamarin.Forms or Write Once, Run Anywhere
Xamarin.Forms or Write Once, Run Anywhere
 
салтыков
салтыковсалтыков
салтыков
 
Almacenamiento de Gas Natural
Almacenamiento de Gas NaturalAlmacenamiento de Gas Natural
Almacenamiento de Gas Natural
 
2010 NZJEL Appreciative Inquiry In Action
2010 NZJEL Appreciative Inquiry In Action2010 NZJEL Appreciative Inquiry In Action
2010 NZJEL Appreciative Inquiry In Action
 
Elizabeth calleja cuadro
Elizabeth calleja cuadroElizabeth calleja cuadro
Elizabeth calleja cuadro
 
Paul Mueller_Resume
Paul Mueller_ResumePaul Mueller_Resume
Paul Mueller_Resume
 
PTA Resume
PTA ResumePTA Resume
PTA Resume
 
Qui és qui?
Qui és qui?Qui és qui?
Qui és qui?
 
Aprima For Physicians
Aprima For PhysiciansAprima For Physicians
Aprima For Physicians
 
Bryly - projekt eukacyjny
Bryly - projekt eukacyjnyBryly - projekt eukacyjny
Bryly - projekt eukacyjny
 
Final FaceView Mask Presentation
Final FaceView Mask PresentationFinal FaceView Mask Presentation
Final FaceView Mask Presentation
 
The State of Email and Marketing Automation in South-East Asia
The State of Email and Marketing Automation in South-East AsiaThe State of Email and Marketing Automation in South-East Asia
The State of Email and Marketing Automation in South-East Asia
 
MA_RUIDO
MA_RUIDOMA_RUIDO
MA_RUIDO
 
Estaciones de flujo
Estaciones de flujoEstaciones de flujo
Estaciones de flujo
 
Meaningful Use of Electronic Health Records (October 16, 2016)
Meaningful Use of Electronic Health Records (October 16, 2016)Meaningful Use of Electronic Health Records (October 16, 2016)
Meaningful Use of Electronic Health Records (October 16, 2016)
 
BlueButton on FHIR at HIMSS'17 HL7 API Symposium
BlueButton on FHIR at HIMSS'17 HL7 API SymposiumBlueButton on FHIR at HIMSS'17 HL7 API Symposium
BlueButton on FHIR at HIMSS'17 HL7 API Symposium
 
Getting started with FHIR by Ewout Kramer
Getting started with FHIR by Ewout KramerGetting started with FHIR by Ewout Kramer
Getting started with FHIR by Ewout Kramer
 
Ch07ath
Ch07athCh07ath
Ch07ath
 
Operating System Chapter 3
Operating System Chapter 3Operating System Chapter 3
Operating System Chapter 3
 

Similar to How We Built a Mobile Electronic Health Record App Using Xamarin, Angular, and Web API

125 고성능 web view-deview 2013 발표 자료_공유용
125 고성능 web view-deview 2013 발표 자료_공유용125 고성능 web view-deview 2013 발표 자료_공유용
125 고성능 web view-deview 2013 발표 자료_공유용NAVER D2
 
[Serverless Meetup Tokyo #3] Serverless in Azure (Azure Functionsのアップデート、事例、デ...
[Serverless Meetup Tokyo #3] Serverless in Azure (Azure Functionsのアップデート、事例、デ...[Serverless Meetup Tokyo #3] Serverless in Azure (Azure Functionsのアップデート、事例、デ...
[Serverless Meetup Tokyo #3] Serverless in Azure (Azure Functionsのアップデート、事例、デ...Naoki (Neo) SATO
 
e-KTP Information Extraction with Google Cloud Function & Google Cloud Vision
e-KTP Information Extraction with Google Cloud Function & Google Cloud Visione-KTP Information Extraction with Google Cloud Function & Google Cloud Vision
e-KTP Information Extraction with Google Cloud Function & Google Cloud VisionImre Nagi
 
Kraken Front-Trends
Kraken Front-TrendsKraken Front-Trends
Kraken Front-TrendsPayPal
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineRicardo Silva
 
Ibm xamarin gtruty
Ibm xamarin gtrutyIbm xamarin gtruty
Ibm xamarin gtrutyRon Favali
 
Into to Node.js: Building Fast, Scaleable Network Applications
Into to Node.js: Building Fast, Scaleable Network ApplicationsInto to Node.js: Building Fast, Scaleable Network Applications
Into to Node.js: Building Fast, Scaleable Network ApplicationsFlatiron School
 
Gdg dev fest hybrid apps your own mini-cordova
Gdg dev fest hybrid apps  your own mini-cordovaGdg dev fest hybrid apps  your own mini-cordova
Gdg dev fest hybrid apps your own mini-cordovaAyman Mahfouz
 
Intro To webOS
Intro To webOSIntro To webOS
Intro To webOSfpatton
 
Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Mahmoud Hamed Mahmoud
 
Android Wear: A Developer's Perspective
Android Wear: A Developer's PerspectiveAndroid Wear: A Developer's Perspective
Android Wear: A Developer's PerspectiveVin Lim
 
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 -  Fullstack end-to-end Test Automation with node.jsForwardJS 2017 -  Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.jsMek Srunyu Stittri
 
Test strategy for web development
Test strategy for web developmentTest strategy for web development
Test strategy for web developmentalice yang
 
Hybrid apps - Your own mini Cordova
Hybrid apps - Your own mini CordovaHybrid apps - Your own mini Cordova
Hybrid apps - Your own mini CordovaAyman Mahfouz
 
Codestrong 2012 breakout session building your own custom cloud services
Codestrong 2012 breakout session   building your own custom cloud servicesCodestrong 2012 breakout session   building your own custom cloud services
Codestrong 2012 breakout session building your own custom cloud servicesAxway Appcelerator
 
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...GITS Indonesia
 

Similar to How We Built a Mobile Electronic Health Record App Using Xamarin, Angular, and Web API (20)

125 고성능 web view-deview 2013 발표 자료_공유용
125 고성능 web view-deview 2013 발표 자료_공유용125 고성능 web view-deview 2013 발표 자료_공유용
125 고성능 web view-deview 2013 발표 자료_공유용
 
iOS and Android apps automation
iOS and Android apps automationiOS and Android apps automation
iOS and Android apps automation
 
[Serverless Meetup Tokyo #3] Serverless in Azure (Azure Functionsのアップデート、事例、デ...
[Serverless Meetup Tokyo #3] Serverless in Azure (Azure Functionsのアップデート、事例、デ...[Serverless Meetup Tokyo #3] Serverless in Azure (Azure Functionsのアップデート、事例、デ...
[Serverless Meetup Tokyo #3] Serverless in Azure (Azure Functionsのアップデート、事例、デ...
 
e-KTP Information Extraction with Google Cloud Function & Google Cloud Vision
e-KTP Information Extraction with Google Cloud Function & Google Cloud Visione-KTP Information Extraction with Google Cloud Function & Google Cloud Vision
e-KTP Information Extraction with Google Cloud Function & Google Cloud Vision
 
Kraken Front-Trends
Kraken Front-TrendsKraken Front-Trends
Kraken Front-Trends
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 Engine
 
Ibm xamarin gtruty
Ibm xamarin gtrutyIbm xamarin gtruty
Ibm xamarin gtruty
 
Into to Node.js: Building Fast, Scaleable Network Applications
Into to Node.js: Building Fast, Scaleable Network ApplicationsInto to Node.js: Building Fast, Scaleable Network Applications
Into to Node.js: Building Fast, Scaleable Network Applications
 
Gdg dev fest hybrid apps your own mini-cordova
Gdg dev fest hybrid apps  your own mini-cordovaGdg dev fest hybrid apps  your own mini-cordova
Gdg dev fest hybrid apps your own mini-cordova
 
Intro To webOS
Intro To webOSIntro To webOS
Intro To webOS
 
Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development
 
Android Wear: A Developer's Perspective
Android Wear: A Developer's PerspectiveAndroid Wear: A Developer's Perspective
Android Wear: A Developer's Perspective
 
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 -  Fullstack end-to-end Test Automation with node.jsForwardJS 2017 -  Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
 
Test strategy for web development
Test strategy for web developmentTest strategy for web development
Test strategy for web development
 
The MEAN stack
The MEAN stack The MEAN stack
The MEAN stack
 
Hybrid apps - Your own mini Cordova
Hybrid apps - Your own mini CordovaHybrid apps - Your own mini Cordova
Hybrid apps - Your own mini Cordova
 
Night Watch with QA
Night Watch with QANight Watch with QA
Night Watch with QA
 
Codestrong 2012 breakout session building your own custom cloud services
Codestrong 2012 breakout session   building your own custom cloud servicesCodestrong 2012 breakout session   building your own custom cloud services
Codestrong 2012 breakout session building your own custom cloud services
 
Node azure
Node azureNode azure
Node azure
 
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
 

Recently uploaded

How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfayushiqss
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxalwaysnagaraju26
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456KiaraTiradoMicha
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfryanfarris8
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 

Recently uploaded (20)

How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 

How We Built a Mobile Electronic Health Record App Using Xamarin, Angular, and Web API

  • 1. How We Built a Mobile Electronic Health Record App Using Xamarin, Angular, and Web API
  • 2. About Matt Spradley • Sr. Product Manager at Aprima • Co-founded 3 software companies • Used to write code • Tinkers every now and then • linkedin.com/in/mattspradley • mattspradley.com • matt.spradley@gmail.com • 214-403-6749
  • 3.
  • 4.
  • 5. How Should we Build a Cross Platform Mobile App? http://imgs.xkcd.com/comics/efficiency.png
  • 6. Requirements • Tablet 90% functional parity with desktop EHR • Work on iOS and Android phones and tablets • Integrate with on-premise servers • No control over network (DNS, Firewall, etc.) • Multiple versions of REST API
  • 8.
  • 9. …And the Results Score 66 64 63 53 Factor Weight HTML/Steroids HTML/Titanium Native/Xamarin Native UX 3 2 2 3 3 Code Reuse 3 3 3 2 1 Special UI 1 1 2 3 3 Control 1 2 2 3 3 Effort 3 3 2 2 1 Maintenance 3 2 2 3 2 Cloud Reuse 1 3 3 1 1 OS Integration 2 2 2 3 3 Deployment Options 1 3 3 1 1 Existing Dev Skills 1 2 2 3 1 Hiring 2 2 2 3 2 Vendor Stability 3 2 2 2 3 UTDesign Decision 1 2 2 1 1 UI Testability 3 3 3 1 1 Winner???
  • 10. Web UI with Angular Is Easy <ul id="appointments" class="list-group list-group-fixed-height“ collapse="tileState.isCollapsed"> <li class="list-group-item" ng-show="!loading && appointments.length == 0"> <div class="col-xs-12 text-center-vert text-center"> <span translate>No appointments</span> </div> </li> <li ng-repeat="appt in appointments | orderBy:'date'" data-transition-to="{ appRoute: 'patientDashboard', opts: {id: appt.PatientId}}" class="list-group-item" ng-class="{'active': (!!appt.clicked)}"> <ap-appointment-list-item data-appt="appt" data-context-menu-id="appt-context-menu-{{$index}}"> </ap-appointment-list-item> </li> </ul>
  • 11. <div class="panel-body panel-flush" collapse="tileState.isCollapsed" ng-if="!loading && !httpError"> <table class="table table-striped ap-table"> <thead> <tr> <th translate>Name</th> <th ng-repeat="column in vitals.Columns | limitTo:observationLimit"> <ap-date-formatter date="{{column.ObservationDateTime}}“ format="short-date"></ap-date-formatter> </th> </tr> </thead> <tbody> <tr ng-show="vitalsExist" ng-repeat="observations in vitals.Rows | filter:hasValueForColumns"> <td>{{observations.Name}}</td> <td ng-repeat="observation in observations.Observations | limitTo:observationLimit" ng-class="{danger: !observation.IsInRange && observation.Value}" class="vital-value"> {{observation.Value}} </td> </tr> <tr ng-if="!vitalsExist"> <td> <span id="no-vital-results" translate> No known vitals. </span> </td> </tr> </tbody> </table> </div> Web UI with Angular Is Easy, Really
  • 12. Code and Build • Web UI • Code in HTML, Less, AngularJS • Build • Grunt • Less • Template process • JsHint • Uglify • Unit Tests w/ Jasmine and Karma • Deploy • Translate • Images to Less
  • 13. Chocolate and Peanut Butter Our Customers LOVE Aprima NOW
  • 14. Go Native with Xamarin for Hard Stuff • For • Taking Pictures • Image Annotation • PDF Viewer • Why • Flexibility • C# • Performance • Custom UI • Look and Feel • Services • Hiring
  • 16. Aprima NOW Hybrid Architecture Javascript/HTML JS <--> Xamarin(C#) Bridge Xamarin(C#) AngularJS App JS Bridge Common (portable class library) Xamarin.Android Xamarin.iOS Fire Event Subscribe SubscribeHandle Events Handle Events Fire Event or Subscribe Invoke Callback from Subscription AppServer
  • 17.
  • 18. Javascript Bridge Angular Service, Ctrl etc iOS JS Bridge Android JS Bridge WinForms JS Bridge Fire Events to C#. Subscribe to Events from C# iOS C# Bridge Android C# Bridge WinForms C# Bridge XHR to app:// window.AndrApp.Event(eventData); window.external.HandleEvent(eventData) C# Objects Fire Events to JS Subscribe to Events from JS webview.EvaluateJavascript(jsToFireEvent); Webview.LoadUrl( javascript:{jsToFireEvent} ); Webview.Document.InvokeScript( eval , jsToFireEvent ); Handle events from C# Handle events from JS
  • 19.
  • 20. Jsbridge.js • JS object provides bridging capabilities to JS code • Fire events to C# • Add event handlers in JS to be called when event is fired from C# • Bridge implementations for iOS, Android, and WinForms • Normalizes event structure for consistency: app://{module}/fireEvent?data={jsEventDataJson}&_={random}
  • 21. C# -> JS event Firing • To fire an event, call the following. BridgeContext is a bridge which is scoped to the UI WebView component (iOS: UIWebView; Android: WebView; WinForms: Form/Control/etc) this.BridgeContext.FireEvent(eventName, data); • Which calls the following within the BridgeContext instance and actually dispatches the event to javascript. ExecuteScript is implemented differently by each platform. ExecuteScript(string.Format("bridge.app._dispatchEvent('{0}', {1});", eventName, json));
  • 22. iOS Jsbridge.js • To send an event from JS to C#, iOS uses a custom NSUrlProtocol implementation which listens for XHR traffic on a custom protocol (“app://”). • To send event from JS to C#, an XHR request is made to custom protocol with event data in the url. function (url) { var x1 = new bridge.app.CustomXhr(); x1.onerror = function (e) { console.log('XHR error:' + JSON.stringify(e)); }; x1.open('GET', url); x1.send(); }
  • 23. iOS C# Bridge • Registers global NSUrlProtocol handler, takes an instance of UIWebView and bind global events to specific UIWebViews. • To send event from C# to JS, executes dynamically generated JS which calls into jsbridge.js component. public override void ExecuteScript(string javascript) { webView.BeginInvokeOnMainThread(() => _webView.EvaluateJavascript(javascript)); }
  • 25. Android jsbridge.js • To send an event from JS to C#, Android uses a Java object which is made accessible as a JavaScript object by adding the object instance to the Webview as a JavaScript Interface. • To send event from JS to C#, a method on the Java object instance is invoked from JavaScript. function (url){ var result = window.AndrApp.Event(url); result = JSON.parse(result); if (!result.Success) { console.log('Android bridge error: ' + JSON.stringify(result)); } }
  • 26. Android C# bridge • Instantiates and adds java object with [Export] or [JavascriptInterface] members. Members are accessible from javascript. webView.AddJavascriptInterface(new JsBridgeExports(this), "AndrApp"); • To execute a script, it loads a url which contains javascript to be executed: public override void ExecuteScript(string javascript) { activity.RunOnUiThread(() => _webView.LoadUrl(string.Format("javascript: {0}", javascript))); }
  • 27. WinForms jsbridge.js • To send an event from JS to C#, WinForms uses a C# object which is made accessible as a Javascript object by adding the object instance to the WebView as the ObjectForScripting. • To send event from JS to C#, a method on the C# object instance is invoked from javascript. function (url) { var result = window.external.HandleEvent(url); result = JSON.parse(result); if (!result.Success) { console.log('PRM bridge error: ' + JSON.stringify(result)); } }
  • 28. WinForms C# bridge • Instantiates and adds C# object to the WebBrowser instance as the ObjectForScripting. ObjectForScripting must be have[ComVisible(true)] this._browser.ObjectForScripting = new JsBridgeWindowExternalHandler(this); To fire event from C# to JS, eval function is invoked from C# with a IIFE (Immediately Invoked Function Expression) public override void ExecuteScript(string javascript) { _browser.Invoke(new Action(() => { if (_browser.Document != null) { var script = string.Format("(function() {{ {0}; }})();", javascript); _browser.Document.InvokeScript("eval", new object[] { script }); } })); }
  • 29. JS Code to fire and listen for events angular.module('amodule').controller('SomeCtrl', ['$scope', 'Bridge', function ($scope, Bridge){ //fire event Bridge.navigate('aRoute', { id : 0 }); //listen for event Bridge.on('someEvent', function (data) { $scope.data = data; }); }] );
  • 30. C# code to fire and listen for events //Fire Event this.BridgeContext.FireEvent("navigate", new { id = 0}); //listen to event this.BridgeContext.AddEventListener("someEvent", (SomeType data) => { //do something with data });
  • 31. Notes • Bridge lifetimes vary by platform. • iOS has a singleton bridge because NSProtocolHandler is added for an entire application instead of for a specific UIWebView. iOS bridge has logic to broker events to the correct bridge context which isassociated with a specific UIWebView. • Android bridges are instantiated per WebView instances • WinForms bridges are instantiated per WebBrowser instance • Native components must tell JS bridge which native implementation is used. This can happen AFTER events have already been fired from JS. This required queuing of events until the bridge was finished being setup.
  • 32. Notes • Majority of code is in a PCL library and reused by all platforms • Dll exists for each platform that contains platform specific code • Very little platform specific code • Bridge behavior consistent across the platforms
  • 33. Frontend Tech Stack • Xamarin • Angular • Bootstrap • lodash • Less • Hammer.JS
  • 35. Web UI is Easy to Test and Debug Grunt Jasmine Protractor Webdriver E2E
  • 36. Device Testing with Xamarin Test Cloud
  • 37. Xamarin Test Cloud Testing [Test] public void PinchToZoom() { LoginPage.Login(app); app.WaitForElement(x => x.Css("#dashboard")); app.Screenshot("Then I am logged in at my home screen"); app.GoToPatients(); QuicksearchPage.SearchForPatient(app, "Anderson"); QuicksearchPage.SelectPatient(app, "e2ab0790-f271-471a-bdc2-e6bca0889dad"); app.WaitForElement(x => x.Css("#patient-widgets"), "Timed out waiting for patient dashboard to load", new TimeSpan(0, 0, 3)); app.Screenshot("Then I see Jeff's profile"); PatientDashboardPage.ExpandWidget(app, PatientDashboardWidget.ObservationResults); PatientDashboardPage.TapObservationResult(app, "3f39a0fa-99e9-494b-a234-170f3ff824ba"); Thread.Sleep(5000); app.Screenshot("Now I should see the images"); //Scroll down to view first image app.ScrollDownEnough(x => x.WebView().Css(".image-viewer")); var rect = app.Query(x => x.WebView().Css(".image-viewer"))[0].Rect; app.Zoom(rect.CenterX, rect.CenterY, 100); app.Screenshot("Now I zoom in on the image"); }
  • 38. Not All Web Browsers are Equal
  • 39. iOS and Android Webview Update Differences
  • 40. Inertial Scroll or EasyScroller • Safari: Fixed DIVs Bad • https://github.com/zynga/scroller
  • 41. Xamarin Issues • Constant updates • Things break • Universal API kerfuffle • IDE lockups • They’re still awesome and smart http://www.doomsteaddiner.net/blog/wp-content/uploads/2013/04/wheels-off-hummer.png
  • 42. Backend • Web API • OWIN • Azure Relay • SQL Server • Feature List for Versions • NEO (home brew ORM)
  • 43. REST Facade App Server UI 1 UI 2 DBEF Other Aprima Mobile Application Architecture Decoupled deployment from Aprima Main
  • 45. Azure Relay WebHttpBinding A Developer’s Guide to Service Bus in Windows Azure Platform
  • 46. Service Bus Relay Web API Host https://pfelix.wordpress.com/tag/asp-net-web-api/
  • 47. Relay Demo • By pass on-premise issues • … and pesky IT road blocks http://imgs.xkcd.com/comics/security.png
  • 48. Azure Relay Performance -100 0 100 200 300 400 500 600 700 800 Azure Ping1 (ms) Relay Ping1 (ms) Azure Ping2 (m2) Relay Ping2 (m2) Azure 5K (ms) Relay 5K (ms) Azure 10k (ms) Relay 10k (ms) Azure 50K (ms) Relay 50K (ms) Azure 500K (ms) Relay 500K (ms)Average
  • 49. Code Metrics • Backend ≈ 50K lines • 87% C# • 10% Build scripts • 3% Other • Frontend ≈ 100K lines • 59% JavaScript • 30% HTML (HTML, CSS, Less) • 8% C# (90% in common PCL) • 3% Build scripts
  • 51. Thanks to a Great Team • Mobile Team • Ryan Cady • Kenneth Crawford • Mike Duran • Jeff Lott • Contributors • Doug Jost • Chris Mojica • Karl Shearer • Design • More Simple
  • 52. Top Ten Rules of Software Development 1. Order the T-shirts for the Development team 2. Announce availability 3. Write the code 4. Write the manual 5. Hire a Product Manager 6. Spec the software (writing the specs after the code helps to ensure that the software meets the specifications) 7. Ship 8. Test (the customers are a big help here) 9. Identify bugs as potential enhancements 10. Announce the upgrade program http://www.nullskull.com/a/722/the-top-ten-rules-of-software-development.aspx
  • 53. Links • http://xamarin.com/ • https://angularjs.org/ • https://github.com/crdeutsch/MonoTouch-JsBridge • http://zynga.github.io/scroller/ • https://pfelix.wordpress.com/tag/asp-net-web-api/ • Designing Evolvable Web APIs with ASP.NET • https://github.com/pmhsfelix/WebApi.Explorations.ServiceBusRel ayHost • www.moresimple.com