A Mobile App with Offline Maps using Titanium

Written by Tim Varney on . Posted in App Dev, Mobile

This past week I was presented with a typical request, but with an unusual twist.  I needed to create a Titanium mobile app which features custom raster and vector layers.  The challenge: the map had to be available when the end user was not connected to the Internet.

Titanium’s implementation of the Ti.Map object doesn’t support offline maps, so I knew right away that I’d have to find a third party solution.  I’m not an Objective C or Java programmer, so writing a custom module was out of the question.  That left me one option.  I needed to find a JavaScript mapping library which I could present in a webview.

During my research, I came across a blog post that mirrored what I wanted to do.  Scott Sheri had created an offline map mobile app using PhoneGap, Leaflet and TileMill which was very similar to what I wanted to accomplish.  Seeing how Scott had blazed the trail for me, I decided to follow his path, only using Titanium instead of PhoneGap.  I knew there would be a lot of differences in implementation, but it gave me a strong starting point.

Generating the Raster Images with TileMill

Years ago, I spent a lot of time working with GIS data, so I have a very strong understanding of how to produce and display spatial data.  I chose TileMill to produce my raster layer because it was easy use and readily saved the images in the mbtiles format.  The beauty of this is that an .mbtiles file is nothing more than a SQLite database.  I could imbed my generated .mbtiles in my application and query it natively using Titanium.

Pay no attention to my horrible choice of colors.  I won’t go into details about how I produced this map.  TileMill has some pretty good tutorials on their website.  Needless to say, what we’re concerned about here is how it’s formatted when it’s exported.

The mbtiles files produced by TileMill are simple SQLite databases.  The schema can be found on the MapBox website.  To view the data within the file, I’m using SQLite Manager add-on for Firefox.

Now that we have our raster layer, we can work on getting Leaflet to work in a Titanium webview.

Using Leaflet in a Titanium Webview

This was relatively simple.  I created an HTML page which included all of the JavaScript needed to produce a Leaflet map.  I then took the two Leaflet source files (leaflet.js and leaflet.css) and included them in the Titanium /Resources/ directory to allow it to run offline.  I then created a Titanium webview to display the page.  Quite quickly I had Leaflet up and running in Titanium.

Extending Leaflet to Utilize a SQLite .mbtiles Database

Leaflet doesn’t support .mbtiles out of the box.  The good news is that because Leaflet is open-source and well documented, it was possible to extend its functionality.  I extended L.TileLayer to create a new JavaScript constructor for adding mbtile layers.  The new constructor is L.TileLayer.MBTiles.

