i3Factory World

Your Iphone, iPad & Android Application Factory

Browsing Posts tagged i3F editorial

HTML(5) Approach
The final technique is something that is emerging now, especially thanks to the great improvements in term of stability and speed introduced by the latest version of iOS for the in-app web views. A couple of good examples of this approach are the Ars Technica app (link) and the Bloomberg Businessweek+ magazine (link).

The concept is quite simple: html and css are common and powerful techniques to layout a page on screen: why not leverage the skills developed by many web designers to make a magazine that perfectly fits with the iPad?
The core block at the base of this approach is the UIWebView Cocoa Touch object: with this view we can load any kind of html document, loaded locally or remotely, and layout it in the page at an adequate speed (but not the fastest) and without surprises. Besides we can get rid of the overlay
technique, as the web view is capable of displaying images, playing movies and of course execute javascript based widgets. Also this component provides a two way interaction between the javascript world and the objective-c runtime (and in fact this justifies the existence of extension languages
such as Objective-J, provided with the Cappuccino framework: http://cappuccino.org/). Finally the web view is highly respondent to user interactions, and some features like text selection and dictionary lookup come for free.
The open-source world is highly active in this area: projects like Baker (www.bakerframework.com), Siteless (www.siteless.org), Laker (www.lakercompendium.com) and pugpig (pugpig.com) make publicly available this kind of solution.

Sincerely we don’t know if this will be the final solution for everybody. Of course a publisher that already invested in setting up a web site (but not in Flash!), and this is quite common between newspapers, will be able to port most of the layout and contents to the iPad, and sometimes this can
be achieved with an adaption of the CMS output views to provide files that can be easily fed to the app.

Careful must be given to don’t push this behavior at its extremes: don’t forget in fact that web page rendering requires an inner engine and at the end any intermediate layer will require resources and extra time. Sometimes, and this is particularly evident with the first generation of the iPad, content
updates following user interaction are not very reactive. So it is not recommended to transform every single aspect of the magazine app into web based content: clearly in this way you’re helping all javascript developers not skilled with objective-c, but
a performance penalty will be visible.

As an example, the toolbar typical of all magazine apps used to access extra features (sharing, table of contents, home page, etc.) should always be done using the native Cocoa Touch component and not an html+css solution.

However if the publisher accepts to convert his design flow to a web based one and you, as developer, prefer to base your work on consolidated and easy to manipulate methodologies, this one should be your first choice to be taken in consideration.

Conclusions
We hope this article gives a good overview of the major techniques used to render pages in a magazine, newspaper or e-book. It could be we have not mentioned some technique we’re not aware of, in such case dear reader any feedback from you is welcome!

About the author: Carlo Vigiani
He is an electronics engineer and software developer, located in Italy. He is CTO and co-founder of new startup i3Factory.com, active in the development of iOS, Android and Win Mobile apps, with special focus on publishing, tourist and music apps.

Source: www.icodermag.com

01/2012

Pages Pre-Rendered by images
This technique is heavily used inside the highly interactive magazines published using the Adobe Digital Solutions environment: well known examples are the Condé Nast magazines (Wired is one of the most famous examples).
The way these magazines are implemented starts with the well known suite of Adobe Digital Publishing tools, In Design in primis. These tools are used by many publishers around the world and the latest versions offer the pos sibility to export the project, other than in the ubiquitous pdf format, in a package suited for distribution through iPad. The output of these files can be tested using the free app Adobe Content Viewer downloadable from the App Store, but of course the final branded app, together with the server infrastructure required to serve the contents, requires a higher tier license.

What characterizes this kind of magazines is that at the moment of project creation all pages are pre-rendered as jpeg or png images and then special effects are overlaid.
This means that the core section of the magazine reader is essentially an image viewer. Sure these images will span an area slightly larger than the iPad screen, so they will be embedded inside a scroll view, but they are still images. All in all technically the choice is not bad: the iPad is quite better in rendering images than PDF files, as the required calculations needed to transform the pdf data in bitmaps is completely skipped here, while the CPU will just need to decompress the image and send it to the graphics hardware. Exactly as we did in the PDF case, we can apply the overlay technique to over impose somecontent that requires user interaction on top of the bottom rendering layer.

While this technique is highly efficient from the point of view of rendering time, and is simple to implement as all the page layout complexities have been taken into account and solved by the desktop publishing tools, it offers a few limitations that need to be considered:

•     every single page takes quite more space on disk and download time of this kind of magazines is increased correspondingly; in comparison with a pdf page, the space taken is much more as every pixel of text must be provided in the file and we cannot force high compression ratios if we don’t want to introduce blurring in the text. The pdf page, especially those pages made of text only, is much lighter as the text is not pre-
rendered.

•     zooming or font resizing is not feasible: both pdf and core text redraw the text using vectorial algorithms or per-size font representations, this is not possible to achieve on a static image. This means that the magazine needs to be drawn with specific fonts types and sizes, fonts which are well suited for jpeg compression (no blur) and the screen resolution (132 dpi, not so high; things will be better with the next retina display iPad!)

•     text search, highlight and selection is impossible, unless the digital publishing tool exports together with the pre-rendered pages a full map of text coordinates, something I haven’t seen yet!

Adobe is not alone in publishing this kind of magazines:
there are several custom apps in the market that follow exactly the same approach. It’s not bad but is not leveraging the great publishing frameworks that Apple is offering to its developers. And it has too many limitations if compared with other techniques. For sure a publisher that is mastering the digital publishing tools I mentioned before can take advantage of this approach, as the final quality is undoubtable and the time to market is the shorter, and at the same time allows to provide a content suited for the iPad, and not just a pdf fit on screen.

But I would recommend to all developers that are making custom products and are not using specialized page composition tools to stay away from such methodology.

Source: www.icodermag.com

01/2012

 

CORE TEXT RENDERING
Core Text (short: CT) is another of those technologies developed for the Mac and later ported to iOS.
The Core Text framework is dedicated to text layout and font handling. Just to summarize the capabilities of this framework, consider that is at the base of the desktop publishing revolution that made the Mac famous in this professional sector.
As CG, even CT has a C-based API, even if there are several third-party open source wrappers that pack together the most common functionalities in a high-level Objective-C interface.

CT should not be used to replace web based rendering based on html and css, this is a too complex field that is better to leave to dedicated system components such as then UIWebView instead it can be used to efficiently render some rich text.

CT talks with CG, in fact text rendering is done at the same time of view Quartz based rendering. The two APIs have similar conventions and memory management rules, so the developer already accustomed with Core Foundation programming model will not find an hurdles in understanding the CT API. This gives the possibility to the developer to eventually mix the text rendering and image drawing at the same rendering stage (CT is limited to text only, it has no image drawing capabilities).

The main reason to use Core Text is because it does direct rendering of text on page without any intermediaries. It differs from PDF which consider each page as a whole, it differs from web based techniques as there is no intermediate language (html) or layout interpretation (css) in between, you can write directly on the page. The basic components behind CT are layout objects such as “runs”, which are direct translation of characters
into drawable glyphs, “lines” of characters and “frames”, which correspond to paragraphs. The translation of characters to glyphs is done by “typesetters” and the text to be plotted is provided using attributed strings, which are common strings enriched with attribute informations (font size, color, ornaments).

You will decide to use Core Text for a magazine whose layout will be mostly based on text with standard layout, so it fits well for newspapers also. Probably it’s not the best choice for glamour magazines where graphics layout is changing on every page and could be quite complicated.
A clear advantage of the Core Text based solution is that you don’t need to apply the overlay technique we mentioned in the paragraph dedicated to pdf. With CT you will directly divide your page in frames and each of these frames will contain text (rendered by CT) or multimedia. Essentially you can define the page layout by selecting a size (it can fit the iPad screen or it can be vertical or horizontal scrolling page), then you will decide the size and position of media content in this page and finally you will define the frames (several rectangular frames) that will contain the text. The text frames organization can be of any kind, from compact single column structures, two multicolumn layout or varying size frames. Inside the frames you will render the text and Core Text will help you to manage line breaks for these paragraphs. Then you can easily provide the user the possibility to change font type and size and the same rendering code can be reused to quickly rearrange the text inside the frames.

The page layout representation can be provided in any form decided by the developer together with the publisher, the best choice will be XML (all in all it’s the base of any markup format!) and it will be shipped to the app together with the texts (still XMLs) and the assets in a zip file package.
One limitation of Core Text is that it is a text drawing technology and is not optimized for editing (but we don’t need it at this stage) and user interaction. This means that if we want to provide text highlight or select and copy features we’ll need to implement them by our own; the framework provides us some APIs to facilitate this task but in any case the code to implement these functionalities must be written by the developer to manage every single detail. In any case all these tasks will be greatly simplified in comparison with PDF: here you have full control of the text and its position of screen, while pdf is still an opaque entity hidden behind a complex data structure that you cannot control in its entirety.

Our recommendation is that if you must implement a digital magazine, without extreme layout requirements, some multimedia content and a fast and powerful control of text, using Core Text is the first technology choice to be considered.

An excellent tutorial on the subject is available at this link on Ray Wenderlich blog: http://www.raywenderlich.com/4147/how-to-create-a-simple-magazine-app-with-core-text

Source: www.icodermag.com

01/2012

 

The Magazine is a PDF File
You may like it or not, but should your software house be committed to develop a magazine iPad app, the magazine will be with high probability given to you as a PDF file. As there is no way to “escape” from it, at the end you will need to develop your own pdf reader or integrate some free or  commercial external library.
The reason why pdf is still the dominant format in the e-publishing world is clear: most of the publishers are porting their existing printed  publications on the iPad, and for obvious budget reasons they want to reuse all the investment done in the creation of their issues. You will not be able to escape from the pdf format dictatorship with the exception of two cases: the publication is brand new and only digital, so there are no previous investments to drive the final choice, or the publisher has large budgets and/or is a strong user experience (UX) believer and accepts to allocate the extra budget to recreate a different format for its publications. Both cases are not so uncommon with those publishers that already did the effort to bring their products to the web (with the notable exception of those that did it in Flash!), but the large part of the small and medium publishers will
still be locked to the pdf format.

Unfortunately the pdf is not the best way to port a magazine in the iPad. And this for several reasons:

•     printed magazines page size is usually larger than the iPad screen: this means that when the page fits to the screen, all characters appear smaller and then something readable in the printed paper could become unreadable without zoom; but zoom is not always efficient and in particular it’s not loved by readers that may lose their “orientation” inside the page.

•     printed magazines pages have not the same aspect ratio of the iPad screen: this means that a page that fits in the screen will be bordered by top/bottom or left/right empty stripes.

•     often printed page layouts are optimized for facing pages, e.g. a panorama picture which is spread between two pages; when the device is kept in portrait orientation, these graphical details will be lost, instead if the device is kept in landscape you will be able to appreciate the two-pages layout but characters will be too small to be read comfortably.

•     as these files are not optimized for digital, normally the outlines (table of contents) and annotations (links to pages or external resources) are not exported; this means that even if your pdf reader code is aware of this information, in the majority of cases it is not available and then you will need to define a different way to provide it.

•     the official pdf format supports multimedia content; unfortunately the iOS is not able to manage it, so all interactive content must be provided  outside the pdf file.

The page rendering is achieved in iOS (and OSX too) through the Quartz 2D API, provided within the Core Graphics framework (shorted with CG). Quartz 2D is the two-dimensional drawing engine on which are based many (but not all) of the drawing capabilities of iOS. The
PDF API is a subset of the huge CG API. This API is “old fashioned” and is not based on Objective-C but on pure
old C; besides all memory management rules will follow the Core Foundation (CF) rules which are different from Obj-C one: this means that special attention must be provided to avoid memory leaks, as each PDF page manipulation can take several megabytes and leaks will easily trigger the memory watchdog, thus force quitting your app.

be immediate to render a PDF page, by following these basic steps:

1. get the CG reference to the pdf page to be drawn;
2. get the current graphics context for the view that will contain the page;
3. instruct Quartz to draw the pdf page to the context.

As you can see, apart the required steps needed by the drawing model of Quartz, the full rendering is accomplished by the system and you don’t need to have any knowledge of the data format of a pdf file. So for you the pdf rendering processor is just a black box, and this is clear when you
see that all CG data structures are in fact opaque and their inner contents can be accessed only via API.
But a valid pdf magazine reader cannot limit itself to rendering, so you will be required to support zoom. Now as your maximum zoom level can be theoretically very high (don’t forget that characters in the pdf file are like fonts in the computer, they will never lose in precision even for
extreme zoom-ins), it is impossible to render the full zoomed page in a canvas much higher than the device screen:
here we have pixels, not vectors, and it would be immediate to crash the app because all the memory has gone away for one page only. So you will be forced to introduce tiling techniques that will limit the effective rendering to the visible part of the page, not always an easy task.

More difficult is document parsing: this is required if you want to extract outlines, annotations, do some text search and highlight. In such case apart a few meta data extraction functions, what the API gives you is a set of functions that will allow you to explore the data structures inside the document. You will not be able to get any information from the file if you don’t explore the data tree correctly and if you don’t follow the specs of the PDF document.
This is worsened by the many versions the PDF specs got in the years and by the fact that many publishers still use old software that exports the  content in the old formats.
I have developed a general purpose PDF explorer, this was part of a commitment of a client that asked me to develop a general purpose PDF reader; but as it is really hard to apply all the specs of the PDF official reference, my suggestion is to concentrate on the most used features and test them with many documents. As I said before, CG navigates the data tree but it doesn’t interpret it for us!

The last section of this part, long explanation but required given the importance of the topic, is how to provide multimedia content on top of a PDF file: all in all the iPad is a so versatile device that we cannot limit ourselves to simple page rendering. By adding extra content to the printed page you can leverage the device characteristics and still taking benefit on the investment done in the magazine creation.

There are many reasons to justify this choice: e.g. a printed advertisement can offer a video instead of a static picture, or a printed link to a web page can be replaced by an active link to a web view, or finally we can show the current weather using an html5 widget. As I previously said it is not recommended to introduce all this content inside the pdf file: it will not be rendered by Quartz and you will still be forced to traverse the data tree to extract the CG object reference for further manipulation. Finally not all publishers are aware of these functionalities or their digital publishing software is too old to fully support them.

So the best solution is based on the “overlay technique”.
This methodology consists in representing the pages in two layers:

•     the bottom layer (“rendering layer”) will contain the PDF rendering, so it will contain the bitmap image of the page;
•     the top layer (“overlay layer”) will draw all overlays and is sensible to user touches.

The overlay layer is typically made of UIKit components, so we’ll add a UIWebView for html widgets, we’ll introduce a UIScrollView to display a gallery of sliding images, or we’ll add a Media Player view for video execution. Typically the overlay descriptions are provided on a separate file, e.g. an xml, json or plist, and they will be packed together with the pdf file and all assets (movies, images, html files, music
files) in a zip file.
The app will download the zip file, will unpack it and then for each page it will use the pdf page to fill the rendering layer, and the overlay information associated to that page to build the overlay layer.
Note that this technique can be applied also in the other rendering techniques we’ll talk about in the next paragraphs, in such case it allows to overcome many of the pdf format limitations. The major requirement for the deve loper is to define a suitable format, follow all page zoom
and rotations with a corresponding overlay transformation and finally provide the publisher with the instruments and
guidelines required to easily create such overlays.

source: www.icodermag.com

01/2012

 

This article was written to our CTO, Carlo Vigiani, for iCoder magazine

One of the great improvements in all iPad owners lifestyle is the possibility to bring everywhere any sort of magazine or book, thanks to the screen size and the device light weight which both facilitate reading and carrying. In particular reports demonstrated that in a printed publications decreasing market there is a huge increase in the number of subscriptions to the digital versions of the same product (the interested reader can read this report from MPA: http://www.magazine.org/association/press/mpa_press_releases/mag-mobile-reader-study.aspx)

Apple is following this trend with great interest, and this is quite clear if we take a look at the evolution of the iOS features that have been introduced since the release of the version dedicated to iPad, that is 3.2.
In the particular the milestones that have been reached are three, shared between three major releas es of the operating system:

•     iOS 3.2 was enriched by the CoreText framework, a technology dedicated to rendering text on display available since long time on Mac OSX and  never ported in the earlier versions of the iPhone OS.

•     iOS 4.x introduced the concept of auto-renewable subscriptions, as an addition to standard non consumable In App Purchases; this feature has been introduced after long discussions between Apple, that applies the 30% commission on every In App sale and forbids any other external cheaper store access within its devices, and the publishers looking for customer fidelity techniques.

•     finally iOS 5.0 added the Newsstand feature, which provides a central place to collect all magazine and newspaper apps and at the same time provide night-time content push to all subscribers, letting them to immediately read the latest issues of their publications and saving them for the extra time (sometimes long) required for the download.

What Apple didn’t provide instead is a common and unique developer platform dedicated to the creation of apps dedicated to the magazine consumption. This lead to a lot of initiatives dedicated to help publishers to enter in the iPad market with their own magazines. These initiatives were taken by major and well known companies, such Adobe with its Digital Publishing business, and a lot of many start-
ups, everyone with its own solution.

As I said, Apple doesn’t provide a unique solution, but developers have the availability of a set of frameworks and techniques, with different levels of complexity, that provide different way of representing the page on the screen.
There is not an optimal choice, as the final decision needs to take care of aspects that go beyond pure technical considerations.
In this article we will try to depict these solutions mainly from the app developer point of view, but will never forget to enumerate the pro and cons that can affect the publisher decision on which technology to adopt.

Page rendering overview
We assume that you, the developer, are in a certain point of your app development where the magazine has been purchased, downloaded and it’s ready to be read. Your document data at this point is safely stored in the device file system and it can be represented by a single pdf file, or a collection of html and css files or a directory containing assets of different formats, such as images, videos, html5 widgets, text files. You’re now facing the problem of taking one page (which can extend beyond the screen boundaries) and presenting it in the empty space of your UIView dedicated to the
page rendering.

In the next post I will present the following methodologies to achieve this result:

•     pdf document rendering
•     pre-rendered image display
•     free format CoreText rendering
•     web based approach

01/2012 – source: www.icodermag.com

 

Icona Newsstand Icon

The iOS5 revolution

A lot of water has flowed under the bridge since our first part of this tutorial. We’re sorry for the delay, but at the time of writing we were aware of the new featured introduced with iOS5 but we were still under NDA and not authorized to disclose anything about the SDK. Finally we’re now able to provide our example magazine app with the double iOS4/iOS5 compatibility.

 

I will not spend my time explaining all the Newsstand features, all in all we’re creating a magazine app here and the Newsstand implementation details go beyond our original purposes. I have written a two parts tutorial in my personal blog that you can read here and here, and that covers all Newsstand aspects and the required (by Apple reviewers) subscriptions. In short, Newsstand is both a new way to present magazines in the iPad and iPhones, where the original icon is replaced by a cover of the magazine or newspaper and is placed under a special group dedicated to collect all Newsstand icons installed by the user. For the developer it is also a framework, called Newsstand Kit, that introduces a new methodology to organize, download and install the app content.

The example app

The screenshot shows the final appearance of the app. A set of nine magazines with their nine fruity cover. You can download a magazine, see the progress bar change while the operation is in progress and finally read it. The other screenshot shows the appearance in the Newsstand. The typical icon has been replaced by a magazine-like representation inside the Newsstand group. The same, if run on an iPad with iOS4 installed will show the classical icon instead.



The full app code is available on GitHub. Don’t consider it as a production code, so please don’t try to reuse as it is with your clients unless you have tested it in all possible corner cases. Anyway it can be considered as a valid starting point for real apps. Essentially the principles behind the code architecture have been depicted in Part I of this tutorial; if you haven’t read it yet I recommend to jump to that article before entering in this one, at least to understand the key components of such an app. The driving aim is to keep the issues management (controller, don’t confuse it with “view controller”) separated as much as possible from the UI concerns. This means that in theory the whole code behind the Store Manager and Issue Models part can be reused even in a Mac OSX app, as they relationship with UI stuff is minimum.

I have setup this app using the basic single window Xcode template and then added the two main components in the application delegate startup method:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// here we create the “Store” instance
_store = [[Store alloc] init];
[_store startup];self.shelf = [[[ShelfViewController alloc] initWithNibName:nil bundle:nil] autorelease];
_shelf.store=_store;self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.window.rootViewController = _shelf;
[self.window makeKeyAndVisible];
return YES;
}

The two components are:

  • the Store class, which represents the Store Manager block in the app architecture; this Class is a subclass of NSObject and is not linked to the user interface.
  • the ShelfViewController represents the UI of the application. It is linked to the store using a specific property. Note that the controller will not access the store exposed properties, but will get the needed information via a simple API. We could have used a delegate pattern instead, but as both blocks are essentially custom blocks in a custom app, there is not much need to define a protocol for their interaction. We can say that the controller part has been split in two parts, one for the UI, the shelf, and one for the back-end, the Store. Their link is such that the Shelf depends on the Store (strict link), not viceversa. Any Store to Shelf communication is done using lazy methods, based on notifications.

The app has then been integrated with the new Newsstand requirements in the info plist. Again have a look at Apple docs or my tutorial for a detailed guide.

Models and Controllers

We have one model in this app, it is the Issue model which represents a single magazine issue in the store or in the user library. There is also one controller, which is the Store. As I said this controller is not a UI component but the app back-end is self sufficient with these two components. In theory we can retrieve the store status and download magazines even without any user interface. This is a basic concept in magazine apps, where many events happen in the background are not related to direct user interaction: this means that the app should be capable to perform several tasks even if the user interface has not been loaded at all.

The role of the Issue class is to represent all relevant magazine properties, that is a unique identifier, a title, a release date, a link to the cover image, obviously the link (URL) to the content (which can be a pdf file, an epub file or a zip file for complex packages). In particular the unique identifier is a piece of data that must be maintained along the full life of the issue: it is the only way to uniquely identify a particular issue, independently of localization issues (e.g. the title can change in different countries, but not the unique ID). Besides it is the link to the Newsstand way to identify issues (the NKIssue‘s name field) and it can be also used to link the product with the App Store if we’re going to implement In App Purchases.

Other than this role, the Issue class will have a central role in the downloading of a magazine. Essentially the Store class will schedule a download but it will be monitored (progress) and then finished (effective magazine installation) by the Issue class.

Finally this class has limited capabilities to represent a magazine already downloaded and available in the user library. For this we provide the simple isIssueAvailableForRead that will be used by the user interface to know which action is possible with an issue (read or download) and eventually display the contents.

The Store class is the app controller. It is initialized at the very beginning of the app and its instance is never released. Besides immediately after initialization this class will fetch the store contents from the publisher server. In the example we decided to implement the store contents as a simple property list, and we instruct the store to retrieve this property list, decode it and create the Issue objects, and finally download their cover images. All this is done asynchronously using the Grand Central Dispatch and at the end a notification will be sent to inform all interested objects (in particular the view controller) that the store contents are ready and the UI can be safely displayed. Note that the store status is represented by a property status. We have overridden its setter method to post a notification that informs any interested observer of the new state. For simplicity we decided to limit the possible statuses to “not initialized”, “downloading”, “ready” and “error”. A more complex app can introduce extra states if needed. Finally as a fallback in case of missing connection (the user must be able to access his/her content even if not connected to the Internet) we reload a locally saved copy of the store.

The central piece of the code is in the downloadStoreIssues method of the class, that we report below:

-(void)downloadStoreIssues {
self.status=StoreStatusDownloading;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0), ^{
NSArray *_list = [[NSArray alloc] initWithContentsOfURL:[NSURL URLWithString:@”http://www.viggiosoft.com/media/data/iosblog/magazine/store.plist”]];
if(!_list) {
// let’s try to retrieve it locally
_list = [[NSArray alloc] initWithContentsOfURL:[self fileURLOfCachedStoreFile]];
}
if(_list) {
// now creating all issues and storing in the storeIssues array
[_list enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSDictionary *issueDictionary = (NSDictionary *)obj;
Issue *anIssue = [[Issue alloc] init];
anIssue.issueID=[issueDictionary objectForKey:@”ID”];
anIssue.title=[issueDictionary objectForKey:@”Title”];
anIssue.releaseDate=[issueDictionary objectForKey:@”Release date”];
anIssue.coverURL=[issueDictionary objectForKey:@”Cover URL”];
anIssue.downloadURL=[issueDictionary objectForKey:@”Download URL”];
anIssue.free=[(NSNumber *)[issueDictionary objectForKey:@”Free”] boolValue];
[anIssue addInNewsstand];
[storeIssues addObject:anIssue];
[anIssue release];
// dispatch cover loading
if(![anIssue coverImage]) {
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:anIssue.coverURL]];
if(imgData) {
[imgData writeToURL:[anIssue.contentURL URLByAppendingPathComponent:@”cover.png”] atomically:YES];
}
});
}
}];
// let’s save the file locally
[_list writeToURL:[self fileURLOfCachedStoreFile] atomically:YES];
[_list release];
self.status=StoreStatusReady;
} else {
ELog(@”Store download failed.”);
storeIssues = nil;
self.status=StoreStatusError;
}
});
}

