{"id":213,"date":"2014-10-14T09:00:00","date_gmt":"2014-10-14T09:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudio\/2014\/10\/14\/mobile-apps-for-web-developers\/"},"modified":"2022-09-30T11:21:01","modified_gmt":"2022-09-30T18:21:01","slug":"mobile-apps-for-web-developers","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/visualstudio\/mobile-apps-for-web-developers\/","title":{"rendered":"Mobile Apps for Web Developers"},"content":{"rendered":"<p>The path of a mobile app developer often begins with a choice: <em>develop for iOS, Android or Windows?<\/em> It\u2019s a choice that instantly diminishes the size of your potential audience, but developers often hold their nose and reluctantly make a decision. Those who need to reach all three app stores, choose to rewrite the application for each platform.<\/p>\n<p>Visual Studio enables you to have maximum reach while achieving significant code re-use. With Xamarin, C# developers can share business logic across iOS, Android, and Windows applications. With Apache Cordova, web developers can achieve maximal code re-use by building cross-platform mobile applications using HTML, CSS, and JavaScript.<\/p>\n<p>In this post, we\u2019ll take a close look at how you can use Visual Studio\u2019s extension for Multi-Device Hybrid App Development to build a cross platform app using HTML, JS, and CSS. To follow along in the IDE:<\/p>\n<ul>\n<li><a href=\"http:\/\/msdn.microsoft.com\/en-us\/vstudio\/dn722381.aspx\">Download and install the extension<\/a> on Visual Studio 2013 Pro Update 3, or\u2026<\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/visual-studio-tools-for-apache-cordova-azure-vm-available\/\">Try one of the trial VMs available on Azure<\/a>.<\/li>\n<\/ul>\n<p>Once you\u2019ve installed the tools, create a project for \u201cMulti-Device Hybrid Apps.\u201d<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2014\/10\/1050.CreatenewprojectinVisualStudioforMobileDeviceHybridApps_12403A0E.png\"><img decoding=\"async\" style=\"float: none; margin-left: auto; margin-right: auto; border-width: 0px;\" title=\"Create new project in Visual Studio for Mobile Device Hybrid Apps\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2014\/10\/1050.CreatenewprojectinVisualStudioforMobileDeviceHybridApps_12403A0E.png\" alt=\"Create new project in Visual Studio for Mobile Device Hybrid Apps\" width=\"640\" height=\"409\" border=\"0\" \/><\/a><\/p>\n<h2>Access Device Capabilities on any Platform Using the Same JS API<\/h2>\n<p>Before we explore the tools, let\u2019s take a moment to look at the architecture of a Cordova app. The application itself is implemented as an HTML application (e.g. <a href=\"http:\/\/en.wikipedia.org\/wiki\/single-page_application\">Single Page Application<\/a>) hosted inside a webview control (or on Windows, as a WWA) that gives your app access to native device APIs. Most developers prefer to synchronize data with a server via RESTful web services (e.g. <a href=\"http:\/\/azure.microsoft.com\/en-us\/services\/mobile-services\">Azure Mobile Services<\/a>), but all file assets like HTML, CSS, JS, and media are packaged with the application so that users can continue to use the app offline.<\/p>\n<p>To access native device capabilities (e.g. camera, contacts, file system, accelerometer) from JavaScript, Cordova uses a construct called plugins. Plugins typically encapsulate two components: native code to invoke capabilities for each of the three platforms (i.e. Objective-C, Java and C#) and a normalized JavaScript API available for your app to use.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2014\/10\/8816.Plugin_7FF7734B.png\"><img decoding=\"async\" style=\"float: none; margin-left: auto; margin-right: auto; border-width: 0px;\" title=\"Plugin\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2014\/10\/8816.Plugin_7FF7734B.png\" alt=\"Plugin\" width=\"184\" height=\"279\" border=\"0\" \/><\/a><\/p>\n<p>To use the API, you make an asynchronous call from within your JavaScript. The native code returns a response to the callback function. In the example below, the camera plugin returns the URI of a photo pointing to the file system on the mobile device.<\/p>\n<blockquote><p><span style=\"font-size: x-small;\"><span style=\"font-family: Consolas;\"><span style=\"color: #008000;\">\/\/ Retrieve image file location from the mobile device photo library<\/span>\n<span style=\"color: #0000ff;\">function<\/span> getPhotoURI() {\nnavigator.camera.getPhoto(onPhotoSuccess, onPhotoFail, {\nquality: 50,\ndestinationType: destinationType.FILE_URI,\nsourceType: pictureSource.PHOTOLIBRARY\n});\n}\n<span style=\"color: #008000;\">\/\/ Callback from successful Photo Library event<\/span>\n<span style=\"color: #0000ff;\">function<\/span> onPhotoSuccess(imageURI) {\n<span style=\"color: #008000;\">\u00a0 \/\/ Add img to div#album<\/span>\n<span style=\"color: #0000ff;\">var<\/span> img = document.createElement(<span style=\"color: #c10000;\">&#8216;img&#8217;<\/span>);\nimg.setAttribute(<span style=\"color: #c10000;\">&#8216;src&#8217;<\/span>, imageURL);\ndocument.getElementById(<span style=\"color: #c10000;\">&#8216;album&#8217;<\/span>).appendChild(img);\n}<\/span><\/span><\/p><\/blockquote>\n<h2>Designed to Converge with Web Standards<\/h2>\n<p>Cordova plugins are generally designed to expose JavaScript APIs that will converge with web standards over time. The goal is for the plugins to eventually evaporate leaving the implementations of the W3C standards in their place. For example, the <a href=\"http:\/\/www.w3.org\/tr\/vibration\/\">Web API<\/a> for activating device vibration, navigator.vibrate(time), is already implemented by <a href=\"http:\/\/plugins.cordova.io\/#\/package\/org.apache.cordova.vibration\">Cordova<\/a>, <a href=\"https:\/\/groups.google.com\/a\/chromium.org\/forum\/#!topic\/blink-dev\/hH9bJGWKAbk\">Chrome<\/a>, and <a href=\"https:\/\/developer.mozilla.org\/en-us\/docs\/web\/api\/navigator.vibrate\">Firefox<\/a>. Over time all the mobile devices and browsers will use the same API, thereby making plugins obsolete as a polyfill. The ultimate goal is for Cordova to serve as a temporary bridge until the standard web platform supports the device capability.<\/p>\n<h2>JavaScript or TypeScript: Your Choice<\/h2>\n<p>Once you get started, a large part of your time will be spent writing code. Whether it\u2019s HTML, CSS, JavaScript or TypeScript, we aim to provide our developers with help in context for the task at hand<strong>.<\/strong> For example, many developers depend on IntelliSense to avoid common syntax errors and quickly explore new APIs. Would you like to know what native device capabilities are available to your app? Visual Studio\u2019s Tools for Apache Cordova include IntelliSense support for common Cordova plugins using both JavaScript and TypeScript.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2014\/10\/5023.MobileAppsForWebDevsIntelliSensesupportforcommonCordovaplugins2_6ADC8026.png\"><img decoding=\"async\" style=\"float: none; margin-left: auto; margin-right: auto; border-width: 0px;\" title=\"IntelliSense support for common Cordova plugins\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2014\/10\/5023.MobileAppsForWebDevsIntelliSensesupportforcommonCordovaplugins2_6ADC8026.png\" alt=\"IntelliSense support for common Cordova plugins\" width=\"640\" height=\"116\" border=\"0\" \/><\/a><\/p>\n<p>If you write a custom plugin, you might want to enable IntelliSense for your component as well. To support the common Cordova plugin APIs, we use a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/hh874692.aspx\">JavaScript IntelliSense extension<\/a> for the JavaScript editor. For TypeScript, we simply wrote TypeScript d.ts files to describe each API. You can see the d.ts files in the public home for open source d.ts files: <a href=\"https:\/\/github.com\/borisyankov\/definitelytyped\/tree\/master\/cordova\">DefinitelyTyped<\/a>. Each d.ts file provides the meta-data necessary to provide rock-solid, accurate IntelliSense for Cordova plugins without executing JavaScript code in the background.<\/p>\n<h2>Three Ways to Preview Your App<\/h2>\n<p>To gain the highest productivity benefit, most developers choose to use the same code &#8211; 95% or more &#8211; amongst all deployment targets: iOS, Android, and Windows.<\/p>\n<p>Since most developers choose to deploy a single shared HTML\/CSS\/JS codebase to all platforms, it\u2019s important to be sure your apps look and behave as expected across the platforms you care about. We made sure that previewing your app would be as painless and efficient as possible by providing three options to test your app: (1) a Chrome-based simulator called Ripple, (2) native emulators provided by the platform vendors, and (3) deployment to an actual tethered device.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2014\/10\/3618.Previewingyourapp_11D40719.png\"><img decoding=\"async\" style=\"float: none; margin-left: auto; margin-right: auto; border-width: 0px;\" title=\"Previewing your app\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2014\/10\/3618.Previewingyourapp_11D40719.png\" alt=\"Previewing your app\" width=\"640\" height=\"350\" border=\"0\" \/><\/a><\/p>\n<p>Unless you\u2019re an otherworldly developer who can get an app running perfectly without ever running it, you\u2019ll eventually need to deploy and test it on a device or emulator for each platform. However, that\u2019s not necessarily where you want to start. Our general guidance is as follows:<\/p>\n<ol>\n<li><strong>For basic layout and early-stage debugging, use Ripple.<\/strong> Ripple is an open-source simulator that runs inside Chrome. Visual Studio automatically downloads and installs both Ripple and Chrome when you install our tools. Because Ripple uses Google\u2019s V8 engine and blink-based rendering, it is ideal for simulating behavior on an iOS or Android device. Realistically, there are only a small number of substantial rendering differences between Chrome and IE11 these days, so it\u2019s also a good proxy for Windows platforms. It\u2019s nice to do your early development in Ripple because, quite frankly, it\u2019s fast and familiar to web developers. Ripple benefits from all the CPU resources of your desktop and thousands of tiny performance optimizations designed to make desktop browsing snappy.<\/li>\n<li><strong>For final validation and full-fidelity debugging, use a device.<\/strong> As much as we love to debug in the desktop browser, there are some minor, but significant differences between it and mobile browsers. Unfortunately, tiny differences in CSS rendering or JavaScript interpretation can have a big impact, so it\u2019s important to test your app on the real thing. The real source of truth will always be the device. Using the native build systems (i.e. Xcode, the Android and Windows SDKs), Visual Studio can build and deploy to devices tethered to your dev machine via USB.<\/li>\n<li><strong>If a device isn\u2019t available, use an emulator.<\/strong> Given the range of devices and platform versions out there \u2014 especially Android versions \u2014 it\u2019s not always possible to have a complete library of test devices. In our office, we keep a small library of representative devices including: iPods running iOS7-8, a Samsung Galaxy running Android 4.0, a Nexus 7 running Android 4.4, a Nokia 1520 running Windows Phone 8.1 and our dev machines running Windows 8.1. For everything else, we use an emulator.<\/li>\n<\/ol>\n<p>For more about the previewing options available and their level of support on Android, iOS, and Windows, check out our <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dn757049.aspx\">documentation<\/a>.<\/p>\n<h2>Find and Fix Bugs Before Your Customers Do<\/h2>\n<p>Finally, there will be times when you have some tough or hard-to-find bugs in your JavaScript or TypeScript code. During these times, you will need to call in your trusty friend, the debugger.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2014\/10\/3632.Debugging_3497CF87.png\"><img decoding=\"async\" style=\"float: none; margin-left: auto; margin-right: auto; border-width: 0px;\" title=\"Debugging\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2014\/10\/3632.Debugging_3497CF87.png\" alt=\"Debugging\" width=\"640\" height=\"367\" border=\"0\" \/><\/a><\/p>\n<p>You get all the debugging tools already familiar to Windows Store developers including the DOM Explorer, JavaScript Console, breakpoints, watches, locals, Just My Code, and more. Other diagnostic tools are not yet available.<\/p>\n<p>In our initial release, we focused debugging support on Android 4.4 and Windows Store. But after hearing from developers like you, this summer we added debugging support for Android 2.3.3 and above. Debugging support for versions below Android 4.4 requires you to use a debug proxy, the most popular of which is <a href=\"https:\/\/www.jshybugger.com\/\">jsHybugger<\/a>.<\/p>\n<h2>That\u2019s it. Now go try the tools!<\/h2>\n<p>If you haven\u2019t already, please <a href=\"http:\/\/msdn.microsoft.com\/en-us\/vstudio\/dn722381.aspx\">download and install the tools<\/a> or <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/visual-studio-tools-for-apache-cordova-azure-vm-available\/\">try one of the trial VMs hosted in Azure<\/a>. Sample apps are available using three of today\u2019s popular frameworks: <a href=\"http:\/\/code.msdn.microsoft.com\/angularjs-todo-sample-for-b651512a\/\">AngularJS<\/a>, <a href=\"http:\/\/code.msdn.microsoft.com\/backbonejs-todo-sample-for-615ac9f0\">Backbone<\/a> and <a href=\"http:\/\/code.msdn.microsoft.com\/winjs-todo-sample-for-17295485\">WinJS + TypeScript<\/a>. Once you get rolling:<\/p>\n<ul>\n<li><a href=\"mailto:multidevicehybridapp@microsoft.com\"><strong>Send feedback<\/strong><\/a> to the product team via email.<\/li>\n<li><a href=\"http:\/\/stackoverflow.com\/questions\/tagged\/multi-device-hybrid-apps\"><strong>Ask for help with a problem<\/strong><\/a> via StackOverflow using the tag <em>multi-device-hybrid-apps<\/em><em>.<\/em><\/li>\n<li><a href=\"http:\/\/visualstudio.uservoice.com\/forums\/121579-visual-studio\/category\/82642-multi-device-hybrid-apps\"><strong>Vote for a new feature<\/strong><\/a> via UserVoice.<\/li>\n<\/ul>\n<p>Until next time, happy coding!\nRyan J. Salva<\/p>\n<table style=\"width: 811px;\" border=\"0\" cellspacing=\"0\" cellpadding=\"2\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"124\"><a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2014\/10\/3250.image_thumb_0F66B79D.png\"><img decoding=\"async\" style=\"border-width: 0px;\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2014\/10\/3250.image_thumb_0F66B79D.png\" alt=\"image\" width=\"160\" height=\"139\" border=\"0\" \/><\/a><\/td>\n<td valign=\"top\" width=\"685\"><strong>Ryan J. Salva<\/strong>, Principle Program Manager, Visual Studio Client Tools team\nTwitter: <a href=\"https:\/\/twitter.com\/ryanjsalva\" target=\"_blank\" rel=\"noopener noreferrer\">@ryanjsalva<\/a><\/p>\n<p>Ryan is a Principal Program Manager working in the Visual Studio Client Tools team where he looks after HTML, CSS and JavaScript development. He comes from a 15 year career in web standards development &amp; advocacy as an entrepreneur, developer and graphic designer. Today, he focuses primarily on mobile app development using web technologies and Apache Cordova.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>The path of a mobile app developer often begins with a choice: develop for iOS, Android or Windows? It\u2019s a choice that instantly diminishes the size of your potential audience, but developers often hold their nose and reluctantly make a decision. Those who need to reach all three app stores, choose to rewrite the application [&hellip;]<\/p>\n","protected":false},"author":13,"featured_media":255385,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1195,1196,4980,1028,561,155],"tags":[5,136,9,137,376,124,125,12,353],"class_list":["post-213","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cross-platform","category-desktop","category-java","category-mobile","category-open-source","category-visual-studio","tag-csharp","tag-css","tag-debug","tag-html","tag-java","tag-javascript","tag-typescript","tag-visual-studio","tag-xamarin"],"acf":[],"blog_post_summary":"<p>The path of a mobile app developer often begins with a choice: develop for iOS, Android or Windows? It\u2019s a choice that instantly diminishes the size of your potential audience, but developers often hold their nose and reluctantly make a decision. Those who need to reach all three app stores, choose to rewrite the application [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/213","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/comments?post=213"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/213\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media\/255385"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media?parent=213"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/categories?post=213"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/tags?post=213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}