L.TileLayer was intended to add raster layers where the images are server by a tile server with a standard URL format.  (For example, http://{s}.tile.cloudmade.com/[API-key]/997/256/{z}/{x}/{y}.png.)  It was going to be necessary to modify this so that the images would instead be drawn from a BLOB field in the .mbtiles SQLite database.

This is where my implementation had to differ from Scott Sheri’s.  Because Scott was using PhoneGap, he queried the .mbtiles database using a SQLite plugin.  With Titanium, I have native database functionality and would be using that instead.  The big hurtle was that the main Titanium app and the webview are in different JavaScript contexts and I would have to pass information between the two using the Ti.App.addEventListener() and Ti.App.fireEvent() methods.  The fireEvent() method is not asynchronous and does not allow for a callback function.

I overrode three of the L.TileLayer methods (_loadTile(), _createTile(), and _addTilesFromCenterOut()) and added one new method (_onLoad).

  • _createTile() – Originally, the Leaflet tiles (which are simply img html elements) didn’t have an id attribute that I could reference.  This was going to be a necessity because the fireEvent() and addEventListener() methods are not asynchronous.  I was going to have to reference the tile by id when the Titanium response for a request for a tile was returned.  I simply created a random guid and set it as the id.
  • _loadTile – I removed the setting of the tile’s src attribute in this method.  I placed the relevant information needed for requesting tiles (i.e. x, y, z, and id) in an array named aUpdate.  When loaded, the map will consist of blank tiles and they will be populated by Titanium through a later request.
  • _addTilesFromCenterOut() – Leaflet uses a document fragment to load the img tiles to the DOM.  I had to wait until this document fragment was added before I could send the request to Titanium to query for the actual image data.  At the end of this method, I just added a call to _onLoad().
  • _onLoad() – This new method will fire once the blank map tiles are added to the DOM.  It calls a Titanium application level event named getMbTiles.  It passes a JSON form of the aUpdates array.

The getMbTiles event triggers the query of the database for the needed tiles.

SELECT tile_data
FROM images
INNER JOIN map ON images.tile_id = map.tile_id
WHERE zoom_level = ?
AND tile_column = ?
AND tile_row = ?

These tiles are then base64 encoded and sent back to the webview using a custom event named receiveTileUrl.  receiveTileUrl sets the src of the various tiles to the appropriate image data.

Source Files

Leaflet Demo  (does not include mbtiles file) .zip

MasterView.js

map.html

The Offline Map!

Ta-da!  The images are now shown on the Leaflet map imbedded in a Titanium webview.  By turning on airplane mode will show that all the data and code is hosted locally and that no Internet connection is required to use this map.

Next Steps

Now, this is just a proof-of-concept and is not production ready.  The current obstacle is the size of the .mbtiles file.  My simple demonstration map was about 4mb and contained very little visual data.  A more robust raster layer can easily exceed the 50mb limit imposed by the Apple App Store.  A strategy needs to be developed where the end user can pick and choose what data they will need in the field and download it accordingly through the app.

But that’s another blog entry…

HTML5 & < Video>

Written by jbriccetti on . Posted in App Dev, Misc Ramblings, Mobile, Strategy

Why Now?

At the crossroads of today’s internet experience, we see a convergence of html5, social media, video and a multitude of web enabled devices. The day for all these elements has come  and they are all, equally affecting the web of tomorrow.

The internet has brought us a culture transformation, away from the world of “restrictive” business and social models. Think about real estate & media moguls – giants who monitized information via exclusive rights and limited access – these industries are nothing like they once were. Today, easy discovery, unlimited access and free distribution are the underlying principles of the “inclusive mindset” that closes the gap between content and audience.

HTML5 <video> tag brings a much needed standard to the web. But more importantly it is the opportunity for moving pictures to have it’s heyday on the internet. The benefits?

  • A broader reach: 50%+ of all internet traffic is video; 60%+ of all mobile data is video. 
  • Mega-stickiness: video shows the full range of human emotion and context, the result of which is better communication & faster calls to action.
  • Better content, better context: relatedness via metadata and transparent content density improves the quality of discovery; “Deeper” content, faster and easier.
  • Viral distribution: Social media “pushes” make discovery easier – we no longer have to find content, it find us. Brightcove reports that it’s 2nd biggest referrer of video content is Facebook.

Timing is everything. The success of social media,  the expectations of html5 standards, the proliferation of devices have converged at a time when a new, open mindset creates opportunity like never before. Video is ripe on the vine.

Strategy

Creating and managing optimized video content is critical; Video content production is different than authoring text content. Social media goals are to raise awareness and leverage viral distribution. Core content is for engagement and information distribution. Managing metadata and creating “relatedness” are critical elements of a successful game plan.

Distribution strategy is multifaceted. Viral distribution is powerful yet uncontrollable. Managed syndication via MRSS or syndication partnerships improves reach even further and with more controls. Both vehicles improve inbound links and drive better SEO.

Often overlooked, Analytics is as important as any other part of your strategy. Without metrics for engagement, distribution, content and device support, you have no idea where your successes and failures reside.

Finally, player ubiquity is the most important technical piece of the strategic puzzle. <html5> brings us the hope of a future emerging standards. File formats (codecs) and device support is far from standardized. Much like the browser wars of 2001, 10 years later we are seeing the device wars play out, especially in the video space. Your technical solution must address all devices to fully leverage all that video has to offer.

Some interesting statistics:

  • The average web user watched 75% more video in 2010 than in 2008
  • By 30 seconds into an online video up to 33% of viewers have moved on; at 1 minute 44% have left (regardless of the clip’s length) and almost 60% have abandoned by the 2 minute mark. [source]
  • More than 16 Million mobile users in the U.S. watched TV or video on their mobile phone in Q2, 2011
  • Every second, 1 million minutes of video content will cross global IP networks in 2015. That would take a person 5 years to watch. [source]

Myth-busting html5 <video>

 The Promise

  • No fragmentation – higher success factor with scalable, manageable solutions
  • No need for plugins, 3rd party tools or proprietary solutions.
  • Better performance – native functionality
  • More culturally aligned with the web – open & free standards

The Reality

  • The functionality is standardized, the implementation isn’t
  • War of the codec standards
  • Reliance on Plugins (Flash) for fallback

Implementation

  • Make one version of your video in WebM (VP8+Vorbis)
  • Make another version in H.264 +AAC audio in an mp4 container
  • Make a third version in theora + Vorbis in an ogg container
  • <video> embed with a fallback on flash

Why Bother?

  • Devices. If you care at all about reaching the mobile marketplace, html5 video is a must.
  • Lead, don’t follow –  be a part of setting the standard. The sooner you get started, the better off you’ll be when it matures.
  • Potential – html5 <video> is where flash was 10 years ago – on the precipice of explosive growth.
  • It’s worth it – any bumps are outweighed by video’s extended reach.
  • SaaS Solutions – you don’t have to DIY.

Resources:

Example using VideoJS Plugin for wordpress:

All i had to do was add the code like this (it doesn’t matter if you enter it in using visual or html mode, either way the plugin picks it up:

 [ video mp4="http://video-js.zencoder.com/oceans-clip.mp4" ogg="http://video-js.zencoder.com/oceans-clip.ogg" webm="http://video-js.zencoder.com/oceans-clip.webm" poster="http://video-js.zencoder.com/oceans-clip.png" preload="true" width="640" height="264" ]

 

Deploying Beta Test Apps to iPhones+

Written by Anthony DeBonis on . Posted in App Dev, Misc Ramblings, Mobile

After you have developed your mobile application you want to test it out on real devices with real testers, both Android and Apple let you run provisioned ad-hoc version of your application. On Android devices its usually as easy as connection your USB cable and running a command from the command line/terminal or have your tool run a deploy for you.  For iOS devices it can take some extra steps to share your ipa install file around, have your testers drag it into iTunes then trigger synch with the device and this has to happen with each beta release.  We found this workflow cumbersome and looked for a better way.  We found it with testflightapp.com – a free online service that makes distribution of your iOS apps easy and comes with some other helpful features.

Once you have an account you can upload a build, be sure to always update the version number or you will get prompted to make a decision on whether to force an update using the old version number.  The service allows you to enter in release notes which are great for the testers and for general tracking of releases and features.  The system easily tracks multiple project application and test teams for distribution.  With each deploy you can choose which team or user will get a notification of the new application version.  The test end user does need to install the TestFlightApp iOS app from the AppStore or follow the link off the email/website.  It’s a basic app that handles the install of your latest version of the app on the device.  The test users can reply to the test email with comments and those comments will be added to the running comments for that version.  You still have to create a signing certificate and provisioning file with specific devices listed, this is done up on the Apple Developer portal – so you will still need to pay for a developer license. When you invite a tester  to install your beta app you receive notification from their device with its serial number uuid that you will need to create the provisioning file, so there is still some hoops to jump through but this service smoothes it all out nicely with a very clean UI.

Side note – this works with the iPhone, iPad and iPod Touch devices – I wish we could deploy our Android beta versions of our applications this way too…. maybe in a future version of TestFlightApp….