Blog

    Happenings and acts of geekery.

Mobile app for the 2013 Ivy+ Annual Fund Conference

We have heard a lot of positive feedback on the mobile app we built for the attendees of the 2013 Ivy Plus Annual Fund conference hosted by Cornell University this week. We are happy to help!

Released for iOS, Android, and mobile web users, the app offers up-to-the-minute schedule information, an attendee listing, and "the Stream" - a combined twitter and in-app message feed. One feature that attendees won't see but will appreciate is the ability for the app to function even when the network isn't available.

The app is integrated with Cornell Connect (using the Harris Connect REST API) to pull both schedule and attendee information over for display. A separate mobile app admin console manages any on-site registration needs, schedule updates, broadcast announcements, and most importantly check in activity.

Tracking who has actually showed up for the event is as simple as a search and a touch for the welcome desk staff using the check in feature. It's turned off for this event, but the app does have the ability to inject "so-and-so just checked in!" messages to the Stream too.

And of course, no app is complete without a dashboard - ours shows the 'hot spots' of content and gives us a good idea of which platforms we should target for future projects. The mix does shift from one group to the next - far more than we ever expected.

If you think an app like this would be useful for your alumni or professional group event, please drop Steve a note. We'll be happy to demo everything for you and discuss the various options available to you.

Cornell Mobile App Using the Harris Connect API

Last January we released a mobile app for the Cornell Alumni Leadership Conference that was extremely well received by alumni and staff alike. The app (CALC 2012 iOS | CALC 2012 Android | CALC 2012 Mobile Web) featured the conference schedule, session surveys, attendee listing, and "the Stream" - an aggregation of tweets and attendee-shared messages in one consolidated conversation view. The app was heavily used by about a third of the attendees.

The 2013 version of the app was designed to meet three major objectives: integrate with registration, improve responsiveness, and overhaul the user interface. Here are the resulting apps: CALC 2013 iOS | CALC 2013 Android | CALC 2013 Mobile Web.

Integration with Harris Connect

Last year we employed the usual lowest common denominator approach to integration: spreadsheets. That introduced a whole host of issues including timeliness of data, proper formatting of the sheet itself, and adding another human to the data transfer process. We knew we had to do better this year because we really wanted to highlight the sessions that people had registered for in the conference agenda. Extracting relational information like that in spreadsheet form wasn't going to end well.

Cornell uses the Harris Connect system for their alumni online community and event management needs. Recently Harris annouced beta availability of their OpenAPI that would allow us to get access to the registration data automatically. A "beta" label doesn't scare us, so we plowed right ahead with it thanks to the help of the ever-awesome Kim Barrett (Cornell Connect project manager), Eric Slosson (Harris Client Relations Manager), and Irwin Horowitz (Harris Technical Architect).

Much to our delight the API allows us to retrieve the data in XML or JSON format - JSON please! A couple quick hours of work and we we're all set. The process of loading and checking the attendee and schedule data went from several hours to just a couple minutes, eliminating all timeliness, formatting, and human factors in the process. Now that we have the integration components built we can very quickly build mobile apps for other Cornell (and other Harris user) events very quickly (and cost effectively)!

What did we do with this data? The app has a session bookmarking feature that we were able to preload for every attendee. We used those bookmarks to also show the next session the attendee was scheduled to attend on the home screen of the app.

Improve Responsiveness

The CALC app caches a lot of data locally so that key information is accessible to the attendee no matter what kind of data coverage the event venue has. This approach requires us to think carefully about how we load, store, and refresh that data on the device.

One thing we are never particularly happy about is any noticeable delay between user interaction and an update on the screen. We use PhoneGap and jQuery Mobile for our applications, which means our apps are essentially browser-based within a native wrapper. As a consequence, we're heavily dependent on the performance of the mobile device browser and its javascript engine. We invested a considerable amount of research time testing and timing several possible solutions for the "touch delay" on both old and new devices on both Android and iOS. In addition, we reevaluated the use of jQuery Mobile (which survived the cut!) and our client-side templating solution (which was moved from the comatose jQuery Templates project to Handlebars). Adam also built a much improved read-through cache mechanism reducing both data traffic (good for battery life) and rendering time. The result was a much faster appliation that felt closer to native than the 2012 edition - with the added benefit of being supported by a cleaner, more modular codebase.