Note that in the code above for simplicity I have queued the cover downloading immediately after the property list download. Probably this is not the best way to do this, as we are adding extra networking steps before presenting the app status, with possible delays if network conditions are not good. We can do this in an example where we know that the number of issues is limited, probably in a real app it makes more sense to do this in a background job and then notify the UI to update its status every time a new cover is ready to be displayed.

The view controller

The user interface will wake up immediately, and will change its appearance based on the notifications coming from the store. When the notification center will deliver the store “I’m ready” message to the UI, this one will load all UI issue representations (the CoverView class in the code, a basic view with really minimum application logic) and show the shelf to the user.

At this point the app terminated its back-end processing and is waiting for user commands. Here we have two possibilities:

  • A magazine has been downloaded, the user will see a “READ” button, clicking on it he will be able to read it. In our example all our content is made of pdf files, we decided to use the Quick Look framework in iOS, it is enough for our purposes.
  • A magazine has not been downloaded yet, the user will see a “DOWNLOAD” button, clicking on it the download will start and we’ll show a progress bar. At the end we need to replace the button label and hide the progress. We’ll see this part in more detail.

The view controller is dependent on the store. In order to get the issues information (number of issues, detail of each issue) it will not access directly to the store properties but will use a very simple API, made of three methods:

/* “numberOfIssues” is used to retrieve the number of issues in the store */
-(NSInteger)numberOfStoreIssues;/* “issueAtIndex:” retrieves the issue at the given index */
-(Issue *)issueAtIndex:(NSInteger)index;/* “issueWithID:” retrieves the issue with the given ID */
-(Issue *)issueWithID:(NSString *)issueID;

