3 May 2012
All
Note: If you have questions about this article, use the comments feature at the bottom of the article. Please don’t contact technical support with questions about Adobe Developer Connection articles.
This tutorial focuses on the basics of Storefront customization for Adobe Digital Publishing Suite (DPS). After completing this tutorial, you will have an understanding about how custom storefronts work, how they can be developed, and how they can be integrated into Adobe DPS Viewer applications. Storefronts are developed using HTML(5) and JavaScript. In this tutorial, you'll use the iOS platform for deployment, but the same methodology applies to Android environments as well. With good development practices, the storefronts can be developed for cross-platform usage.
Standard DPS comes with a default library in which the user can buy, download, and view publications that are available. This library is not customizable and has minimal capabilities to incorporate marketing messages. Using storefront customization, publishers can differentiate themselves, extend their brand identities, and incorporate marketing activities into their apps.
Samples of current applications with custom storefronts on iOS that can be found in the iTunes app store:
In this tutorial, you'll use the following resources:
Each application within Adobe DPS Enterprise Edition can be extended via the JavaScript Viewer (Custom Storefront) API. This will give developers the opportunity to design and develop their own storefronts and make calls into the viewer for common viewer actions.
The DPS viewer application extends the WebKit framework and adds the additional calls listed in the API. The API documentation explains the available API calls and provides small examples.
The following is a basic overview of the important APIs:
getPreviewImage() call. The result will be a JSON object with the status ("result") and the "path" to the preview on the local device.The current implementation of the viewer only supports one callback function at a time. This means that you'll have to wait for one callback to be complete before you call another function.
Now that you've learned the basic API calls, this section will focus on building an actual store. This will be done in several exercises. Each exercise has a _start and _finish file. The _start file contains the beginning state for the exercise, in which you can make the modifications. The _finish file contains the end state for that particular exercise. For most of the exercises, the JQuery framework will be used in the examples. Any JavaScript framework can be used to implement the custom stores.
<javascript include> is necessary to use the JavaScript bridge. But while testing and developing on the desktop, a sample implementation will be used that simulates the behavior of the device. This library is included on line 7. Make sure that this line is removed (or that the js-file is not copied) when you test this later on a device.window.onadobedpscontextloaded when the APIs are available. Only then may the actual store construction work start. In this case, the init() function is called. When the store is tested on the desktop (testondesktop="true"), this check is being bypassed. Make sure to set testondesktop="false" when you deploy on the device.getFolioData() is an asynchronous call like almost every storeAPI call, and wants a callback function as an argument (line 12).
To show titles for folios:
showFolios is called to show an initial list of folios.title of the folio and the productId. A list of folios should appear. A sample implementation can be found in exercise_2_final.html. The following lines are added in the _final version of the file:// MODIFY HERE
$('#folios').append(folio.title);
$('#folios').append(" / ");
$('#folios').append(folio.productId);
$('#folios').append(" <BR> "); From this exercise on, the JQuery framework is being used.
Now that the code generates a list of folios, the links to download or view a Folio need to be added.
addFolio function.folioHTML.click(function(e) {
adobe.dps.store.viewFolio(folio.productId);
});
The final code can be found in exercise_3_final.html.
The store now renders a list of folios. The next step is to add a preview image for each folio. Preview images can be obtained through a separate call to adobe.dps.store.getPreviewImage. It takes five arguments, of which two (width and height) are currently ignored. The first argument is the productId of the folio for which the image is requested. The second argument is the orientation; the Boolean value will indicate if a portrait image is requested. The last argument is the callback function that will be called when the image is available.Open file exercise_4_start.html and extend the code on line 73 with the following:
imgElement = $('<img>');
imgElement.attr('class','withStyle');
imgElement.attr('width',120);
adobe.dps.store.getPreviewImage(folio.productId, false, 0, 0, function(data) {
var result = data && data.result;
if(result == "succeeded") {
imgElement.attr('src',data.path);
} else {
console.log("An error occurred");
}
});
folioElement.append(imgElement);
Preview images should now appear for each folio.
Up until now, the logic for the store has been implemented directly in the HTML page. This page will end up in the ZIP file, which in turn will be baked into the viewer. This means that for any updates to the custom storefront, the viewer must be updated, which can be a complicated and time-consuming process. An alternative is to "externalize" the store. The store logic will be stored on a remote web server and invoked when the store is started.
<script type="text/javascript" src="http://yourservername[:port]
/exercise_5/store.js"></script>
Now that the store has been externalized, proper logic is needed to check if the viewer is online or offline and provide proper feedback to the user. In this case, a separate JavaScript file is used (network_detection.js). This JavaScript file will be included in the viewer. The init() function will be called when the JavaScript Bridge in the viewer is ready, or directly after loading in a desktop situation.Using a jQuery Ajax call, a remote web server will be called using the HEAD HTTP call. If this call succeeds, the viewer is online. If the call fails, the viewer is offline and a message will be shown accordingly. The HEAD call is used to avoid unnecessary network traffic. If the GET method were used, the actual page would be downloaded and directly discarded after receiving it.
<script type="text/javascript"
src="exercise_6/network_detection.js"></script>
"#offline" div to the HTML body on line 16:<div id="offline">
Trying to connect to online store...
</div>
Now that the store is working, it will be packaged for deployment in Viewer Builder, and you will create the actual viewer.
Walk through the various screens in the process. First, you'll add icons and splash screens in that section (see Figure 3); then, in the Navigation Toolbar section, the store will be added to the actual viewer (see Figure 4). In this case, only assets for iPad and iPad2 will be used (no Hi Res assets for the new iPad).
Note:
testondesktop=false is set in the store.js file.
The provided Store API Explorer (in deploy-store-explorer.zip) can be added to your viewer in a slot in the navigation toolbar. The Store API Explorer can be useful during the development of a custom store—it enables you to execute functions directly in your existing folios for testing and debugging (see Figure 6).
The getFolioData() call retrieves an array of folio descriptors known to the Viewer's library. Valid folioState values are as follows:
Value identifier |
Numeric value |
Description |
|
|
|
|
|
The folio is not yet available for purchase |
|
|
Can be purchased and downloaded |
|
|
There is an active or paused Purchase Transaction for the folio |
|
|
The folio is free, or its Purchase Transaction completed successfully |
|
|
There is an active or paused Download Transaction for the folio |
|
|
The folio content is stored locally. |
|
|
There is an active or pause Extraction Transaction for the folio |
|
|
The folio is can be loaded in the viewer |
|
|
The folio is viewable but can be updated |
|
|
There is an active update download for this folio |
|
|
The folio is viewable but has an update that can be installed |
|
|
There is an active update extraction for this folio |
For example, you can test some of the APIs as follows:
folioState values.productId of a folio that has status "200". Paste (or type) the productId into the textbox after "viewFolio". Tap on "viewFolio"productId into the first textbox. Enter "0" into the "width" and "height" textboxes. In the current implementation, these values are ignored. Tap on the link for "getPreviewImage". The result will be a JSON object with the status ("result") and the "path" to the preview on the local device.productId into the textbox after "archiveFolio" and tap the link. This will archive the folio.This tutorial demonstrated the process of developing a custom store. In this example, only free folios were used. When folios are available for purchase, use the call to buyFolio() to initiate the purchasing process. In the same way, subscription purchasing can be initiated.
To get more information about current subscriptions and past purchases, the getReceiptData() call can be used to retrieve that information from the viewer.
A good understanding of the various JavaScript viewer APIs will result in good implementations of custom store fronts.
See the article Build a horizontal swipe storefront with folio preview for a complete template for a custom store that enables users to swipe horizontally through store pages, view folio previews, and navigate to different sections of the store which can feature different categories of product offerings.

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License