Overhaul the Interface

Last but certainly not least we wanted to break free of the stock-standard "this is supposed to look like an iOS application" default look and feel that jQuery Mobile provides out of the box. From the first sketch to the final implementation we wanted to make the first screen to be both useful for information delivery and simple to "fat finger" your way around.

We also dropped most of the jQuery Mobile list views and replaced them with leaner, meaner HTML and CSS, wrapped in the really nice pull-to-refresh iscroll plugin. Not only was this a nice usability improvement, but it also gave us better rendering performance.

In Conclusion...

We met the three objectives, building a much-improved core under a better performing user interface that was used by even more attendees than last year. Our admin dashboard told us so in real time!

PhoneGap 1.x, Google Analytics, and XCode 4.2

So I was working on a PhoneGap app for the Lehigh/Lafayette Challenge and realized it might be wise to include an analytics package so we'd have something to work from for next year. A quick Google search yielded me this blog post on including Google Analytics in a PhoneGap app.

The problem is, the instructions are outdated...and the package docs on github are also out of date. Commence headdesk. Bang. I don't know the first thing about Xcode or Objective-C, so this was quite an adventure!

Here's what you need to do to use this in an iOS PhoneGap app (jQueryMobile 1.0RC2, PhoneGap 1.1, Xcode 4.2) so that the plugin works with the PhoneGap 1.x plugin architecture. Guaranteed to work as of right this second with these versions. I'm sure it'll break again soon :-)

  • Go get the code from the PurpleCabbage Github site
  • Drop GANTracker.h, GoogleAnalyticsPlugin.h, GoogleAnalyticsPlugin.m, and libGoogleAnalytics.a in the Plugins folder in your Xcode project. Right click on Plugins, Add Files to , select 'em, make sure "Copy items into.." is selected, and click "Add".
  • Modify GoogleAnalyticsPlugin.h to comply with the new plugin architecture
  • /* OLD VERSION - will not work */
    #import <Foundation/Foundation.h>
    #import "PhoneGapCommand.h"
    #import "GANTracker.h"

    @interface GoogleAnalyticsPlugin : PhoneGapCommand<GANTrackerDelegate> {

    }

    /* Replace all of that with this */
    #import <Foundation/Foundation.h>

    #ifdef PHONEGAP_FRAMEWORK
    #import <PhoneGap/PGPlugin.h>
    #import <PhoneGap/NSData+Base64.h>
    #import <PhoneGap/JSON.h>
    #else
    #import "PGPlugin.h"
    #import "NSData+Base64.h"
    #import "JSON.h"
    #endif

    #import "GANTracker.h"

    @interface GoogleAnalyticsPlugin : PGPlugin<GANTrackerDelegate> {

    }

  • Drop the GoogleAnalyticsPlugin.js file in the www folder for your project. I put my stuff in a subdirectory (assets/js) just to keep things neat.
  • Don't forget to include it in index.html with a script tag!
  • <!-- google analytics -->
       <script type="text/javascript" charset="utf-8" src="assets/js/GoogleAnalyticsPlugin.js"></script>
  • Now setup your app startup scripts to initialize the GA code too
  • /* Wait for PhoneGap to connect with the device */
    function onLoad() {
    document.addEventListener("deviceready", onDeviceReady, false);
    }

    /* PhoneGap is ready to be used! */
    function onDeviceReady() {
    window.plugins.googleAnalyticsPlugin.startTrackerWithAccountID("UA-YOUR-GOOGLE-SITE-CODE");
    /* i like to throw a startup event in there just to know how many launches we get */
    window.plugins.googleAnalyticsPlugin.trackPageview("startup");
    /* other startup code here */
    }
  • You'll probably also want to track every jQuery Mobile "page" view too. I just hooked in to the 'pageshow' event. You can track pageviews (which I'm clearly faking here) and "events" (better explained here).
  • $(document).ready(function(){   
       /* track page views */
       $('div').live('pageshow', function(event, ui){
          var pagename = $(this).attr('id');
          window.plugins.googleAnalyticsPlugin.trackPageview(pagename);
          return true;
       });
    });
  • This will save you some hair pulling: the Android PG/GA plugin uses a js method named "trackPageView". The iOS version is named "trackPageview". Yeah...case sensitivity strikes again. Save yourself hours of screaming by watching for that.
  • Now we have to make PhoneGap aware of the plugin. This is the undocumented part.
  • In your /Resources/PROJECTNAME.plist file, open up the Plugins area and add a new item. The name is "googleAnalyticsPlugin" (which is the name of Javascript object). The value is "GoogleAnalyticsPlugin" (which is the name of the Obj-C object). This took a ton of trial and error.
  • Last step: allow the app to reach external hosts. You could list each one individually, but I wildcarded it for this project. Under ExternalHosts in that same PROJECTNAME.plist file, add a line, and set the value to "*". You can see it in the screenshot above.