Based on this information, and on the Issue properties, it will create the Issue view representation (CoverView) and place it on the screen.

Downloading a magazine

In a magazine app there are three critical sections: retrieve and display of the store contents, download the contents and finally read them (a good PDF or epub reader is mandatory in an app like that; it’s not the purpose of this tutorial, aimed to explain the architecture and the techniques needed to make such an app, but it is a relevant part in the user experience).

My approach in the magazine download is that the user must be completely free to do any action and such actions shouldn’t interfere with the result of the download. Now many apps take a shortcut: they put a spinner in the center of the screen, then block any user interaction with the UI objects behind the spinner and ask the user to wait. It’s easy to do this, but it is not the better user experience. While waiting the user can read another issue, can navigate inside the store or decide to switch temporarily to another application or finally can temporarily lose the network. Newsstand Kit provides a system level methodology that simplifies (in some cases) the developer life but at the same time removes any excuse on not doing a good job in term of user experience.

As soon as the user triggers a new download, the view controller will send its download request to the store class. In the code below you can see the scheduleDownloadOfIssue: code. This method will prepare the network request and will send it in the background. Note how we split the app behavior based on the operating system version we’re on. If it is iOS5 then we must use the Newsstand approach – where the downloading will be managed by the system in a Newsstand queue – , if we are in iOS4 we’ll follow a classic methodology based on NSOperation: in this case I missed for simplicity to get the content length of the content to be downloaded, so in the iOS4 case the progress bar will not be displayed. This information instead if provided “for free” by Newsstand.

