i3Factory

La tua Iphone, iPad & Android Application Factory

Visualizza gli articoli con tag Editorial

    Rivista della provincia di Milano

    Rivista della provincia di Milano

     

    La Provincia in Casa ha scelto di entrare nel mercato mobile e tablet con i3Factory utilizzando il sistema editoriale i3F Editorial, una soluzione tecnologicamente all’avanguardia senza alcun costo di gestione. La tecnologia avanzata di i3F Editorial permette agli editori di pubblicare nuovi numeri della rivista o magazine senza alcun costo. Appare incredibile ma è vero.

    La versione per i dispositivi iOS Apple, tutti gli iPhone e iPod Touch (iPhone 3, iPhone5, iPhone 5) e iPad (iPad 3 Retina, iPad 4 Retina, iPad 1, iPad2) la trovate al seguente link:

    https://itunes.apple.com/it/app/la-provincia-in-casa/id606239216?mt=8

    La versione Android per tutti gli smartphone e tablet android (Samsung , Kindle, Sony, Asus, etc..):

    https://play.google.com/store/apps/details?id=org.imaginor (GOOGLE PLAY- Android Market)

    http://www.amazon.com/Provincia-Casa-Milano-italian-Magazine/dp/B00BUL9THS (Amazon App Store – Kindle fire)

     

      i3Factory accompagna il Ministero del Lavoro che attraverso il Sistema Editoriale i3Editorial sbarca su App Store.
      Uno strumento agile per essere sempre aggiornati sul mondo del lavoro. La newsletter di Cliclavoro è un appuntamento mensile che raccoglie le più importanti novità del settore: tendenze del mercato del lavoro, opportunità dall’Europa, interviste a personalità di spicco.

      La Newsletter si articola in 5 sezioni:

      • In apertura
      • Approfondimento
      • L’intervista
      • Dall’Europa
      • Dai Social Network

      Tieniti aggiornato sull’andamento del mercato con dati e informazioni arricchiti da link e contenuti multimediali.
      Per seguire in tempo reale le news dal mondo del lavoro scarica l’applicazione CliComunica.
      Versione Apple iPhone e iPad: https://itunes.apple.com/it/app/clicomunica/id582587332?mt=8

      Versione per Android: https://play.google.com/store/search?q=clicomunica&c=apps

        Questo articolo e’ stato pubblicato dal nostro CTO , Carlo Vigiani,  su icoder magazine, una validissima rivista per gli sviluppartori iOS.

        Uno dei grandi miglioramenti per tutti i proprietari di iPad è la possibilità di portare ovunque le propie rivista preferite o libri, grazie alle dimensioni dello schermo e il peso leggero dispositivo, che permette una  facile lettura. In particolare le relazioni sulle vendite  hanno dimostrato che in un momento di diminuzione mercato della stampa delle pubblicazioni vi è un enorme aumento del numero di abbonamenti alle versioni digitali degli stessi prodotti (il lettore interessato può leggere questo rapporto da MPA: http://www.magazine.org/association/press/mpa_press_releases/mag-mobile-reader-study.aspx)

        Apple sta seguendo questa tendenza con grande interesse, e ciò è abbastanza chiaro se diamo uno sguardo alla evoluzione della
        le caratteristiche di iOS che sono state introdotte dopo il rilascio della versione dedicata a iPad, che è di 3,2.
        In particolare le tappe che sono state raggiunti sono tre, in comune tra i tre principali releases del sistema operativo:

        iOS 3.2 è stata arricchita dal framework CoreText, una tecnologia dedicata al rendering del testo sul display disponibile da tempo su Mac OSX e mai portati nelle versioni precedenti di iPhone OS.

        iOS 4.x ha introdotto il concetto di abbonamento auto-rinnovabile, in aggiunta allo standard di  Acquisti In App, questa funzione è stata
        introdotto dopo lunghe discussioni tra Apple, che applica la commissione del 30% su ogni In App venduta e vieta a qualsiasi altro store esterno più economico l’accesso all’interno dei suoi dispositivi, e gli editori in cerca per le tecniche di fedeltà dei clienti.

        • infine iOS 5.0 ha aggiunto la funzione di Edicola (Newsstand), che fornisce un luogo centrale, una vera e propria app App,  per raccogliere tutte le pubblicazioni e le  magazine  app compatibili e allo stesso tempo fornire una push notification per i nuovi contenuti e automaticamnte fornire a tutti gli abbonati la possibiltà di scaricare automaticamente i nuovi numeri, permettendo di leggere immediatamente le novità e  far risparmiare i tempi (A volte lunghi) necessari per il download.

        Quello che Apple non ha fornito invece è un unica piattaforma di sviluppo per la creazione di applicazioni dedicate ai consumi di riviste. Questo ha portato a numerose iniziative dedicate per aiutare gli editori ad entrare nel mercato iPad con le proprie riviste . Queste iniziative, come ad esempio il nostro sistema editoriale i3F Editorial,  sono state preso da società importanti e ben noti, come ad esempio Adobe con i suoi affari Digital Publishing, e un sacco di molte start-
        up, ognuno con una propria soluzione.

        Come già detto, Apple non fornisce una soluzione unica, ma i developers hanno la disponibilità di una serie di frameworks e tecniche, con diversi livelli di complessità, che prevedono diversi modi di rappresentare la pagina sullo schermo.

        Non c’è una scelta ottimale, poiché la decisione finale deve considerare aspetti che vanno oltre la pura tecnica.

        In questo articolo cercheremo di descrivere queste soluzioni principalmente dal punto di vista dello sviluppatore di applicazioni, ma non dimentichiamo di enumerare i pro e i contro che possono influenzare la decisione dell’editore , come l’agency,  su quale tecnologia adottare.

         

        Panoramica sul page rendering

        Diamo per scontato che voi, lo sviluppatore, siate ad una certo dello  sviluppo di un  applicazione in cui la rivista è stato acquistato, scaricato ed è pronto per essere letta.
        I dati del vostro documento, a questo punto vengono conservati nel file system del dispositivo e possono essere rappresentati da un unico file pdf, o da un insieme di file html e css o una directory contenente files di diversi formati, quali immagini, video, widget HTML5, file di testo.
        Stai quindi per affrontare il problema di prendere una pagina (che nosrmalmente si estende oltre i limiti dello schermo) e la presentazione nello spazio vuoto del vostro UIView dedicato al rendering della pagina.

        Nei prossimi paragrafi il nostro Carlo (CTO di i3factory)  presentera le seguenti metodologie per ottenere questo risultato:

        • il rendering documento pdf
        • pre-rendered visualizzazione delle immagini
        • libero formato di rendering CoreText
        • approccio basato sul web

        Continua a leggere il prossimo articolo su Parte 2: Tecniche di Page Rendering #parte 2 : Riviste e Magazine in PDF

        Questo articolo e’ stato pubblicato dal nostro CTO , Carlo Vigiani,  su icoder magazine, una validissima rivista per gli sviluppartori iOS.

          Il linguaggio HTML5 avrà un profondo impatto sulla Internet.

          Per citare la definizione di Wikipedia, l’HTML5 è un linguaggio di markup per la progettazione delle pagine web attualmente in fase di definizione presso il World Wide Web Consortium.

          iOS 5 introduce 1.500 nuove API per gli sviluppatori, compreso l’accesso icloud, Storage, Newstand e Twitter.
          Apple ha apportato alcune migliorie sul supporto per html, come Safari Mobile che permette di attingere a maggiori porzioni di memoria locale del dispositivo e ai servizi di geolocalizzazione.

          Abbiamo pensato quindi di integrare il supporto all’html5 all’interno del nostro sistema editoriale i3F Editorial.

          Vi segnalamiamo a questo proposito un interessante articolo di autore del Bolg Siteless.Org:
          Bart sta lavorando su un piccolo progetto per la creazione di un generico codice basato su HTML5 per la lettura di riviste come soluzione per l’iPad.

          L’idea di base è che le soluzioni editoriali adottate dalle corporate sono troppo costose per una vasta gamma di editori. Inoltre, queste soluzioni editoriali non sembrano essere di semplice utilizzo e integrazione e molti non sfruttano la tecnologia HTML5, ma sono derivanti da logiche d’informatizzazione ad alto impatto architetturale.

          Crediamo che la semplicità sia la chiave del successo per il mercato delle App online e per questo , come Bart, siamo certi che l’iPad sia un dispositivo meraviglioso per leggere riviste – soprattutto se queste riviste sono ricche di contenuti interattivi.

          Creare un app che ti permette di gestire pubblicazioni multiple, con la possibilità di lettura off-line con performance scattanti non è facile.

          Se qualcuno volesse cimentarsi con un progetto Xcode puo’ trovare il sources code sul blog http://www.siteless.org/books/SitelessMagazine.zip.

          Per una soluzione didattica possiamo provare a dare un’occhiata al framework Baker, Baker framework, Laker compendium and pugpig. Tutto il codice è open source-

          Innanzi tutto il codice è:
          - siteless magazine è il nome del progetto e prende la grafica e altra roba dal sito Siteless.org a scopo di test
          - Minizip per decomprimere
          - Json per il parsing json
          - pugpig reader (ha delle belle pre-rendering snapshot)

          Viewcontrollers:
          - LibraryViewController – qui è dove accadono le cose principali. Nota che le copertine fanno riferimento ad una url nella stringa JSON. Oltre alle funzionalità di sincronizzazione (il pulsante in basso a sinistra ), che cura anche la creazione di istanze di oggetti issueviewcontroller e la gestione del layout
          - IssueViewController – questo è il viewcontroller di una singola pubblicazione. Il Design (xib) è in bozza. Si occupa anche di scaricare / decomprimere una singola pubblicazione e l’archiviazione (che elimina la pubblicazione dal filesystem)
          - ReaderViewController – si prende cura del lettore reale – utilizza il framework pigpug in questa versione open.

          il suo modello misto di storage :
          - Le pubblicazioni sono memorizzate utilizzando core data (database SQLite). È possibile esaminare il database utilizzando il browser dei database SQLite. Come potete vedere, il database non è incluso – viene creato automaticamente se non esiste.

          - Le copertine grafice sono memorizzate sul filesystem – la posizione delle cover sul filesystem viene mantenuta nel database. E’ un path completo – Bart sostiene di un essere incorso in problemi con esso.
          - Le Pubblicazioni (dossier) vengono memorizzate sul filesystem. L’operazione ‘archive’ rimuove la pubblicazione mentre ‘download’ la scarica , poi unzippa e inserisce il riferimento ad esso nel database.
          Il DataModel è nel file xcdatamodel. La classe Issue, copertina e contenuti sono generati da quel DataModel.

          Per verificare che cosa sta succedendo, è facile monitorare la cartella e il database. Ricominciare è anche facile: rimuovere tutto cio’ che si trova in quella cartella (/’user’/Application Support/iPhone Simulator/4.3.2/Applications/’applicationid’/Documents/)

          Il formato JSON è facile da capire, assicurarsi che i numeri di serie delle pubblicazioni siano unici. Sul sito di siteless sono incluse due testissue – (pubblicazione numero 1 e 2, da Laker e Pigpug), mentre le altre non esistono.

          Qualche necessità per rendere questo codice meno didattico:
          - Integrazione del reader. Il reader in questo codice non consente ancora lo scorrimento verticale. Il doppio tap non mostra l’indice. Il pulsante library ha bisogno di essere implemntato. Non aggiornare se si vuole aprire un altra pubblicazione
          - Refactoring di alcuni metodi (alcuni sono troppo lunghi e verbosi)
          - Generalizzare il codice e includerlo nel github (dopo il test)

            Icona Newsstand Icon

            La rivoluzione iOS5

            Molta acqua è passata sotto i ponti da quando abbiamo pubblicato la nostra prima parte di questo tutorial. Ci scusiamo per il ritardo, ma al momento di scrivere eravamo consapevoli delle nuove funzionalità introdotte con iOS5 ma eravamo ancora sotto NDA e non autorizzati a rivelare nulla del SDK. Finalmente siamo ora in grado di fornire l’esempio  della nostra applicazione per riviste e magazine  con compatibilità doppia: iOS4/iOS5 .

            Non passeremo il tempo a spiegare tutte le caratteristiche della funzione Newstand (edicola), tutto sommato stiamo dandovi le informazioni per creare un app per leggere delle riviste e i dettagli d’implementazione Newstand  vanno oltre il nostro scopo originale.
            Abbiamo scritto un tutorial di due parti, presente in inglese nel  blog personale del nostro CTO, che potete leggere qui, e che copre tutti gli aspetti Newstand e le richiesta (da parte di revisori Apple) in caso di abbonamenti.

            In breve, Newstand (edicola) è un nuovo modo di presentare riviste nel iPad e iPhone, dove è sostituita l’icona originale dalla copertina della rivista o giornale, ed è posto sotto uno speciale gruppo dedicato a raccogliere tutte le icone Newstand installate dall’utente.
            Per lo sviluppatore c’è anche un framework, chiamato Newstand Kit, che introduce una nuova metodologia per organizzare, scaricare e installare il contenuto dell’ App.

            L’esempio di applicazione

            La schermata mostra l’aspetto finale dell’ app. Un insieme di nove riviste con ongnuna un differente frutto in copertina.

            È possibile scaricare una rivista, vedere il cambiamento barra di avanzamento mentre l’operazione è in corso e, infine, leggerla. La schermata mostra l’altro aspetto nel Newstand (edicola).
            L’icona tipica è stata sostituita dalla rivista, come la rappresentanza all’interno del gruppo Edicola.
            Invece, se eseguito su un iPad con iOS4 installato apparirà l’icona classica.

            Il codice di un’applicazione completa è disponibile su GitHub. Non considerarla come un codice di produzione, quindi per favore non cercate di riutilizzare così com’è per la vostra app o con i vostri clienti se non avete provato in tutti i possibili casi limite.
            In ogni caso può essere considerato come un valido punto di partenza per le applicazioni reali. In sostanza i principi alla base dell’architettura del codice sono stati descritti nella Parte I di questo tutorial, se non avete ancora letto vi consiglio di saltare al precedente articolo prima di leggere questo, almeno per capire i componenti chiave di tale applicazione.
            Lo scopo di queto tutorial , guida o howto, è quello di capire e tenere la gestione dell’ issues management (controller, da non confondere con “View Controller”) separata il più possibile dalle UI (interfaccie utente). Ciò significa che in teoria il codice che sta dietro Store Manager and Issue Models  può essere riutilizzato anche in un applicazione Mac OSX , in quanto rapporto con cose come la UI è minimo.

            Abbiamo installato questa applicazione utilizzando il modello di base di una singola finestra Xcode (the basic single window Xcode template) e poi aggiunto le due componenti principali del metodo all’avvio dell’applicazione (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;
            }

            I due componenti sono:

            la classe Store, che rappresenta il blocco Store Manager nell’architettura applicazione, questa classe è una sottoclasse di NSObject e non è legata all’interfaccia utente.
            Il ShelfViewController rappresenta l’UI (interfaccia utente) dell’applicazione. E’ collegata allo Store (negozio) utilizzando una proprietà specifica. Si noti che il controller non avrà accesso alle proprietà Store esposte, ma otterrà le informazioni necessarie attraverso una semplice API.
            Avremmo potuto utilizzare un modello di delega (delegate pattern), invece, ma poichè i due blocchi sono blocchi essenzialmente custom in un’applicazione personalizzata, non c’è proprio bisogno di definire un protocollo per la loro interazione. Possiamo dire che la parte del controller è stato suddiviso in due parti, una per l’interfaccia utente (UI), la mensola (the shelf), e uno per il back-end, il negozio (Store). Il loro legame è tale che la mensola dipende dallo Store (strict link), non viceversa.
            Ogni Store per la comunicazione con il prodotto (shelf) utilizza le notifiche.

            L’applicazione è stata poi integrata con le nuove esigenze Newstand nel plist info. Anche in questo caso dare un’occhiata alla documentazione di Apple per una guida dettagliata.

             

            Modelli e Controller

            Abbiamo un modello in questa applicazione, è il modello Issue che rappresenta un numero singolo del magazine o rivista nello Store (negozio) o nella libreria utente (user library). C’è anche un controller, che è il Store. Come abbiam detto questo controller non è un componente di UI (interfaccia utente), ma l’applicazione di back-end è autosufficiente con questi due componenti. In teoria siamo in grado di recuperare lo statuo negozio e riviste scaricate (store status and download magazines) anche senza alcuna UI (interfaccia utente). Questo è un concetto di base in applicazioni per riviste (Magazine Apps), in cui molti eventi avvengono in background non sono legati all’interazione diretta dell’utente : questo significa che l’applicazione dovrebbe essere in grado di eseguire diverse operazioni, anche se l’interfaccia utente non è stata caricata.

            Il ruolo della “issue class” è quello di rappresentare tutte le proprietà rilevanti rivista, che sia un identificatore univoco, un titolo, una data di uscita, un collegamento alla immagine di copertina, ovviamente il link (URL) al contenuto (che può essere un file PDF, un file epub o un file zip per i pacchetti complessi).
            In particolare, l’identificatore univoco (unique identifier) è un pezzo di dati che deve essere mantenuta lungo la vita dell’ issue: è l’unico modo per identificare univocamente un determinato issue, indipendentemente da problemi di localizzazione (ad esempio, il titolo può cambiare in diversi paesi, ma non l’ID univoco). Inoltre è il link per il modo in Newsstand (edicola) per identificare le issue  (il nome del campo NKIssue) e può anche essere utilizzato per collegare il prodotto con l’App Store, se abbiamo intenzione di implementare gli Acquisti In App o In App Purchases.

            Oltre a  questo ruolo, le issue class avranno un ruolo centrale nel download di una rivista. In sostanza la classe Store (Store class) potra fare uno schedule e quindi potra’ programmare un download, ma questo sarà monitorato  dalla issue class (progress) e poi terminare (installazione effettiva della rivista/magazine ).

            Infine, questa classe ha limitate capacità di rappresentare una rivista già scaricata e disponibile nella libreria utente (user library). Per questo mettiamo a disposizione la semplice isIssueAvailableForRead  che sara utilizzata da parte dell’interfaccia utente per sapere quali interventi sono possibili con un issue (leggere o scaricare) ed eventualmente visualizzarne il contenuto.

            La classe Store è il controller app. E ‘inizializzato all’inizio delle app e la sua istanza non è mai rilasciata. Subito dopo l’inizializzazione DI questa classe verrà recuperato il contenuto dello store (negozio) dal server dell’editore.

            In questo esempio abbiamo deciso di attuare il contenuto negozio come un semplice elenco delle proprietà, e poi istruire il negozio per recuperare questa lista di proprietà, decodificarlo e creare gli oggetti di emissione e, infine, scaricare le loro immagini di copertina. Tutto questo è fatto in modo asincrono utilizzando la Grand Central Dispatch e alla fine una notifica verrà inviata per informare tutti gli oggetti interessati (in particolare il controller della vista) che i contenuti Store sono pronti e l’interfaccia utente può essere tranquillamente visualizzata.
            Si noti che il negozio è stato rappresentato da un property status. Abbiamo ignorato il  setter method, di inviare una notifica che informa ogni osservatore interessato del nuovo stato. Per semplicità abbiamo deciso di limitare i possibili stati di “non inizializzato”, “download”, “pronto” e “errore”. Una applicazione più compless può introdurre gli stati extra se necessario. Infine come ripiego in caso di collegamento mancante (l’utente deve essere in grado di accedere al suo / suoi contenuti, anche se non collegato a Internet) si potrà ricaricare una copia salvata in locale del negozio.

            Il pezzo centrale del codice è nel metodo downloadStoreIssues della classe, che riportiamo di seguito:

            -(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;
            }
            });
            }

             

            Si noti che nel codice qui sopra, per semplicità, abbiamo messo in coda il  download della copertina (cover) subito dopo il property list download (download elenco di proprietà).
            Probabilmente questo non è il modo migliore per fare questo, stiamo aggiungendo ulteriori networking steps  prima di presentare lo status dell’applicazione, con possibili ritardi se le condizioni della rete non sono buone. Possiamo fare questo in un esempio in cui sappiamo che il numero di problemi è limitato, probabilmente in una applicazione vera e propria ha più senso farlo in un processo in background e quindi notificare all’interfaccia utente di aggiornare il suo status ogni volta che una nuova copertina è pronta da visualizzare.

             

            La “View Controller”

            L’interfaccia utente si sveglia immediatamente, e cambierà il suo aspetto, basato sulle comunicazioni provenienti dal negozio. Quando il centro di notifica consegnerà al negozio “Sono pronto” come  messaggio per l’interfaccia utente, questo verrà caricato tutte le rappresentazioni problema UI (la classe CoverViewè  nel codice, una view di base con la logica dell’applicazione davvero minimo) e mostrare la shelf (mensola) all’ utente.

            A questo punto l’applicazione ha terminato la sua elaborazione back-end ed è in attesa di comandi dell’utente. Qui abbiamo due possibilità:

            Una rivista è stata scaricata, l’utente vedrà un pulsante “Leggi”, cliccando su di essa egli sarà in grado di leggerla.
            Nel nostro esempio tutti i nostri contenuti sono costituiti di file Pdf, abbiamo deciso di utilizzare il framework Quick Look in iOS, che è sufficiente per i nostri scopi.
            Una rivista non è ancora stata scaricata, l’utente vedrà un pulsante “Download”, cliccandoci sopra si avvia il download e ti mostrano una barra di avanzamento (progress bar). Alla fine avremo bisogno di sostituire l’etichetta del pulsante e nascondere il progress. Vedremo questa parte in modo più dettagliato.

            La view controller dipende dallo Store (negozio). Al fine di ottenere le informazioni sull’issue(numero dell’issue, il dettaglio di ogni numero/issue) questa non avrà accesso direttamente alle proprietà del negozio, ma userà una API molto semplice, fatta di tre metodi:

            /* “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;

            Basandoci su questa informazione, e sulle propieta’ dell’ Issue (properties), si creerà la Issue view representation (CoverView) e sarà visualizzata sullo schermo.

            Il download di una rivista o giornale

            In una Magazine App ci sono tre sezioni critiche:
            recuperare e visualizzare i contenuti negozio, scaricare il contenuto e, infine, leggerlo (un buon lettore PDF o EPUB  è obbligatorio in un app del genere, non è lo scopo di questo tutorial, mirato a spiegare l’architettura e le tecniche necessarie per rendere tale applicazione, ma è una parte rilevante l’esperienza utente).

            Il nostro approccio nel download della rivista è che l’utente deve essere completamente libero di fare qualsiasi azione e tale azione non deve interferire con il risultato del download.
            Ora molte applicazioni sono solite prendere una scorciatoia: hanno messo uno spinner al centro dello schermo, poi bloccano qualsiasi interazione dell’utente con gli oggetti dell’interfaccia utente dietro lo spinner per poi chiedere all’utente di aspettare.
            E ‘facile fare questo, ma non è la migliore esperienza utente.
            Durante attesa l’utente deve poter leggere un altro numero (issue), poter navigare all’interno del negozio o decidere di passare temporaneamente a un’altra applicazione o infine può perdere temporaneamente il collegamento con la rete.
            Newsstand Kit fornisce una metodologia a livello di sistema che semplifica (in alcuni casi) la vita degli sviluppatori, ma al tempo stesso elimina ogni scusa per non fare un buon lavoro in termini di user experience.

            Non appena l’utente attiva un nuovo download, il view controller invierà la sua richiesta di download alla classe Store. Nel codice qui sotto potete vedere il scheduleDownloadOfIssue:code.
            Questo metodo prepara la richiesta di rete e la invierà in background. Si noti come abbiamo diviso il comportamento applicazione in base alla versione del sistema operativo siamo in. Se è iOS5 allora dobbiamo utilizzare l’approccio Newsstand-Edicola – dove il download saranno gestiti dal sistema in una coda Edicola -, se siamo in iOS4 faremo seguire una metodologia classica basata su NSOperation: in questo caso mi sono perso per la semplicità per ottenere la  content length del contenuto da scaricare, nel caso iOS4 la barra di avanzamento non viene visualizza. Questa informazione è invece fornita “for free” da 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];
            }

            Nei due casi mi piacerebbe sottolineare il fatto che lo “Store” avvia l’operazione di download, ma poi  delega ogni ulteriore elaborazione alla parte interessata, l’ Issue da scaricare. Così sarà la classe Issue che monitorerà il download e poi lo finalizzerà.

            La issue class (classe di Emissione) si comporterà come delegato dell’operazione di scaricamento innescata dalla Store class. Il delegate protocolrisulta differente se si sta utilizzando “Edicola” oppure no. Nel primo caso sarà necessario per essere compatibile con il protocollo NSURLConnectionDownloadDelegate mentre nel secondo caso il protocollo da rispettare sara’ il  non documentato (o: documentato solo nel file header ) NSURLConnectionDataDelegate che è una “spin-off” di il NSURLConnectionDelegate classico.
            La differenza tra i due protocolli è che il primo scriverà nel file system, l’altro in memoria.
            Anche in questo caso non usare il “data” approach a fini di produzione, qui si sta caricando tutto il contenuto in memoria e quindi salvando su disco quando il contenuto è stato completamente scaricato: in realtà non è l’approccio migliore se il contenuto è centinaia di megabyte, la vostra applicazione sarà certamente crash.

            Al fine di monitorare visivamente l’avanzamento e quindi aggiornare l’interfaccia utente, abbiamo deciso, essendo coerente dei nostri principi, per tenere l’ application store controller  indipendente per ogni scelta dell’interfaccia utente. Per fare questo ci avvaliamo di KVO e notification. In sostanza quando il view controllerinizia un download, sarà impostato e la “magazine view” come “notification observers” del risultato download, al fine di aggiornare il suo status non appena termina il download (con successo o con errore):

            -(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];
            }
            Sia con la “cover view” che il “view controller”, sarà necessario annullare la registrazione dal centro della notifica non appena termina l’operazione di download. Oltre a permettere la visione di copertura per tenere traccia del progress status, come il download comincia, sarà registrato come “KVO observer” della proprietà DownloadProgress del “issue”. Questo significa che per ogni cambiamento di questa proprietà, che si verifica durante la fase di scaricamento, la cover view sara’ informata del cambiamento per aggiornare la barra di avanzamento (quindi abbiamo qui una separazione di  back-end property, del download progress, dell’ UI, e la UIProgressBar). La cover vieweliminarà la registrazione non appena termina il download.Quando termina il download, l’ Issue instance  (istanza di emissione) copierà il contenuto scaricato fino alla destinazione finale. Nell’ambito Newstandquesta destinazione è specificato dal sistema, in iOS4 lo copia nella directory di cache per essere compatibile con i requisiti icloud (sì, iOS4 non funziona con icloud ma la nostra applicazione è la stessa per entrambe le generazioni del sistema operativo, quindi dobbiamo essere buoni cittadini, in ogni caso).Nel caso Newstand avremo anche bisogno di aggiornare l’immagine di copertina per l’icona Edicola. Lo faremo con un semplice comando all’interno del codice che gestisce la cessazione download (alla fine dobbiamo anche inviare la notifica di fine download di cui abbiamo parlato in precedenza):
            -(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];
            }

            Conclusioni

            Questa è la conclusione di questo tutorial. Abbiamo deciso dopo un lungo intervallo di fare uno sforzo per proporre una applicazione completa valida sia per ambienti iOS4 e iOS5 . Nel codice si trovano cose più interessanti, ad esempio un “aggancio” allo Store Kit: questo è un problema tipico non considerato dagli sviluppatori quando fanno le applicazioni che vendono magazines.
            In tal caso la memorizzazione del prezzo del’issue nel server dell’editore non è di aiuto poicheì dobbiamo recuperare le informazioni sui prezzi alla fonte, che è l’App Store. Per fare questo la nostra applicazione deve – in modo asincrono – fsre query su iTunes Store per ottenere i prezzi di tutte le pubblicazioni e quindi visualizzarle una volta recuperate.

            Non abbiamo aggiunto questo ulteriore passaggio nel codice, solo il “gancio” per future estensioni, ma ovviamente, se richiesto dai nostri lettori la avremo possibilità di estendere ulteriormente questo tutorial.

            Have a nice Code with

            Carlo Vigiani

               

              I3Factory World LLc published a new app with owr i3F Editorial System. The most simple and usefull system of owr developing department.

              Disponibile su App Store

              http://itunes.apple.com/app/id455225634

                Schermate dell’applicazione

                Un’applicazione per la lettura di riviste si compone principalmente di 3 schermate principali, indicate in figura

                (sebbene ci si riferirà in seguito all’iPad, tutte le considerazioni sono valide anche per l’iPhone e l’iPod Touch)

                 

                Applicazione iPad per riviste e Magazine

                Sviluppo App per Magazine

                 

                La prima schermata  rappresenta lo Store ossia la vetrina delle pubblicazioni. Questa è di solito la prima schermata che viene presentata all’utente (con l’eventuale eccezione dello splash screen) e visualizza le copertine e le informazioni principali dei numeri attualmente in vendita, in genere con particolare evidenza per l’ultimo numero. Tutti i numeri presentati sono acquistabili, dove per acquistabile si intende anche nel caso la rivista fosse gratuita, ossia venduta a prezzo zero.

                Tipicamente in un’app per riviste si ha una sola testata a disposizione, per cui la vetrina sarà limitata all’ultimo numero a disposizione e un insieme di numeri precedenti selezionati dall’editore. Per riviste con periodicità mensile in genere si raccomanda la visione degli ultimi 12 o 24 numeri, per riviste con cadenza settimanale non conviene appesantire troppo la vetrina limitandosi alla visualizzazione degli ultimi 3 o 6 mesi di pubblicazioni, eventualmente fornendo la possibilità all’utente di una ricerca in archivio per poter accedere a numeri più vecchi.

                Chiaramente per app più complesse, esempio multi testata o per librai, l’organizzazione della vetrina dovrà essere di tipo gerarchico, consentendo ad esempio una scelta iniziale per categorie o testate. Inoltre la rappresentazione grafica può essere di diversi tipi: a copertine scrollabili, a griglia, con effetto cover flow, su scaffale ecc.

                Di ogni pubblicazione presentata in vetrina viene in genere presentata la copertina, il numero, la data di pubblicazione, il prezzo, eventualmente un breve sommario, oltre che ai bottoni necessari all’utente per poter effettuare la sua scelta. Questi bottoni consentiranno l’acquisto (o il download diretto nel caso di prodotti gratuiti) e la possibilità di effettuare una preview (che può avvenire on-line oppure mediante il download di un numero ridotto o infine per presentazione di alcune miniature significative).

                Una volta che la procedura di acquisto è completata, la rivista viene immediatamente copiata nella Libreria utente. Questa schermata ha lo scopo di mostrare all’utente tutte le pubblicazioni acquistate. La presentazione grafica potrà essere simile a quello dello Store oppure differente, mentre diverse saranno le azioni possibili. Oltre ovviamente al bottone “Leggi”, si dovrà prevedere un certo numero di azioni legate alla struttura dell’applicazione. Per esempio nell’eventualità che concluso l’acquisto si sia reso impossibile effettuare il download, allora al posto del bottone “Leggi” dovrà presentarsi un bottone “Download”. Oppure l’utente può decidere di rimuovere completamente la rivista già letta dallo scaffale (“Cancella”) o di liberare spazio nella memoria permanente dell’iPad cancellando il file che contiene la rivista ma lasciando la copertina per poter effettuare un successivo download (“Archivia”).

                Infine la terza schermata fa riferimento al Reader, ossia la pagina dedicata alla fruizione dei contenuti. Quest’ultimo può essere un lettore di file pdf di tipo generale, o un lettore di ePub, oppure un lettore customizzato nel caso la rivista fosse rappresentata con formati non standard  o infine (ma sconsigliato) il Preview interno al sistema operativo (sostanzialmente il lettore di documenti integrato in Safari).

                Alcuni editori potrebbero richiedere che le funzioni Libreria e Store siano unificate in un’unica schermata. Questa scelta è comune a molte applicazioni già presenti sul mercato, compito dell’applicazione sarà quello di mostrare chiaramente e in maniera opportuna le varie scelte possibili. Ad esempio non avrà senso visualizzare il prezzo della pubblicazione se quest’ultima è già stata acquistata. Inoltre se la pubblicazione è stata acquistata, letta e archiviata sarebbe più opportuno presentare il bottone “scarica” piuttosto che il bottone “acquista” per non disorientare il cliente (sebbene la policy dell’App Store sia tale per cui successivi riacquisti dello stesso prodotto non comportino un ulteriore addebito in carta di credito). Infine si dovrà prevedere uno spazio apposito per la gestione degli abbonamenti nel caso che la pubblicazione prevedesse questa forma di acquisto.

                Architettura

                Un’app correttamente organizzata dovrà disaccoppiare, per quanto possibile, i moduli gestionali da quelli visuali. Questo perché diversi editori potrebbero richiedere importanti variazioni grafiche e di approccio sull’interfaccia utente, ma ovviamente lo sviluppatore deve cercare di riutilizzare per quanto possibile i blocchi critici legati alla gestione dei dati. L’approccio da seguire è quello suggerito da Apple per la programmazione con Cocoa e denominato MVC (Model View Controller) che va implementato fin dai più alti livelli.

                Riportiamo di seguito un diagramma a blocchi funzionale.

                Il Publisher Server indicato nel diagramma con una nuvola non fa parte dell’applicazione ma costituisce l’insieme dei servizi internet a cui si appoggia l’app. Esso consiste di solito della infrastruttura server per l’immagazzinamento e la fornitura dei contenuti (quindi delle riviste) oltre che dei servizi web di cui si avvarrà l’applicazione per poter costruire la sua vetrina. Questo back-end può essere gestito direttamente dal cliente sui suoi server, oppure su servizi dedicati quali Amazon S3 o infine direttamente dallo sviluppatore (in tal caso si raccomanda una buona larghezza di banda e un tempo di indisponibilità veramente ridotto).

                Lo Store Manager è uno dei blocchi funzionali centrali dell’applicazione. Il suo ruolo è sia quello di comunicare con il back-end dell’editore sia quello di fornire alle altre componenti dell’app i dati che verranno di volta in volta richiesti. La progettazione di quest’oggetto deve essere quindi particolarmente curata e dovraà essere assolutamente svincolata dall’interfaccia utente.

                All’apertura dell’app lo Store Manager si inizializzerà e quindi provvederà a contattare il server per recuperare la lista aggiornata delle pubblicazioni in vetrina. Come questo avviene è strettamente legato alle caratteristiche del servizio fornito dal server. Qui possiamo usare un semplice file XML, JSON o PLIST – nel caso di prodotti con pochi numeri pubblicati – o un insieme ben più complesso di API che permetteranno di muoversi all’interno di un catalogo ben più vasto o di poter fare ricerche (per autore, titolo, genere nel caso di libri).

                Val la pena sottolineare che la comunicazione server – applicazione è avviene principalmente in una direzione, dato che la gran parte del flusso di dati procede dal server verso l’app. La comunicazione inversa dall’applicazione al server sarà limitata alla gestione delle query e alla fornitura di alcuni dati quali la registrazione delle transazioni di acquisto o l’invio di dati di monitoraggio (“analytics”). Si raccomanda allo sviluppatore di gestire la comunicazione tra Store Manager e server per mezzo di un livello di intermediazione. Il vantaggio di questo approccio è che lo Store Manager esporrà un insieme di API generiche e ben identificate mentre il livello intermedio di comunicazione si comporterà da driver specifico per il tipo di back-end. In questa maniera sarà possibile riutilizzare lo Store Manager per applicazioni che pur presentano back-end molto differenti.

                Ogni qual volta un certo numero di informazioni sulle riviste viene trasmesso dal server all’applicazione, lo Store Manager si occuperà di creare gli Issue Model.

                L’issue model è la rappresentazione logica di ogni singola rivista ed in genere è costituito da un identificatore univoco (non visibile all’utente), un titolo, una data di pubblicazione, un’immagine di copertina, una URL di download (nel caso il numero fosse gratuito) e una URL di preview, un’eventuale indice o sommario, una breve descrizione dei contenuti. Si noti che tra queste informazioni è stata volutamente tralasciata l’informazione di prezzo. Questo perché attualmente l’unica forma autorizzata di acquisto on-line tramite iPad deve avvenire per mezzo dell’In App Purchase (App Store) e le informazioni di prezzo derivano da quest’ultimo. Ciò significa che lo Store Manager dovrà farsi carico, una volta raccolte le informazioni sui vari numeri, di contattare l’App Store per verificare l’effettiva vendibilità del prodotto e conoscere il prezzo di vendita espresso nella valuta indicata dal cliente nelle impostazioni di sistema.

                Inoltre l’issue model potrà cambiare durante il ciclo di vita all’interno dell’app. Questo perché una volta che l’utente avrà provveduto all’acquisto si dovrà senza indugio memorizzare localmente l’informazione ottenuta. Inoltre può essere elegante poter fornire una vista della vetrina anche in assenza di connessione internet, se non altro per non presentare l’app con un laconico messaggio di errore e una vetrina vuota (in pratica come un negozio che nel giorno di chiusura abbassasse le saracinesche). E’ vero che non si potrà concludere nessuna transazione ma se non altro i prodotti saranno visualizzabili. Questi motivi giustificano la presenza del Local Storage come copia locale dei dati associata agli Issue Model.

                Nella parte inferiore dello schema precedente abbiamo indicato i due blocchi che si occupano dell’interfaccia utente, ossia la Store View e la Library View (abbiamo volutamente escluso il Reader dato che esso si comporta come un componente aggiuntivo – sebbene essenziale – non vincolante ai fini dell’architettura). In questo schema le due viste sono state volutamente tenute separate per evidenziarne la diversa natura, ma ricordiamo che in molti casi possono essere unificate in un’unica schermata.

                Al fine di poter garantire l’approccio MVC, le due viste comunicheranno con lo Store Manager per mezzo di un protocollo di delega (delegate protocol). In sostanza la vista farà delle opportune richieste allo Store (quanti numeri ci sono? quali sono i numeri?) e si comporterà di conseguenza per la rappresentazione visuale. La comunicazione sarà di tipo bidirezionale (questo perché la vista deve trasmettere le scelte dell’utente allo Store) e occorrerà prevedere anche una comunicazione asincrona basata sulle notifiche o sul KVO (key-value observing). Il motivo di quest’ultima richiesta nasce dal fatto che lo Store Manager in genera lavora indipendentemente dal fatto che lo Store View stia facendo o meno delle richieste, ma quest’ultimo ha bisogno di essere aggiornato nel caso vi fossero delle novità sostanziali. Esempio: stiamo sfogliando la vetrina, quando termina il download di un numero precedentemente acquisito. In tal caso la Store View dovrà essere aggiornata dell’avvenuto cambiamento e modificare la grafica in maniera adeguata. Oppure: decidiamo di monitorare il progresso del download di un numero, sarà opportuno che la Store View osservi l’andamento del progresso per poter aggiornare la progress bar in maniera opportuna.

                Lo Store Manager infine dovrà mantenere i contatti con due servizi forniti da Apple: l’In App Purchase e il Newsstand.

                Abbiamo già introdotto in precedenza l’In App Purchase. Ricordiamo che ad esso si accede tramite il framework integrato Store Kit. Anche qui è buona norma avvalersi di un’interfaccia semplificata nello Store Manager e delegare il lavoro di comunicazione con lo Store Kit a moduli adhoc. Un ottimo esempio open-source e’ l’MKStoreKit. Inoltre la presentazione dello store (non mostrata nel diagramma) avverrà in maniera modale per poter catturare l’attenzione dell’utente e costringere quest’ultimo a dedicarsi esclusivamente all’operazione di acquisto.

                L’altro servizio è il Newsstand. Quest’ultimo sarà parte integrante di iOS5 che al momento in cui scriviamo è ancora in beta. Come sviluppatori siamo legati all’NDA con Apple per cui ci limiteremo a esporre del Newsstand solamente il materiale marketing presente nel sito di Apple. Fondamentalmente il newsstand rappresenterà una sorta di ufficio centrale per la gestione delle pubblicazioni in sottoscrizione e si presenterà all’utente finale come uno speciale folder contenente le copertine degli ultimi numeri delle app installate nel sistema. Un’app su iOS5 non potrà fare a meno di dover essere compatibile con il Newsstand.

                Nel prossimo articolo entreremo nel dettaglio dei vari blocchi implementativi e cominceremo la costruzione di una semplice app per la lettura di riviste.

                L’articolo è disponibile in inglese su iOS Blog.

                 

                
                		


                  Sin dal momento dell’ introduzione dell’iPad nel mercato,uno dei generi più apprezzati di applicazioni è stato senza dubbio quello delle app per poter leggere libri, rivieste e giornali. Durante il suo anno di vita, tutti i maggiori editori hanno reso disponibili per iPad le loro principali testate, a cui si sono aggiunti – tra gli editori minori – inizialmente un manipolo di coraggiosi e poi, visto il numero straordinario di dispositivi venduti in poco tempo, tantissimi editori si sono a poco a poco convinti a portare i loro prodotti sul tablet di Apple. Nonostante le potenzialità di guadagno siano ancora da discutere – e nel mondo dell’editoria si stia ancora cercando la strada giusta per rendere profittevole questo tipo di attività (dato che comunque vige la regola non del tutto giustificata che ciò che si trova su Internet debba essere gratis) – senza dubbio esiste per gli editori un’ampia possibilità di scelta su come entrate nell’App Store.

                  Attualmente un editore si trova a dover compiere un certo numero di scelte, le quali a loro volta influenzeranno i costi di sviluppo, di manutenzione di un eventuale server e infine il flusso stesso di preparazione della rivista. In particolare l’editore dovrà:

                  • scegliere se è preferibile pubblicare la sua testata con un’app specifica, o affidarsi ad app di tipo “newsstand” del tipo di Zinio
                  • decidere se contattare una software house per uno sviluppo dedicato, o affidarsi a dei servizi su internet che consentono una pubblicazione più rapida ma con possibilità di personalizzazione limitate
                  • verificare se converrà ospitare i servizi di back-end su un proprio server o utilizzando un servizio di terze parti
                  • infine dovrà decidere se mantere il proprio flusso di pubblicazione via file pdf o affidarsi ad una soluzione completamente diversa che però potrebbe avere un grande impatto nel flusso di preparazione del prodotto.
                  Noi di i3factory ci siamo nel tempo specializzati nell’offrire prodotti che sono sicuramente “custom”, ossia prodotti adattati alle esigenze del cliente, riuscendo a realizzare il prodotto con costi ragionevoli e in tempi abbastanza rapidi, il tutto rimanendo aggiornati di continuo con le novità sfornate da Apple ad ogni rilascio di una nuova versione del sistema operativo e fornendo un prodotto di qualità.
                  In questa serie di articoli mettiamo in campo le nostre conoscenze per spiegare come è organizzata un’app di lettura di riviste per iPad (ma i concetti sono adattabili per app destinate alla pubblicazioni di libri e giornali, tenendo conto delle rispettive peculiarità). Premettiamo che sebbene l’argomento sia inizialmente di natura generale, via via nei prossimi articoli approfondiremo la questione e ci rivolgeremo prettamente alla platea degli sviluppatori.
                  Ricordiamo che questi articoli vengono riportati in lingua inglese nel sito iOS blog

                   

                    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.

                    Sistema editoriale per piccoli medi e grandi editori i3F Editorial inoltre e' un'investimento una tantum , una volta sola. Tutto resta all'editore.

                    Diamo i numeri?

                    La nostra soluzione, con personalizzazioni richieste dal cliente,  e dedicata ai nostri agenti è stata progettata per:

                    a)  Autori indipendenti

                    b)  Piccoli-medi editori

                    c)  Medi e grandi editori.

                    d) Produttori di cataloghi

                    NB: Per tutte le offerte il nostro sistema non necessita di Costi di manutenzione o canoni. Il costo e’ una sola volta (una tantum) e non dipende dal numero di download o dal numero di utenti / lettori.
                    La soluzione i3F Editorial non genera alun costo fisso o variabile.

                    Siamo sempre disponibili a valutare anche soluzione “Custom Made“, per gli Editori che hanno esigenze di personalizzazione e adattamento ai propri modelli.

                    Offerte in corso:

                    Sistema Automatizzato per grande pubblico direttamente sul sito i3F Editorial (http://i3factory.com/editorial)