So from this point forward, you should be able to see pages being logged in Google Analytics from your mobile app. Hope this helps!

PhoneGap, FileTransfer, and ColdFusion

I like PhoneGap. Really. But I bashed my head on this for a while so if this saves you the headache, you're welcome!

The app I am working on uses the Camera API to capture an image and then submits it to a back-end service for inclusion in an online photo gallery. Pretty simple.

When you capture the image, you have two choices for how to handle the data:

Camera.DestinationType.DATA_URL
Camera.DestinationType.FILE_URI

The problem with DATA_URL is that the cameras on mobile devices are getting to be too darn good. That DATA_URL is a Base64 encoded string that can very quickly run you straight out of memory. Therefore, you are strongly encouraged to use FILE_URI instead which is simply a pointer to a file on the device file system.

How do you then get this file moved up to the server? Use the File API's FileTransfer object.

var imageURI = PATH_TO_FILE_AS_GIVEN_BY_CAMERA;

var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
/* ColdFusion barfs if you don't set this */
options.chunkedMode = false;

var params = new Object();
params.formfield1 = 'send other data along for the ride';
   params.formfield2 = 'using more fields like this';

options.params = params;

var ft = new FileTransfer();
ft.upload(imageURI, "http://YOUR_URL_HERE/SOME_FILE.cfm", win, fail, options);
/* don't forget to create functions for win and fail conditions */

The key line here is options.chunkedMode = false;. From what I could tell by reading Ben's blog post , ColdFusion simply can't handle chunked form data. Two hours of searching and evaluating alternatives...and then I noticed this option.

So...lesson learned. Base64 will not only drag your app down but probably crash it as well. FileTransfer (sans chunks) is the way to go.

Fun with Twilio, Part 2 (The Results!)

Last week I wrote up a summary of a project I threw together that leveraged ColdFusion and Twilio to enable the reunion crowd to vote for their favorite performance.

Well, everything went off without a hitch on Saturday! In fact, I spent an hour on Friday night changing how the system worked to cater to both smartphone and "dumbphone" users. I promised a writeup on how it worked and what the results were, so without further delay...

Promotion

We printed up about 1000 stickers - just plain old Avery mailing labels - with two ways to cast your vote. First was via SMS to the number printed on it. The second way was for those "in the know" who understood what a QR code was.

The parade commentators plugged the voting in the warmup before the parade started, between acts and again at the very end. This definitely helped our cause - there was nothing else to pay attention to during those times, so the exclusivity of the promotion really stood out.

We handed out the stickers to as many spectators as we could along with each of the reunion classes while they were lining up for the parade. After a quick explanation of what was at stake (a new award!), some classes eagerly set to work with their phones. They loved that there was something to do while they were waiting for the parade to start.

This was the extent of the promotion. For an app that came together really quickly, there wasn't time to get word out in advance -- and honestly it wasn't necessary. This was a very "event specific" thing that required no prep on the part of the participants.

How It Worked