-(void)scheduleDownloadOfIssue:(Issue *)issueToDownload {
NSString *downloadURL = [issueToDownload downloadURL];
NSURLRequest *downloadRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:downloadURL]];
if(isOS5()) {
// iOS5 : use Newsstand
NKIssue *nkIssue = [issueToDownload newsstandIssue];
NKAssetDownload *assetDownload = [nkIssue addAssetWithRequest:downloadRequest];
[assetDownload downloadWithDelegate:issueToDownload];
} else {
// iOS4 : use NSOperation
NSURLConnection *conn = [NSURLConnection connectionWithRequest:downloadRequest delegate:issueToDownload];
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(startDownload:) object:conn];
if(!downloadQueue) {
downloadQueue = [[NSOperationQueue alloc] init];
downloadQueue.maxConcurrentOperationCount=1;
}
[downloadQueue addOperation:op];
[downloadQueue setSuspended:NO];
}
}// iOS4 only
-(void)startDownload:(id)obj {
NSURLConnection *conn = (NSURLConnection *)obj;
[conn start];
}

In the two cases I’d like to emphasize the fact that the Store initiates the download operation but then it will delegate any further processing to the interested part, the is the Issue to be downloaded. So it will be the Issue class that will monitor the download and then will finalize it.

The Issue class will behave as delegate of the download operation triggered by the Store class. The delegate protocol changes if you’re using Newsstand or not. In the former case you will need to be compliant with the NSURLConnectionDownloadDelegate protocol while in the latter the protocol to be respected will be the un-documented (or: documented in the header files only!) NSURLConnectionDataDelegate which is a “spin-off” of the classic NSURLConnectionDelegate. The difference between the two protocols in that one will write in the file system, the other in memory. Again don’t use the “data” approach for production purposes, here we’re loading the whole content in memory and then saving on disk when the content has been completely downloaded: really not the best approach if your content is hundred of megabytes, your app will certainly crash.

