Gopro App
TRANSILVANIA UNIVERSITY OF BRAȘOV
Electrical Engineering and Computers Science Faculty
Electrical Engineering and Applied Physics Department
Bachelor degree: Electrical Engineering and Computers
GoPro App
– DIPLOMA PROJECT –
Graduate: MOIAN-DUSA Radu
Scientific coordinator: Conf.univ.dr.ing. Ungureanu Delia
2015
Table of Contents
Native, Web or Hybrid Apps? What’s the difference?
[1]
The Basics
As it stands, most mobile devices use one of the two dominant operating systems: Google-developed Android (48.3%) and the Apple-developed iOS (41%).
The difference between these operating systems and their related devices isn’t just aesthetic: Just as your MacBook won’t run a Windows application, an Android phone can’t run an app built for iPhone — in most cases at least.
With the rise of the smartphone, it’s apparent that we love apps. You only have to look at the statistics: App Store, 85 billion downloads to October 2014, Google Play, 50 billion downloads to January 2014.
What about Blackberry and Windows phones? From an app developer point of view, their small, declining market share means that there’s little need to consider them. Google and Apple are dominant and this is not going to change.
Native Apps
Native apps are what typically springs to mind when you think of an app. You download them from the App Store or Google Play, they sit within your device’s applications and you launch them by tapping their icon.
Developing Native Apps
What distinguishes native apps from the alternatives mentioned is that they are designed and coded for a specific kind of device. For instance, iPhone apps are written in Objective-C, Android apps in Java, etc.
Each mobile platform offers developers their own development tools, interface elements and standardized SDK. This should enable any professional developer to develop a native app relatively easily.
There are a number of advantages to writing apps in this way:
They offer the fastest, most reliable and most responsive experience to users.
They can tap into the wider functionality of the device; including the camera, microphone, compass, accelerometer and swipe gestures.
Publishers can make use of push-notifications, alerting users every time a new piece of content is published or when their attention is required. This is a key method of engagement. You get the opportunity to continually bring your audience back for more.
Users spend time on apps. The popularity of apps has increased enormously and is continuing to rise.
It’s not just about access to core device capabilities though, native apps, when well designed, respect the design patterns and standards of each platform. It goes beyond a left-aligned header on Android vs a center-aligned header on iOS, there’s hundreds of small differences in the design of user interactions on each platform. Taking them all into account means designing apps that are intuitive to use and play well with the rest of that platform’s ecosystem. Overall, going for native apps helps you create apps that are designed to delight your users.
The main downside of a native app is that it will not work with other kinds of devices. If you write an app in Objective-C for iOS, it’s not going to run on Android without being completely re-written in Java. When building for multiple platforms, developing a native app therefore can be quite expensive (when done from scratch), as it will require you to build and maintain multiple, separate versions of your app. It’s also common for developers to specialize in one platform, so often you’ll have to find different coders for each platform you want your app to be available for.
If your budget allows it, native apps are the ideal, offering the best user experience. When building from scratch and when multi-platform support is key, then be aware this can also be the most costly option.
A reputable developer or agency can easily quote between $25,000 and $50,000 for a custom native app, built from the ground up. Multiply that for every platform you need to cover, considering nowadays you kind of have to build for both iOS and Android.
What are Web Apps?
At the other end of the scale are mobile-optimized web apps.
If you’ve ever seen the ‘mobile version’ of a site, that’s what we’re talking about. An “app” like this loads within a mobile browser, like Safari or Chrome, like every other website. Your audience doesn’t have to install a web app. They don’t need to have available space on their devices.
Web apps are sometimes designed to look and behave like apps and are in general ideal when the purpose is simply to make content or functionality available on mobile, but an app is either not a good fit or too expensive.
Web apps use JavaScript, CSS, HTML5 or other languages. A developer won’t have access to a standardized SDK. Developing a web app can be simple and quick, however, their simplicity is also their downside.
There are web app “evangelists” out there that are adamant that web apps are equal to, or even better than native apps. They argue flexibility in terms of cost and functionality. There is no dependence on having a certain type of hardware either.
Web apps are limited in what they can do effectively in terms of features and they will generally always require an Internet connection to work. They are slower and less intuitive. Web apps are designed once for every platform and therefore won’t look or behave like a real app on any of them.
If you use a web app, be warned that they are also more difficult to build a loyal user-base form. Unless the reader saves it as a bookmark, users won’t have the app’s icon on their home screen as a constant reminder. As a developer or publisher, you can’t send them notifications to bring them back to your content. It’s difficult to engage with your audience.
Furthermore, with a web app, you’re missing out on an important source of downloads/traffic. Whilst native and hybrid apps appear on the App Store and Google Play, web apps won’t. With millions of searches every day on these stores, the potential to get your app discovered is real.
What are Hybrid Apps?
Somewhere between native and web apps you’ll find hybrid apps. They are usually quicker to build (and thus cheaper) than native apps, but a step-up from what you can expect out of browser-based web apps. Is the hybrid app the best of both worlds?
The bulk of the app is built using cross-compatible web technologies, such as HTML5, CSS and JavaScript — the same languages used to write web apps. Some native code is used however to allow the app to access the wider functionality of the device and produce a more refined user experience. For native apps, instead only native code is used. The advantage of this approach is obvious: only a portion of native code has to be re-written to make the app work on the different kinds of devices available.
An advantage that hybrid apps have over native is that it’s faster and easier to develop. It’s also easier to maintain and you can change platforms. The app itself will not be as fast as a native app as it still depends on the browser speed.
There are two main players in the world of hybrid apps: Phonegap/Cordova and Appcelerator Titanium. With these tools you create HTML/CSS/JavaScript local files, design and build the app as if it was a website, then use Cordova to wrap them into a mobile app.
Getting your hybrid app to run appropriately on each platform generally takes substantial work. In some situations, the total cost might become comparable to that of fully native apps, rendering the cost benefits negligible. It all depends on how close you want to get to the “native user experience” or how simple your app is.
When the user accesses your web content online through a hybrid app, performance will be sluggish when compared with a native app.
Still, there’s one big advantage in hybrid apps. Being built on one single core, you can add functionality and have multiple versions of the app all benefit from it. On the contrary, with native apps, for every new functionality you want to introduce, the feature will have to be replicated on each platform. [1]
Frameworks
Cordova
Figure 1. Cordova’s logo
Overview [2]
Apache Cordova is an open-source mobile development framework. It allows you to use standard web technologies such as HTML5, CSS3, and JavaScript for cross-platform development, avoiding each mobile platforms' native development language. Applications execute within wrappers targeted to each platform, and rely on standards-compliant API bindings to access each device's sensors, data, and network status.
Apache Cordova graduated in October 2012 as a top level project within the Apache Software Foundation (ASF). Through the ASF, future Cordova development will ensure open stewardship of the project. It will always remain free and open source under the Apache License, Version 2.0.
Use Apache Cordova if you are:
a mobile developer and want to extend an application across more than one platform, without having to re-implement it with each platform's language and tool set.
a web developer and want to deploy a web app that's packaged for distribution in various app store portals.
a mobile developer interested in mixing native application components with a WebView (special browser window) that can access device-level APIs, or if you want to develop a plugin interface between native and WebView components.
Basic Components
Apache Cordova applications rely on a common config.xml file that provides information about the app and specifies parameters affecting how it works, such as whether it responds to orientation shifts.
The application itself is implemented as a web page, by default a local file named index.html, that references whatever CSS, JavaScript, images, media files, or other resources are necessary for it to run. The app executes as a WebView within the native application wrapper, which you distribute to app stores.
The Cordova-enabled WebView may provide the application with its entire user interface. On some platforms, it can also be a component within a larger, hybrid application that mixes the WebView with native application components.
A plugin interface is available for Cordova and native components to communicate with each other. This enables you to invoke native code from JavaScript. Ideally, the JavaScript APIs to that native code are consistent across multiple device platforms. As of version 3.0, plugins provide bindings to standard device APIs. Third-party plugins provide additional bindings to features not necessarily available on all platforms. You can find these third-party plugins in the plugin registry and use them in your application. You can also develop your own plugins. Plugins may be necessary, for example, to communicate between Cordova and custom native components.
NOTE: As of version 3.0, when you create a Cordova project it does not have any plugins present. This is the new default behavior. Any plugins you desire, even the core plugins, must be explicitly added.
Cordova does not provide any UI widgets or MV* frameworks. Cordova provides only the runtime in which those can execute. If you wish to use UI widgets and/or an MV* framework, you will need to select those and include them in your application yourself as third-party material.
Development Paths
As of version 3.0, you can use two basic workflows to create a mobile app. While you can often use either workflow to accomplish the same task, they each offer advantages:
Cross-platform (CLI) workflow: Use this workflow if you want your app to run on as many different mobile operating systems as possible, with little need for platform-specific development. This workflow centers on the Cordova utility, otherwise known as the Cordova CLI, which was introduced with Cordova 3.0. The CLI is a high-level tool that allows you to build projects for many platforms at once, abstracting away much of the functionality of lower-level shell scripts. The CLI copies a common set of web assets into subdirectories for each mobile platform, makes any necessary configuration changes for each, and runs build scripts to generate application binaries. The CLI also provides a common interface to apply plugins to your app. Unless you have a need for the platform-centered workflow, the cross-platform workflow is recommended.
Platform-centered workflow: Use this workflow if you want to focus on building an app for a single platform and need to be able to modify it at a lower level. You need to use this approach, for example, if you want your app to mix custom native components with web-based Cordova components, as discussed in Embedding WebViews. As a rule of thumb, use this workflow if you need to modify the project within the SDK. This workflow relies on a set of lower-level shell scripts that are tailored for each supported platform, and a separate Plugman utility that allows you to apply plugins. While you can use this workflow to build cross-platform apps, it is generally more difficult because the lack of a higher-level tool means separate build cycles and plugin modifications for each platform. Still, this workflow allows you greater access to development options provided by each SDK, and is essential for complex hybrid apps. See the various Platform Guides for details on each platform's available shell utilities.
When first starting out, it may be easiest to use the cross-platform workflow to create an app. You then have the option to switch to a platform-centered workflow if you need the greater control the SDK provides. Lower-level shell utilities are available in a separate distribution than the CLI. For projects initially generated by the CLI, these shell tools are also available in the project's various platforms/*/cordova directories.
NOTE: Once you switch from the CLI-based workflow to one centered on the platform-specific SDKs and shell tools, you can't go back. The CLI maintains a common set of cross-platform source code, which on each build it uses to write over platform-specific source code. To preserve any modifications you make to the platform-specific assets, you need to switch to the platform-centered shell tools, which ignore the cross-platform source code, and instead relies on the platform-specific source code.
Platform Support
The following shows the set of development tools and device APIs available for each mobile platform. The device APIs listed here are provided by the core plugins, additional APIs are available via third-party plugins. Column headers display the CLI's shorthand names.
Table 1. Table containing development tools and APIs available for each platform
The Command-Line Interface
The Command-Line Interface is a tool that allows you to create new projects, build them on different platforms, and run on real devices or within emulators. The CLI is the main tool to use for the cross-platform workflow described in the Overview. Otherwise you can also use the CLI to initialize project code, then switch to various platforms' SDKs and shell tools for continued development.
Prerequisites
Before running any command-line tools, you need to install SDKs for each platform you wish to target.
To add support or rebuild a project for any platform, you need to run the command-line interface from the same machine that supports the platform's SDK. The CLI supports the following combinations:
iOS (Mac)
Amazon Fire OS (Mac, Linux, Windows)
Android (Mac, Linux, Windows)
BlackBerry 10 (Mac, Linux, Windows)
Windows Phone 8 (Windows)
Windows (Windows)
Firefox OS (Mac, Linux, Windows)
On the Mac, the command-line is available via the Terminal application. On the PC, it's available as Command Prompt under Accessories.
The more likely it is that you run the CLI from different machines, the more it makes sense to maintain a remote source code repository, whose assets you pull down to local working directories.
Installing the Cordova CLI
The Cordova command-line tool is distributed as an npm package in a ready-to-use format. It is not necessary to compile it from source.
To install the cordova command-line tool, follow these steps:
Download and install Node.js. Following installation, you should be able to invoke node and npm on your command line. If desired, you may optionally use a tool such as nvm or nave to manage your Node.js installation.
Download and install a git client, if you don't already have one. Following installation, you should be able to invoke git on your command line. Even though you won't be using git manually, the CLI does use it behind-the-scenes to download some assets when creating a new project.
Install the cordova module using npm utility of Node.js. The cordova module will automatically be downloaded by the npm utility.
`on OS X and Linux:
$ sudo npm install -g cordova
On OS X and Linux, prefixing the npm command with sudo may be necessary to install this development utility in otherwise restricted directories such as /usr/local/share. If you are using the optional nvm/nave tool or have write access to the install directory, you may be able to omit the sudo prefix. There are more tips available on using npm without sudo, if you desire to do that.
on Windows:
C:\>npm install -g cordova
The -g flag above tells npm to install cordova globally. Otherwise it will be installed in the node_modules subdirectory of the current working directory.
You may need to add the npm directory to your PATH in order to invoke globally installed npm modules. The installation log may produce errors for any uninstalled platform SDKs.
Following installation, you should be able to run cordova on the command line with no arguments and it should print help text.
Create the App
Go to the directory where you maintain your source code, and run a command such as the following:
$ cordova create hello com.example.hello HelloWorld
It may take some time for the command to complete, so be patient. Running the command with the -d option displays information about its progress.
The first argument hello specifies a directory to be generated for your project. This directory should not already exist, Cordova will create it for you. Its www subdirectory houses your application's home page, along with various resources under css, js, and img, which follow common web development file-naming conventions. These assets will be stored on the device's local filesystem, not served remotely. The config.xml file contains important metadata needed to generate and distribute the application.
The second argument com.example.hello provides your project with a reverse domain-style identifier. This argument is optional, but only if you also omit the third argument, since the arguments are positional. You can edit this value later in the config.xml file, but do be aware that there may be code generated outside of config.xml using this value, such as Java package names. The default value is io.cordova.hellocordova, but it is recommended that you select an appropriate value.
The third argument HelloWorld provides the application's display title. This argument is optional. You can edit this value later in the config.xml file, but do be aware that there may be code generated outside of config.xml using this value, such as Java class names. The default value is HelloCordova, but it is recommended that you select an appropriate value.
Add Platforms
All subsequent commands need to be run within the project's directory, or any subdirectories within its scope: $ cd hello
Before you can build the project, you need to specify a set of target platforms. Your ability to run these commands depends on whether your machine supports each SDK, and whether you have already installed each SDK. Run any of these from a Mac:
$ cordova platform add iOS
$ cordova platform add amazon-fireos
$ cordova platform add android
$ cordova platform add blackberry10
$ cordova platform add firefoxos
Run any of these from a Windows machine, where WP refers to different versions of the Windows Phone operating system:
$ cordova platform add wp8
$ cordova platform add windows
$ cordova platform add amazon-fireos
$ cordova platform add android
$ cordova platform add blackberry10
$ cordova platform add firefoxos
Run this to check your current set of platforms:
$ cordova platforms ls – (Note the platform and platforms commands are synonymous.)
Run either of the following synonymous commands to remove a platform:
$ cordova platform remove blackberry10
$ cordova platform rm amazon-fireos
$ cordova platform rm android
Running commands to add or remove platforms affects the contents of the project's platforms directory, where each specified platform appears as a subdirectory. The www source directory is reproduced within each platform's subdirectory, appearing for example in platforms/ios/www or platforms/android/assets/www. Because the CLI constantly copies over files from the source www folder, you should only edit these files and not the ones located under the platforms subdirectories. If you use version control software, you should add this source www folder, along with the merges folder, to your version control system.
WARNING: When using the CLI to build your application, you should not edit any files in the /platforms/ directory unless you know what you are doing, or if documentation specifies otherwise. The files in this directory are routinely overwritten when preparing applications for building, or when plugins are reinstalled.
If you wish at this point, you can use an SDK such as Eclipse or Xcode to open the project you created. You will need to open the derivative set of assets from the /platforms/ directory to develop with an SDK. This is because the SDK specific metadata files are stored within the appropriate /platform/ subdirectory. Use this approach if you simply want to initialize a project using the CLI and then switch to an SDK for native work.
Build the App
By default, the cordova create script generates a skeletal web-based application whose home page is the project's www/index.html file. Edit this application however you want, but any initialization should be specified as part of the [deviceready] (../../cordova/events/events.deviceready.html) event handler, referenced by default from www/js/index.js.
Run the following command to iteratively build the project:
$ cordova build
This generates platform-specific code within the project's platforms subdirectory. You can optionally limit the scope of each build to specific platforms:
$ cordova build iOS
The cordova build command is a shorthand for the following, which in this example is also targeted to a single platform:
$ cordova prepare iOS
$ cordova compile iOS
In this case, once you run prepare, you can use Apple's Xcode SDK as an alternative to modify and compile the platform-specific code that Cordova generates within platforms/iOS. You can use the same approach with other platforms' SDKs.
Test the App on an Emulator or Device
SDKs for mobile platforms often come bundled with emulators that execute a device image, so that you can launch the app from the home screen and see how it interacts with many platform features. Run a command such as the following to rebuild the app and view it within a specific platform's emulator:
$ cordova emulate android
Some mobile platforms emulate a particular device by default, such as the iPhone for iOS projects. For other platforms, you may need to first associate a device with an emulator. For example, you may first run the android command to launch the Android SDK, then run a particular device image, which launches it according to its default behavior:
Figure 2. Image containing the startup and menu of an android emulator
Following up with the cordova emulate command refreshes the emulator image to display the latest application, which is now available for launch from the home screen:
Figure 3. Image showing the hybrid app opening on an android emulator
Alternately, you can plug the handset into your computer and test the app directly:
$ cordova run android
Before running this command, you need to set up the device for testing, following procedures that vary for each platform. In Android and Amazon Fire OS devices, you would have to enable a USB debugging option on the device, and perhaps add a USB driver depending on your development environment.
Add Plugin Features
When you build and view a new project, the default application that appears doesn't do very much. You can modify the app in many ways to take advantage of standard web technologies, but for the app to communicate closely with various device-level features, you need to add plugins that provide access to core Cordova APIs.
A plugin is a bit of add-on code that provides an interface to native components. You can design your own plugin interface, for example when designing a hybrid app that mixes a Cordova WebView with native components. More commonly, you would add a plugin to enable one of Cordova's basic device-level features detailed in the API Reference.
As of version 3.0, when you create a Cordova project it does not have any plugins present. This is the new default behavior. Any plugins you desire, even the core plugins, must be explicitly added.
A list of these plugins, including additional third-party plugins provided by the community, can be found in the registry at plugins.cordova.io. You can use the CLI to search for plugins from this registry. For example, searching for bar and code produces a single result that matches both terms as case-insensitive substrings:
$ cordova plugin search bar code
com.phonegap.plugins.barcodescanner – Scans Barcodes
Searching for only the bar term yields and additional result:
cordova-plugin-statusbar – Cordova StatusBar Plugin
The cordova plugin add command requires you to specify the repository for the plugin code. Here are examples of how you might use the CLI to add features to the app:
Basic device information (Device API):
$ cordova plugin add cordova-plugin-device
Network Connection and Battery Events:
$ cordova plugin add cordova-plugin-network-information
$ cordova plugin add cordova-plugin-battery-status
NOTE: The CLI adds plugin code as appropriate for each platform. If you want to develop with lower-level shell tools or platform SDKs as discussed in the Overview, you need to run the Plugman utility to add plugins separately for each platform.
Use plugin ls (or plugin list, or plugin by itself) to view currently installed plugins. Each displays by its identifier:
$ cordova plugin ls
[ 'cordova-plugin-console' ]
To remove a plugin, refer to it by the same identifier that appears in the listing. For example, here is how you would remove support for a debug console from a release version:
$ cordova plugin rm cordova-plugin-console
$ cordova plugin remove cordova-plugin-console
You can batch-remove or add plugins by specifying more than one argument for each command:
$ cordova plugin add cordova-plugin-console cordova-plugin-device
Advanced Plugin Options
When adding a plugin, several options allow you to specify from where to fetch the plugin. The examples above use a well-known registry.cordova.io registry, and the plugin is specified by the id:
$ cordova plugin add cordova-plugin-console
The id may also include the plugin's version number, appended after the @ character. The latest version is an alias for the most recent version. For example:
$ cordova plugin add cordova-plugin-console@latest
$ cordova plugin add cordova-plugin-console@0.2.1
If the plugin is not registered at registry.cordova.io but is located in another git repository, you can specify an alternate URL:
$ cordova plugin add https://github.com/apache/cordova-plugin-console.git
The git example above fetches the plugin from the end of the master branch, but an alternate git-ref such as a tag or branch can be appended after a # character:
Install from a tag:
$ cordova plugin add https://github.com/apache/cordova-plugin-console.git#r0.2.0
Or a branch:
$ cordova plugin add https://github.com/apache/cordova-plugin-console.git#CB-8438cordova-plugin-console
Or git-ref could also be a particular commit:
$ cordova plugin add https://github.com/apache/cordova-plugin-console.git#f055daec45575bf08538f885e09c85a0eba363ff
If the plugin (and its plugin.xml file) is in a subdirectory within the git repo, you can specify it with the : character. Note that the # character is still needed:
$ cordova plugin add https://github.com/someone/aplugin.git#:/my/sub/dir
You can also combine both the git-ref and the subdirectory:
$ cordova plugin add https://github.com/someone/aplugin.git#r0.0.1:/my/sub/dir
Alternately, specify a local path to the plugin directory that contains the plugin.xml file:
$ cordova plugin add ../my_plugin_dir
Using merges to Customize Each Platform
While Cordova allows you to easily deploy an app for many different platforms, sometimes you need to add customizations. In that case, you don't want to modify the source files in various www directories within the top-level platforms directory, because they're regularly replaced with the top-level www directory's cross-platform source.
Instead, the top-level merges directory offers a place to specify assets to deploy on specific platforms. Each platform-specific subdirectory within merges mirrors the directory structure of the www source tree, allowing you to override or add files as needed. For example, here is how you might uses merges to boost the default font size for Android and Amazon Fire OS devices:
Edit the www/index.html file, adding a link to an additional CSS file, overrides.css in this case:
<link rel="stylesheet" type="text/css" href="css/overrides.css" />
Optionally create an empty www/css/overrides.css file, which would apply for all non-Android builds, preventing a missing-file error.
Create a css subdirectory within merges/android, then add a corresponding overrides.css file. Specify CSS that overrides the 12-point default font size specified within www/css/index.css, for example:
body { font-size: 14px;}
When you rebuild the project, the Android version features the custom font size, while others remain unchanged.
You can also use merges to add files not present in the original www directory. For example, an app can incorporate a back button graphic into the iOS interface, stored in merges/iOS/img/back_button.png, while the Android version can instead capture [backbutton](../../cordova/events/events.backbutton.html) events from the corresponding hardware button.
Help Commands
Cordova features a couple of global commands, which may help you if you get stuck or experience a problem. The help command displays all available Cordova commands and their syntax:
$ cordova help
$ cordova # same
Additionally, you can get more detailed help on a specific command. For example:
$ cordova run –help
The info command produces a listing of potentially useful details, such as currently installed platforms and plugins, SDK versions for each platform, and versions of the CLI and node.js:
$ cordova info
It both presents the information to screen and captures the output in a local info.txt file.
NOTE: Currently, only details on iOS and Android platforms are available.
Updating Cordova and Your Project
After installing the cordova utility, you can always update it to the latest version by running the following command:
$ sudo npm update -g cordova
Use this syntax to install a specific version:
$ sudo npm install -g cordova@3.1.0-0.2.0
Run cordova -v to see which version is currently running. Run the npm info command for a longer listing that includes the current version along with other available version numbers:
$ npm info cordova
Cordova 3.0 is the first version to support the command-line interface described in this section. If you are updating from a version prior to 3.0, you need to create a new project as described above, then copy the older application's assets into the top-level www directory. Where applicable, further details about upgrading to 3.0 are available in the Platform Guides. Once you upgrade to the cordova command-line interface and use npm update to stay current, the more time-consuming procedures described there are no longer relevant.
Cordova 3.0+ may still require various changes to project-level directory structures and other dependencies. After you run the npm command above to update Cordova itself, you may need to ensure your project's resources conform to the latest version's requirements. Run a command such as the following for each platform you're building:
$ cordova platform update android
$ cordova platform update iOS
Best Practices Cordova app development
SPA Is Your Friend
First and foremost – your Cordova applications should adopt the SPA (Single Page Application) design. Loosely defined, a SPA is a client-side application that is run from one request of a web page. The user loads an initial set of resources (HTML, CSS, and JavaScript) and further updates (showing a new view, loading data) is done via AJAX. SPAs are commonly used for more complex client-side applications. Gmail is a great example of this. After you load Gmail, mail views, editing, and organization are all done by updating the DOM instead of actually leaving the current page to load a completely new one.
Using a SPA can help you organize your application in a more efficient manner, but it also has specific benefits for Cordova applications. A Cordova application must wait for the deviceready event to fire before any plugins may be used. If you do not use a SPA, and your user clicks to go from one page to another, you will have to wait for deviceready to fire again before you make use of a plugin. This is easy to forget as your application gets larger.
Even if you choose not to use Cordova, creating a mobile application without using a single page architecture will have serious performance implications. This is because navigating between pages will require scripts, assets, etc., to be reloaded. Even if these assets are cached, there will still be performance issues. [2]
Angular JS
Figure 4. AngularJS’s logo
What Is Angular? [3]
AngularJS is a structural framework for dynamic web apps. It lets you use HTML as your template language and lets you extend HTML’s syntax to express your application’s components clearly and succinctly. Angular’s data binding and dependency injection eliminate much of the code you would otherwise have to write. And it all happens within the browser, making it an ideal partner with any server technology.
Angular is what HTML would have been, had it been designed for applications. HTML is a great declarative language for static documents. It does not contain much in the way of creating applications, and as a result building web applications is an exercise in what do I have to do to trick the browser into doing what I want?
The impedance mismatch between dynamic applications and static documents is often solved with:
a library – a collection of functions which are useful when writing web apps. Your code is in charge and it calls into the library when it sees fit. E.g., jQuery.
frameworks – a particular implementation of a web application, where your code fills in the details. The framework is in charge and it calls into your code when it needs something app specific. E.g., durandal, ember, etc.
Angular takes another approach. It attempts to minimize the impedance mismatch between document centric HTML and what an application needs by creating new HTML constructs. Angular teaches the browser new syntax through a construct we call directives. Examples include:
Data binding, as in {{}}.
DOM control structures for repeating, showing and hiding DOM fragments.
Support for forms and form validation.
Attaching new behavior to DOM elements, such as DOM event handling.
Grouping of HTML into reusable components.
A complete client-side solution
Angular is not a single piece in the overall puzzle of building the client-side of a web application. It handles all of the DOM and AJAX glue code you once wrote by hand and puts it in a well-defined structure. This makes Angular opinionated about how a CRUD (Create, Read, Update, and Delete) application should be built. But while it is opinionated, it also tries to make sure that its opinion is just a starting point you can easily change. Angular comes with the following out-of-the-box:
Everything you need to build a CRUD app in a cohesive set: Data-binding, basic templating directives, form validation, routing, deep-linking, reusable components and dependency injection.
Testability story: Unit-testing, end-to-end testing, mocks and test harnesses.
Seed application with directory layout and test scripts as a starting point.
Angular’s sweet spot
Angular simplifies application development by presenting a higher level of abstraction to the developer. Like any abstraction, it comes at a cost of flexibility. In other words, not every app is a good fit for Angular. Angular was built with the CRUD application in mind. Luckily CRUD applications represent the majority of web applications. To understand what Angular is good at, though, it helps to understand when an app is not a good fit for Angular.
Games and GUI editors are examples of applications with intensive and tricky DOM manipulation. These kinds of apps are different from CRUD apps, and as a result are probably not a good fit for Angular. In these cases it may be better to use a library with a lower level of abstraction, such as jQuery.
The Zen of Angular
Angular is built around the belief that declarative code is better than imperative when it comes to building UIs and wiring software components together, while imperative code is excellent for expressing business logic.
It is a very good idea to decouple DOM manipulation from app logic. This dramatically improves the testability of the code.
It is a really, really good idea to regard app testing as equal in importance to app writing. Testing difficulty is dramatically affected by the way the code is structured.
It is an excellent idea to decouple the client side of an app from the server side. This allows development work to progress in parallel, and allows for reuse of both sides.
It is very helpful indeed if the framework guides developers through the entire journey of building an app: From designing the UI, through writing the business logic, to testing.
It is always good to make common tasks trivial and difficult tasks possible.
Angular frees you from the following pains:
Registering callbacks: Registering callbacks clutters your code, making it hard to see the forest for the trees. Removing common boilerplate code such as callbacks is a good thing. It vastly reduces the amount of JavaScript coding you have to do, and it makes it easier to see what your application does.
Manipulating HTML DOM programmatically: Manipulating HTML DOM is a cornerstone of AJAX applications, but it’s cumbersome and error-prone. By declaratively describing how the UI should change as your application state changes, you are freed from low-level DOM manipulation tasks. Most applications written with Angular never have to programmatically manipulate the DOM, although you can if you want to.
Marshaling data to and from the UI: CRUD operations make up the majority of AJAX applications’ tasks. The flow of marshaling data from the server to an internal object to an HTML form, allowing users to modify the form, validating the form, displaying validation errors, returning to an internal model, and then back to the server, creates a lot of boilerplate code. Angular eliminates almost all of this boilerplate, leaving code that describes the overall flow of the application rather than all of the implementation details.
Writing tons of initialization code just to get started: Typically you need to write a lot of plumbing just to get a basic “Hello World” AJAX app working. With Angular you can bootstrap your app easily using services, which are auto-injected into your application in a Guice-like dependency-injection style. This allows you to get started developing features quickly. As a bonus, you get full control over the initialization process in automated tests.
Conceptual Overview
Table 2. Table containing the conceptual overview of the framework
A first example: Data binding
In the following example we will build a form to calculate the costs of an invoice in different currencies.
<div ng-app ng-init=”qty=1;cost=2”>
<b>Invoice:</b>
<div>
Quantity: <input type=”number” min=”0” ng-model=”qty”>
</div>
<div>
Costs: <input type=”number” min=”0” ng-model=”cost”>
</div>
<div>
<b>Total:</b> {{qty * cost | currency}}
</div>
</div>
This looks like normal HTML, with some new markup. In Angular, a file like this is called a template. When Angular starts your application, it parses and processes this new markup from the template using the compiler. The loaded, transformed and rendered DOM is then called the view.
The first kind of new markup are the directives. They apply special behavior to attributes or elements in the HTML. In the example above we use the ng-app attribute, which is linked to a directive that automatically initializes our application. Angular also defines a directive for the input element that adds extra behavior to the element. The ng-model directive stores/updates the value of the input field into/from a variable.
Figure 5. Schema showing how the data binding works
Custom directives to access the DOM: In Angular, the only place where an application should access the DOM is within directives. This is important because artifacts that access the DOM are hard to test. If you need to access the DOM directly you should write a custom directive for this.
The second kind of new markup are the double curly braces {{ expression | filter }}: When the compiler encounters this markup, it will replace it with the evaluated value of the markup. An expression in a template is a JavaScript-like code snippet that allows Angular to read and write variables. Note that those variables are not global variables. Just like variables in a JavaScript function live in a scope, Angular provides a scope for the variables accessible to expressions. The values that are stored in variables on the scope are referred to as the model in the rest of the documentation.
The example above also contains a filter. A filter formats the value of an expression for display to the user. In the example above, the filter currency formats a number into an output that looks like money.
The important thing in the example is that Angular provides live bindings: Whenever the input values change, the value of the expressions are automatically recalculated and the DOM is updated with their values. The concept behind this is two-way data binding.
Adding UI logic: Controllers
Let's add some more logic to the example that allows us to enter and calculate the costs in different currencies and also pay the invoice.
angular.module('invoice1', [])
.controller('InvoiceController', function() {
this.qty = 1;
this.cost = 2;
this.inCurr = 'EUR';
this.currencies = ['USD', 'EUR', 'CNY'];
this.usdToForeignRates = {
USD: 1,
EUR: 0.74,
CNY: 6.09
};
this.total = function total(outCurr) {
return this.convertCurrency(this.qty * this.cost, this.inCurr, outCurr);
};
this.convertCurrency = function convertCurrency(amount, inCurr, outCurr) {
return amount * this.usdToForeignRates[outCurr] / this.usdToForeignRates[inCurr];
};
this.pay = function pay() {
window.alert("Thanks!");
};
});
What changed?
First, there is a new JavaScript file that contains a controller. More exactly, the file contains a constructor function that creates the actual controller instance. The purpose of controllers is to expose variables and functionality to expressions and directives.
Besides the new file that contains the controller code we also added an ng-controller directive to the HTML. This directive tells Angular that the new InvoiceController is responsible for the element with the directive and all of the element's children. The syntax InvoiceController as invoice tells Angular to instantiate the controller and save it in the variable invoice in the current scope.
We also changed all expressions in the page to read and write variables within that controller instance by prefixing them with invoice. . The possible currencies are defined in the controller and added to the template using ng-repeat. As the controller contains a total function we are also able to bind the result of that function to the DOM using {{ invoice.total(…) }}.
Again, this binding is live, i.e. the DOM will be automatically updated whenever the result of the function changes. The button to pay the invoice uses the directive ngClick. This will evaluate the corresponding expression whenever the button is clicked.
In the new JavaScript file we are also creating a module at which we register the controller. We will talk about modules in the next section.
The following graphic shows how everything works together after we introduced the controller:
Figure 6. Scheme showing how the connection between the Controller, Scope and the View
View-independent business logic: Services
Right now, the InvoiceController contains all logic of our example. When the application grows it is a good practice to move view-independent logic from the controller into a service, so it can be reused by other parts of the application as well. Later on, we could also change that service to load the exchange rates from the web, e.g. by calling the Yahoo Finance API, without changing the controller.
Let's refactor our example and move the currency conversion into a service in another file:
angular.module('finance2', [])
.factory('currencyConverter', function() {
var currencies = ['USD', 'EUR', 'CNY'];
var usdToForeignRates = {
USD: 1,
EUR: 0.74,
CNY: 6.09
};
var convert = function (amount, inCurr, outCurr) {
return amount * usdToForeignRates[outCurr] / usdToForeignRates[inCurr];
};
return {
currencies: currencies,
convert: convert
};
});
What changed? We moved the convertCurrency function and the definition of the existing currencies into the new file finance2.js. But how does the controller get a hold of the now separated function?
This is where Dependency Injection comes into play. Dependency Injection (DI) is a software design pattern that deals with how objects and functions get created and how they get a hold of their dependencies. Everything within Angular (directives, filters, controllers, services, …) is created and wired using dependency injection. Within Angular, the DI container is called the injector.
To use DI, there needs to be a place where all the things that should work together are registered. In Angular, this is the purpose of the modules. When Angular starts, it will use the configuration of the module with the name defined by the ng-app directive, including the configuration of all modules that this module depends on.
In the example above: The template contains the directive ng-app="invoice2". This tells Angular to use the invoice2 module as the main module for the application. The code snippet angular.module('invoice2', ['finance2']) specifies that the invoice2 module depends on the finance2 module. By this, Angular uses the InvoiceController as well as the currencyConverter service.
Figure 7. Scheme showing how the services work in AngularJS
Angular uses the InvoiceController as well as the currencyConverter service.
Now that Angular knows of all the parts of the application, it needs to create them. In the previous section we saw that controllers are created using a factory function. For services there are multiple ways to define their factory. In the example above, we are using a function that returns the currencyConverter function as the factory for the service.
Back to the initial question: How does the InvoiceController get a reference to the currencyConverter function? In Angular, this is done by simply defining arguments on the constructor function. With this, the injector is able to create the objects in the right order and pass the previously created objects into the factories of the objects that depend on them. In our example, the InvoiceController has an argument named currencyConverter. By this, Angular knows about the dependency between the controller and the service and calls the controller with the service instance as argument.
The last thing that changed in the example between the previous section and this section is that we now pass an array to the module.controller function, instead of a plain function. The array first contains the names of the service dependencies that the controller needs. The last entry in the array is the controller constructor function. Angular uses this array syntax to define the dependencies so that the DI also works after minifying the code, which will most probably rename the argument name of the controller constructor function to something shorter like a. [3]
Ionic
Figure 8. Ionic’s logo
What is Ionic, and where does it fit? [4]
Ionic is an HTML5 mobile app development framework targeted at building hybrid mobile apps. Hybrid apps are essentially small websites running in a browser shell in an app that have access to the native platform layer. Hybrid apps have many benefits over pure native apps, specifically in terms of platform support, speed of development, and access to 3rd party code.
Think of Ionic as the front-end UI framework that handles all of the look and feel and UI interactions your app needs in order to be compelling. Kind of like “Bootstrap for Native,” but with support for a broad range of common native mobile components, slick animations, and beautiful design.
Unlike a responsive framework, Ionic comes with very native-styled mobile UI elements and layouts that you’d get with a native SDK on iOS or Android but didn’t really exist before on the web. Ionic also gives you some opinionated but powerful ways to build mobile applications that eclipse existing HTML5 development frameworks.
Since Ionic is an HTML5 framework, it needs a native wrapper like Cordova or PhoneGap in order to run as a native app. We strongly recommend using Cordova proper for your apps, and the Ionic tools will use Cordova underneath.
Building Hybrid Apps with Ionic
Those familiar with web development will find the structure of an Ionic app straightforward. At its core, it’s just a web page running in a native app shell! That means we can use any kind of HTML, CSS, and JavaScript we want. The only difference is, instead of creating a website that others will link to, we are building a self-contained application experience.
The bulk of an Ionic app will be written in HTML, JavaScript, and CSS. Eager developers might also dig down into the native layer with custom Cordova plugins or native code, but it’s not necessary to get a great app.
Ionic also uses AngularJS for a lot of the core functionality of the framework. While you can still use Ionic with just the CSS portion, we recommend investing in Angular as it’s one of the best ways to build browser-based applications today.
Installation
Platform notes
First, we need to start with a note about minimum requirements for building your app with the current release of Ionic. Ionic targets iPhone and Android devices (currently). We support iOS 6+, and Android 4.0+. However, since there are a lot of different Android devices, it’s possible certain ones might not work. As always, we are looking for help testing and improving our device compatibility and would love help from the community on our GitHub project.
You can develop Ionic apps on any operating system you prefer. In fact, Ionic has been developed at various times on Mac OS X, Linux, and Windows. However, right now you’ll need to use the command line in order to follow this guide and you must have OS X in order to develop and deploy iPhone apps, so OS X is recommended if possible.
If you are on Windows, make sure to download and install Git for Windows and optionally Console2. You will be executing any commands in this guide in the Git Bash or Console2 windows.
First, we will go and install the most recent version of Apache Cordova, which will take our app and bundle it into a native wrapper to turn it into a traditional native app.
Install Ionic
Ionic comes with a convenient command line utility to start, build, and package Ionic apps.
To install it, simply run:
$ sudo npm install -g ionic
Create the project
Now, we need to create a new Cordova project somewhere on the computer for the code for our app:
$ ionic start todo blank
That will create a folder called todo in the directory the command was run. Next, we will go into that directory and list the contents. Here is what the outer structure of your Ionic project will look like:
$ cd todo && ls
├── bower.json // bower dependencies
├── config.xml // cordova configuration
├── gulpfile.js // gulp tasks
├── hooks // custom cordova hooks to execute on specific commands
├── ionic.project // ionic configuration
├── package.json // node dependencies
├── platforms // iOS/Android specific builds will reside here
├── plugins // where your cordova/ionic plugins will be installed
├── scss // scss code, which will output to www/css/
└── www // application – JS code and libs, CSS, images, etc.
If you are planning on using any version control system, you can go ahead and set it up in this new folder.
Configure Platforms
Now, we need to tell ionic that we want to enable the iOS and Android platforms
$ ionic platform add iOS
$ ionic platform add android [4]
GoPro
Figure 9. GoPro’s logo
What is GoPro? [5]
The GoPro is more than a camera, it is an idea that can create many other ideas, hence, the GoPro movement and its large following; making it the highest selling brand of cameras.
GoPro is the action camera of choice as it is lightweight, compact, and mountable. The GoPro camera can capture still photos and video in high-definition through wide-angle lens while being remotely controlled or configured to work automatically.
It is often used in extreme action video photography. In fact, the GoPro was founded by Nick Woodman as a result of the problem he faced capturing photos of himself surfing. At the initial stages of starting the GoPro company, Woodman was selling sea shell necklaces, belts, and fashionable camera straps that he bought on his travels to Asia out of his Volkswagen van on the Californian coast to make enough money. In 2004, the company sold its first camera (which used 35mm film). A decade later, in 2014, GoPro is now selling fixed-lens high-definition video cameras with a wide 170 degree angle which can be used to create 3D videos by pairing two or more cameras together.
There are several models of GoPro cameras on the market. The camera that I used is the GoPro Hero 3+ Black Edition. The specifications for the camera are the following:
Videos Resolution
Table 3. Table containing all the resolutions, framerates and fields of view for video mode
Photos Resolution
Table 4. Table containing all the resolutions and fields of view for photo mode.
Continuous Photo
Table 5. Table containing the number of photos per second for Continuous Photo mode.
Burst
Table 6. Table containing all the configurations possible for Burst mode.
[5]
GoPro App
Figure 10. Image showing the home view of the GoPro App
Purpose
The purpose of this project was to create a hybrid mobile application that can connect to a GoPro and take control of the device.
Frameworks
In the development process of this application, there were three frameworks used:
Cordova
AngularJS
Ionic
Cordova
Cordova is mobile development framework that allows us to use standard web development technologies, such as JavaScript, CSS3, and HTML5 for developing hybrid, cross-platform applications. By doing this we can avoid using the native development languages for each platform, in my case, not having to learn three different programming languages.
This framework is capable of taking a web application, developed with the standard technologies enumerated above and wrap them over native programming languages giving access to a certain device’s sensors and data.
AngularJS
AngularJS is a framework used for dynamic web applications. It offers us tools that can help us create a Single Page Application (SPA). SPAs are web application built in such way, that only the views are changing within the app itself and not the pages. This makes the app run much faster.
Ionic
Ionic is a HTML5 framework that helps us create a hybrid application. The framework itself takes care of the GUI of the application. It offers us lots and lots of components made to look like native components for each platform (buttons, tabs, toggle switches, etc.), but not only that, it also offers the application the feel of the platform we are using.
Ionic offers us some new and advanced ways of building the application. Using different commands, we are able to build applications ready to be published, or debug applications. However, Ionic cannot build application by itself, it needs a framework like Cordova to help wrap the code over native programming language.
GoPro
The GoPro Hero 3+ Black Edition, is an amazing little action camera, capable of recording incredible videos at very high resolutions and framerates. Weighting only 135 grams, this camera can be located in many different places, from where it can record amazing videos.
This camera creates its own Wi-Fi network to which you can connect with a special remote designed especially for it, or with any device that has a wireless network adapter.
The GoPro Remote, has the ability to reproduce everything you see on the device’s display. This has two buttons, just like the GoPro, one that changes the selection and one that selects the option you want.
Figure 11. GoPro Remote
About the app
Once you turn on the Wi-Fi on you camera and set it for GoPro App, it transform itself into a HTTP server, giving us access to all the photos and videos that we took. The IP address of the GoPro is 10.5.5.9 and the port is 8080.
Once you connect to your GoPro by pushing the Connect button on the first page of the application, you will find yourself on the home page of the app. Here you will find 4 buttons:
Power
Preview
Media
Settings
Power
This button turns your GoPro on and off by sending a HTTP request to verify its status. If the request returns an error, it means that the camera is off and it powers it on, if not, it will power it off.
$scope.power = function () {
$http.get("http://10.5.5.9/camera/PV?t=123456789&p=%02")
.success(goProON(), goProOFF());
};
var goProON = function () {
$http.get("http://10.5.5.9/bacpac/PW?t=123456789&p=%01");
};
var goProOFF = function () {
$http.get("http://10.5.5.9/bacpac/PW?t=123456789&p=%00");
};
Preview
The preview button opens a view, where we can find a preview player. This preview window is a work in progress and it currently only works on android and iOS. This live feed is not meant for live preview (as a video), it was meant for the user to create an idea about where the GoPro is pointing. This feature is going to be upgraded in the future.
Beneath this preview player, there are four buttons:
Capture
Mode
Media
Settings
The capture button, does what it says, it triggers the shutter. It is done simply with a HTTP request: $http.get("http://10.5.5.9/bacpac/SH?t=123456789&p=%01");
The mode button, opens a modal window, which is populated with four entries (Video, Photo, Burst and Time Lapse). The capture mode is switched through the following HTTP request: $http.get("http://10.5.5.9/camera/CM?t=123456789&p=%" + value);. The value variable is set to either 00, 01, 02 or 03, depending on which mode did you chose:
$scope.sendModeToGoPro = function (param) {
var value = "00";
if (param === "video") {
value = "00";
} else if (param === "photo") {
value = "01";
} else if (param === "burst") {
value = "02";
} else if (param === "timelapse") {
value = "03";
}
$http.get("http://10.5.5.9/camera/CM?t=123456789&p=%" + value);
$scope.closeModal();
};
The media button, opens a view containing two tabs (photos and videos). By default, on each tab, are displayed the first fifty photos and videos, for performance purposes. The rest of the files will be added later after you scroll to the bottom of the list. The only way I could get a list with all the files that we have on the GoPro is by sending a HTTP request with the following URL to the server: $http.get("http://10.5.5.9:8080/DCIM/102GOPRO/");. This request returns some HTML code that contains the names of the files. I’ve made an algorithm that searches through this code and adds the names of the photos to an array and the names of videos to another one. I then use these arrays to compose two lists: one for photos and one for videos.
getMedia : function (rows) {
var content = res;
if (content) {
var photoCounter = 0;
var photosStop = false;
var videoCounter = 0;
var videosStop = false;
while(((content.indexOf('.JPG"') !== -1) || (content.indexOf('.MP4"') !== -1)) && !photosStop && !videosStop) {
var photoEnd = content.indexOf('.JPG"');
var videoEnd = content.indexOf('.MP4"');
if (rows !== 0 && photosArray.length === rows) {
photosStop = true;
}
if (rows !== 0 && videosArray.length === rows) {
videosStop = true;
}
if (photoEnd >= 0 && videoEnd >=0) {
if (photoEnd < videoEnd && !photosStop) {
var photoStart = photoEnd-8;
photosArray[photoCounter] = content.substring(photoStart, photoEnd);
content = content.slice(photoEnd+1);
photoCounter++;
} else if (!videosStop) {
var videoStart = videoEnd – 8;
videosArray[videoCounter] = content.substring(videoStart, videoEnd);
content = content.slice(videoEnd + 1);
videoCounter++;
}
} else if (photoEnd >= 0 && videoEnd < 0 && !photosStop) {
var photoStart = photoEnd-8;
photosArray[photoCounter] = content.substring(photoStart, photoEnd);
content = content.slice(photoEnd+1);
photoCounter++;
} else if (photoEnd < 0 && videoEnd >= 0 && !videosStop) {
var videoStart = videoEnd – 8;
videosArray[videoCounter] = content.substring(videoStart, videoEnd);
content = content.slice(videoEnd + 1);
videoCounter++;
}
}
}
});
}
After all the media has been loaded, you can press on any item in the list and the view will change again, to a detail view were you will be able to see the photo or video that you selected and its name. Note that not all videos can be played, only videos recorded at certain resolutions and framerates can be played.
The settings button, opens a view containing all the settings you can set to your GoPro. These settings goes from resolution, to frames per second, to field of view, etc.
Figure 12. Image showing the Preview view of the GoPro App
The last two buttons described above (Media and Settings), can be found on the home page as well. These views are the same and have the same functionality.
Things that will be upgraded in the future
There are a couple of features that I plan to develop further:
Live feed
Download and share media
Delete photos and videos
Advanced settings
Windows Phone compatibility for all features
Live feed
I want to make the live feed send a more fluid image. This means implementing or using a new video player plugin.
Download and share media
Once you tap on an image or video from the list, the app takes you to their detail view. In this view should be available more information about the file, as well as three buttons (Download, Share and Delete).
Delete photos and videos
In the settings view there will be two new buttons available: one button that deletes the last photo or video taken and one button that deletes all files from the SD card.
Advanced settings
There are still a couple of settings that are missing from the app (Upside down, Protune which comes with lots of other settings that allows you to control the image quality, etc.).
Windows Phone Compatibility
Windows Phone is an OS which isn’t very popular yet, so the Cordova and Ionic frameworks does not support Windows Phone 100%. Because of that there still are a couple of features missing from the app. I plan on making all of these feature available for this platform as well as the ones described above.
Bibliography
[1] – http://www.mobiloud.com/blog/2012/06/native-web-or-hybrid-apps/
[2] – https://cordova.apache.org/docs/en/latest/guide/overview/index.html#link-1
[3] – https://docs.angularjs.org/guide/introduction
[4] – http://ionicframework.com/docs/guide/preface.html
[5] – http://gopro.com/support/product-manuals-support
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Gopro App (ID: 115946)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