There are two ways to cast a vote: SMS or using the QR code. The original idea was to use the QR code to launch your text messaging app with the appropriate class year already entered as the body of the message (we'd print unique stickers for each class). You can't do that on iOS - only Android. We then realized that was dumb - if you were going to text, it's easier to just do that rather than fiddle with a barcode reader. There had to be something nicer for the barcode crowd.

So Friday night around 11:30 I sat down with Dreamweaver CS5.5, jQuery Mobile and ColdFusion to toss together a really quick web-based mobile app. One hour later it was skinned, released and running. One hour!

Results

All told, reunion attendance was around 1000 people. There were unregistered spectators and probably some unregistered guests floating around too. Out of this crowd, we collected more than 1200 votes! Roughly a tenth of them were submitted using the mobile app. The URL was not public, so the QR code would be the only (easy) way in. At a couple cents per SMS, this was good, cheap fun - and nothing went wrong.

Lessons Learned

  • PEOPLE LOVE TO PARTICIPATE! Everybody wanted to know the results before they were announced. They were really amused when I pulled out my phone and showed them the graph of results...up to the second
  • QR codes look really scary to people who don't know what they are
  • QR codes CAN be safely dressed up! I took advantage of an excess of error correction code built in to the QR structure and "Fireworks-ed" in the Lehigh shield. It looked less intimidating.
  • Make sure auto refresh was active for your Twilio account (thankfully mine was...though my heart stopped when I got an email in the middle of the parade from them!)
  • The alumni band will, upon finding out they lost, make plans to hack the vote next year. Bring it.
  • Do not send an acknowledgement for every vote - you'll hit a limit pretty quick.
  • Call-to-vote? Entirely possible with Twilio. Might be fun to add it just for fun!

One key enhancement for next time: Screens at the reviewing stand showing the real time voting totals. With ColdFusion, Blaze DS and Flex this is maybe another hour of work.

The Award!

The result was a decisive win for the class of 1976. Their re-enactment of Rocky was entertaining, colorful and energetic...and they certainly weren't shy about voting for themselves!

For their efforts, they were the inaugural winners of the Stephen C. Rittler '99 Reunion Parade Fan Favorite Award!

Mobile Apps for Alumni Engagement Presentation

On Tuesday my colleague Chad Davis and I had the wonderful opportunity to present at the CASE District 2 meeting on the topic of "Your Alumni are Moving onto the Mobile Web. Are You? : Mobile Apps for Alumni Engagement." Chad is an Associate Director in the Lehigh Fund at Lehigh University, responsible for the annual giving efforts of Lehigh's 15 youngest classes, a demographic that is increasingly difficult to maintain contact with through traditional means. Embracing mobile technology appears to us to be an ideal means for connecting with this demographic, so there was plenty for us to collaborate on for this talk.

The session description:

In this session we will boldly go where email, Facebook, Twitter, the alumni website and an online community simply can't: directly into the pockets of alumni.

Mobile devices and near-ubiquitous internet access have made immediate information access not only possible but widespread. A well-designed mobile application will open up new opportunities for alumni to connect with both the institution and each other regardless of where they are at the time -- including solutions for special events and targeted micro-campaigns. We'll talk about the strategic use of the "small screen", location-based services and ideas for their use (home and away venues), and tools for building and supporting these applications.

Chad's case study on the Lehigh/Lafayette Challenge was especially well received. That campaign integrated print, email, Facebook, Twitter (a TON of Twitter) and (most interestingly) "text-to-give" functionality. The results were off the charts (over $14k fundraised in a week, a bunch of first-time donors, amazing buzz) that completely contradicts the thesis of the author of this CASE Currents article (login required) that mobile giving isn't a good fit. Lehigh proved it a success through a consistent, well-messaged, and extremely cost-effective effort.

To those of you who were in attendance, we thank you for choosing our session! We were especially happy to introduce some of you to Angry Birds and sorry for the sleep that you're likely to lose in the coming weeks.

Key takeaways from our talk:

Do not just repurpose what you have

You will not get the installation, utilization and feedback that you expect if all you do is pump RSS into a mobile skin. Make it faster and easier for your alumni to interact with the institution and you'll reap dividends for a very long time.

Everything should prompt an action

An engaging application is one that does things. Your app must be functional in order to be useful and as we discussed, only the truly useful apps find a home on the first screen of your moblie phone. If you're not there, you might as well not exist.

"Mobile app in a box" is a lousy shortcut

Several vendors are offering a single "mobile app in a box" solution that is practically useless when held up against an "actionable" standard. I see the attraction - "yes, we're now mobile!" - but the app won't get reuse beyond the intial installation if it doesn't do things that benfit the user. Reading campus news and looking at an event calendar is not substantive engagement - you're wasting your precious resources going down this road.

Segment and target aggressively

A single campus-wide mobile application will contain too much irrelevant content for too many people. Alumni don't care about campus bus schedules (unless they're on campus for reunion), students don't particularly care about regional club activity, faculty don't care about which alumni recently got married and so on. Build niche, targeted, relevant, useful and functional apps and you'll find happy users.