In order to visually track the progress and then update the user interface, we decided, being coherent of our principles, to keep the application store controller independent on any UI choice. To do this we make use of KVO and Notifications. Essentially when the view controller starts a download, it will set itself and the magazine view as notification observers of the download result, in order to update its status as soon the download terminates (with success or with error):

-(void)downloadIssue:(Issue *)issue updateCover:(CoverView *)cover {
cover.progress.alpha=1.0;
cover.button.alpha=0.0;
[issue addObserver:cover forKeyPath:@”downloadProgress” options:NSKeyValueObservingOptionNew context:NULL];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(issueDidEndDownload:) name:ISSUE_END_OF_DOWNLOAD_NOTIFICATION object:issue];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(issueDidFailDownload:) name:ISSUE_FAILED_DOWNLOAD_NOTIFICATION object:issue];
[[NSNotificationCenter defaultCenter] addObserver:cover selector:@selector(issueDidEndDownload:) name:ISSUE_END_OF_DOWNLOAD_NOTIFICATION object:issue];
[[NSNotificationCenter defaultCenter] addObserver:cover selector:@selector(issueDidFailDownload:) name:ISSUE_FAILED_DOWNLOAD_NOTIFICATION object:issue];
[_store scheduleDownloadOfIssue:issue];
}

Both the cover view and the view controller will need to unregister from the notification center as soon as the download operation terminates. Besides to allow the cover view to keep track of the progress status, as the download starts it will be registered as a KVO observer of the downloadProgress property of the Issue. This means that for each change of this property, that will occur during the downloading phase, the cover view will be informed of the change to update the progress bar (so we have here a separation again of the back-end property, the download progress, from the UI, the UIProgressBar). The cover view will unregister itself as soon as download terminates.

