Recently, Float Learning was approached by a client to develop an iPad application for a trade show that allowed customers to learn more about their product. The basic premise of the application was to allow the customer to select a region of the country after which they would be presented with a digital brochure (in PDF format) detailing the company’s product offerings for that region.
In the past, this application had been developed as a standalone kiosk with a touch screen interface that allowed customers to interact with the map in an intuitive, engaging manner. Among the key features of the application that the client wanted to retain were the ability for the customer to touch and drag the map as a navigation mechanism, and to zoom into the map for a detailed view. We wanted to share this experience with you and also provide some insight on how we did it, and finally share the basic code example that the foundation for the iPad application.
We at Float felt that this was an ideal opportunity to leverage the unique capabilities of the iPad to not only meet the client in terms of the base functionality of the application but to also develop it in such a manner that customer contact would be greatly enhanced. We wanted to develop a custom iOS application that would allow representatives to roam the trade show floor with iPad in hand and present customers with the application, increasing face-to-face interaction with the customer. Additionally, we wanted to take advantage of the connectedness of the iPad device, and add functionality that would allow representatives to email a copy of a selected PDF resource to a customer’s email directly from the application. This allowed our client to show great, on-the-spot customer service while negating the need to print thousands of brochures to be on site at the show.
In architecting our solution, we wanted to smartly use existing components in such a way we could deliver the full set of functionality the client was requesting while keeping development time to a minimum. One of the key decisions we made was to leverage the UIWebView component to handle the majority of the map navigation interface. The UIWebView allows you to load in a HTML page into your application, with the UIWebView itself managing iPad gestural commands such as touch and drag and pinch and zoom. Using this method allowed us to implement the touch points of the many regions of the map using a tried and true and a (relatively) easy to implement method–a HTML image map. Looking at the UIButton to launch the associated regions PDF document.
With the map navigation managed this way, the next task was to handle the “taps” on the image map to launch the associated PDFwithin the application. While the UIWebView detects touches “out of the box” on <a href> elements, it keeps those touches within the UIWebView–that is, it will attempt to navigate to the URL pointed to by the tag within the UIWebView instance. While this fulfills the base requirements of the standard component, we needed to intercept taps on the map and handle them within the overall application to launch the associated PDF document. To do this, we turned to a neat trick posted by the folks at Teton Tech. With our MapViewController being defined as a UIWebViewDelegate, we can define a method, shouldStartLoadWithRequest, that will be called whenever a user taps an element that starts a load request (in our case, tapping one of the image mapped regions), receiving the URL being loaded as a parameter. Returning ‘NO’ from this method will prevent the web view from performing the default action associated with the component – that is, loading a web page.
To take advantage of this interaction between the web view and the overall application we specified the href attribute of each of the mapped regions to simply be a named anchor (i.e. #anchorName). With the URL being passed in as a parameter to our method, we then defined each of these anchor names as keys to a dictionary that holds the name of the associated PDF file within the applications resources bundle. Thus, when our method is fired via a tap on one of the image mapped regions, we could then use the provided anchor name to look up (via the dictionary) the PDF document to be launched.
Now, with a mechanism in place to detect the requested launch of a PDF document, we turned our focus to loading and displaying the requested PDF. For this, some brief research turned up the useful Leaves component developed by Tom Brow. As provided, this component gave us most of what we were looking for in our PDF presentation requirements: loading in the PDF from the resources bundle, then presenting the individual PDF pages in an attractive iBooks-like manner with a click and drag page curl transitions. So, in our method that detected and decoded the touches on the map, we added code that created a view controller based on the PDF example given in the Leaves source code, passing in the PDF file name to be loaded from the resources bundle. This view controller was then added to the overall application navigation controller (using the pushViewController method) to provide a nice animated transition from the map to the loaded PDF.
To the core Leaves view controller (PDF ExampleViewController), we then added some additional custom functionality to round out our application, namely the ability to navigate back to the main map interface, a button to email the current PDF to a specified email address, and, finally, a set of “quick links” to enable navigating directly to any page of the loaded pdf. To facilitate these actions, we added buttons to the standard navigation interface, assigning a back button as the left button item, a “share” button as the right button item, then adding a button corresponding to each individual page in the PDF to the toolbar items (achieved by a for loop based on the CGPDFDocumentGetNumberOfPages method for the loaded PDF). The navigation items were then hidden by default (to enable a better overall viewing experience of the document) and made visible by a double tap gesture (see the handleDoubleTap method in the PDFExampleView controller).
For the direct navigation to a page in the PDF, we again leveraged the code provided by Leaves. Because of the spotless and modular implementation by Tom setting the currentPageIndex property of the main leavesView object will automatically load and display the associated page. For our share functionality–emailing a PDF to an email address specified by the customer – we turned to the MFMailComposeViewController. This controller allows us to create and send emails using the built-in email tools on the iPad within the sandbox of our application. Essentially all that is needed to be done is to create an instance of this controller within our code, then use the core method presentModalViewController to have it appear within the application with a smooth animated transition. The key functionality of attaching the current PDF to the generated email is achieved by simply calling the addAttachmentData method on the created mail compose controller, passing a reference to the current PDF as an argument. This code is contained within the shareButtonClick method of the PDFExampleViewController. Again, a good example of leveraging existing components to provide a rich functionality with minimal development time expended.
This project turned out to be a great success for the Float Learning team. Thanks to a great all-around team effort we could deliver an outstanding application that fulfilled all client requirements and surpassed their expectations. Our client reported only rave reviews of the application from the trade show floor. This provided a great example of using the power of mobile to go above and beyond, delivering what is not possible by more standard means.
Latest posts by Mark Tovey (see all)
- Externalizing the Data Source of Your iOS App - June 2, 2011
- Sharing is Fun - March 28, 2011
- Mapping client success in a mobile environment – a case study and tutorial - November 12, 2010