Mobile Web is the way to go

While performance isn't the best, getting something out there that works and can be iterated on quickly is key. Mobile web apps give you that because they can be built using the same skillset that your current web development staff have. Pure native apps bring with them a host of issues including app store approval, the need for completely different development skills for each platform and the cost that inevitably follows. "Near-native" using PhoneGap, Appcelearator, Sencha and others are coming along strong to bridge the gap.

Your campus (and alumni experience) is unique

Every campus is special because the relationship is personal. When I meet with universities to talk about projects, we talk about "emotional resonance" and finding ways to tap in to that to meet institutional objectives. Your mobile presence, whatver it is, should be deeper, more meaninful, more representative of what your institution is all about than just some colors and branding. Do something novel and the alumni will find their way to it. Who doesn't want to be proud of their alma mater for being innovative and inspiring? Seek that out.

Links and our slide deck

Our slide deck (which is fun, but not nearly as fun as the narration that goes along with it): Mobile Apps for Alumni Engagment (pptx) | Mobile Apps for Alumni Engagment (pdf)

Links to mobile/social/mashup services that were mentioned in our talk:

Thank you again to those who attended and to those who subsequently review the content of the presentation. I'll be more than happy to do a webinar for any school who is interested in thinking through the mobile app landscape and visit onsite once my leg is no longer broken!

Chad and I are happy to answer any other questions you have and help you find your way as you begin to evaluate mobile application opportunities.



CASE Mobile: Our first jQuery Mobile + ColdFusion app

Our first mobile application built with jQuery mobile went "live" today at the annual CASE/NAIS conference in Chicago, IL and by early accounts it's a success!

The purpose of the app is to make relevant conference information available to attendees at all CASE events year-round. Conference attendees will particularly enjoy the ability to submit their session evaluations from their mobile devices right away without having to handle the traditional paper forms. Session information is available as is a venue map. Conference organizers can also send out "alerts" that pop up within the app itself, notifying attendees of upcoming sessions, room changes or other important information. The "app" works on all Apple iOS, Android and Blackberry (OS6 preferred) devices and semi-gracefully degrades for use on older devices -- all with no additional development effort thanks to jQuery mobile.




Built on a tried-and-true combination of Adobe ColdFusion, Mach-ii framework, ColdSpring framework and SQL Server for backend data storage, the app is expected to serve tens of thousands of unique users every year. Taking on jQuery Mobile as our front-end framework was not without some risk; it's still in alpha (we used Alpha 2) but the rapid development and cross-device capabilities of the framework far outweighed the immediate concerns. We'll be keeping a close eye on this and upgrade as new releases are made. Testing was done on a Motorola Droid 2, Blackberry Torch, an iPad and an (ancient!) iPhone 3G without issue.

Want to talk about how we might be able to help you implement a cross-platform mobile application? Email Steve at srittler@countermarch.com.

Mobile Apps for Alumni Relations - Cornell Compass

We recently had the privilege of working with Andrew Gossen in Cornell's office of Alumni Affairs on a sweet little mobile project.

The Cornell Compass web application uses geolocation features exposed through mobile browsers to determine the distance and bearing from where you're standing to the center of Cornell's campus. It's fun! It would be way more fun if the orientation of the device was exposed as well (then we could make the compass dynamically spin in real time).

Once your location is determined you have the opportunity to "Check In" and drop a marker on a map with your name and class year (both optional). The map is visible both on the mobile device and via the website (we do some browser sniffing so the content is device-appropriate). All visitors are encouraged to share the link to the site via Facebook and Twitter.

The Compass app is optimized for iPhone, but is functional on both Blackberry and Android devices as well. The backend (which is trivially simple) is ColdFusion with Microsoft SQL Server. The bulk of the front end work was done using jQuery and a few assistive javascript libraries for doing the bearing calculations.

We're working with Cornell to design the next version of this application with more features that make it useful to Cornellians all over the world looking to deepen their relationships with each other. Interested in learning more? Please drop me an email! We're interested in working with other organizations to enhance the usefulness of the app including integration with alumni online communities and CRM systems.

About the blog