When the download terminates, the Issue instance will copy the downloaded content to the final destination. In the Newsstand framework this destination is specified by the system, in iOS4 will copy it in the Caches directory to be compliant with iCloud requirements (yes, iOS4 doesn’t work with iCloud but our app is the same for both generations of the OS, so we must be good citizens in any case).

In the Newsstand case we’ll also need to update the cover image for the Newsstand icon. We’ll do it with a simple command inside the code that manages the download termination (at the end we also send the end of download notification we mentioned previously):

-(void)connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL {
// copy the file to the destination directory
NSURL *finalURL = [[self contentURL] URLByAppendingPathComponent:@”magazine.pdf”];
ELog(@”Copying item from %@ to %@”,destinationURL,finalURL);
[[NSFileManager defaultManager] copyItemAtURL:destinationURL toURL:finalURL error:NULL];
[[NSFileManager defaultManager] removeItemAtURL:destinationURL error:NULL];
// update Newsstand icon
[[UIApplication sharedApplication] setNewsstandIconImage:[self coverImage]];
// post notification
[self sendEndOfDownloadNotification];
}

Conclusions

This is the conclusion of this tutorial. We decided after a long interval to make an effort to propose a complete app valid for both iOS4 and iOS5 environments. In the code you will find more interesting stuff, e.g. a “hook” to the Store Kit: this is a typical issue not considered by developers when they make applications that sell magazines. In such case storing the issue price in the publisher server is not of help as we must retrieve the pricing information from the only relevant source, that is the App Store. To do this our app must – asynchronously – query the iTunes store for the prices of all the publications and then display them once retrieved. I’m not adding this extra step in the code, just the hook as placeholder for future extensions, but of course if required by our readers I can extend this tutorial further. I would appreciate any suggestion and any contribution in the GitHub hosted code, I would like to see the example code provided with this tutorial as a good skeleton for new apps. If you didn’t enjoy this article, at least you can enjoy the literature classics (and a Django manual…) that I used to create my PDF files.

Carlo Vigiani


Introduction

One of the most appreciated features by iPad users is the possibility to read books, magazines and newspapers. Practically all major publishers are in the App Store with apps dedicated to their products but there also many other minor publishers, in every country, that entered in the iOS world with one or more apps.

Today a publisher that wants to enter in the App Store with his own magazine has several decisions he needs to make. Some of these are:

  • is it better to publish a specific app for the magazine or use a newsstand app as Zinio?
  • in case we decide to use our own app, should we contact an iOS dev to have a tailored product or use a web-based service that provides us in short time with a standard app?
  • should the magazine service be hosted by a third party or by the publisher itself?
  • is it better to re-use existing PDF or make a completely new digital magazine (e.g. if you use the Adobe Digital Publishing suite)?

Of course all these decisions will have impact on development costs, web services hosting and maintenance and finally the magazine design flow.

The author of this post has gained some experience by developing and releasing on the App Store several magazines.This series of articles is based on the experience acquired by developing some custom magazine apps and will try to depict what is the architecture of an iPad magazine app starting from the building blocks and entering into the coding challenges occurring on these blocks. We hope that any developer that should have the chance to build an iPad app can take some benefit reading these articles.

 

Sistema editoriale per piccoli medi e grandi editori che permette di pubblicare quotidiani, magazine, riviste ed altro utilizzando i documenti pdf dell'editore. i3F Editorial inoltre e' un'investimento minimo una tantum , una volta sola, e nn necessità di manutenzione e/o costi aggiuntivi. Tutto resta all'editore.
Publishing system for small, medium and large publishers Editorial i3F and also ‘an investment lifetime, once. Everything stays the publisher.

The starting price for our solution starts from 200 euros for small Authors, a customized solution for publisher wishes ,that contains all the features necessary for most small-medium-sized publishers, starts from 900 euros for medium Publishers and starts from  € 2000 for medium and large publishers.

We are also willing to consider solutions “Full Custom Made” for publishers who need to customize and adapt their models.

For Public Market solution Go on  i3F Editorial web site (http://i3factory.com/editorial)
Examples of App Publish with i3editorial:
(Note our customer pays no maintenance or costs both fixed and variable after the publication of the app):

Farmamese, rivista magazine sistema editoriale iPad iPhone & Android i3editorial.com

Farmamese