i3Factory

La tua Iphone, iPad & Android Application Factory

Visualizza gli articoli con tag iOs5

    Spesso ci capita di dover aggiornare le nostre applicazioni con  le immagini ad alta risoluzione necessarie per il nuovo iPad (iPad 3 o iPad 4). Fortunatamente il nuovissimo iPad Mini ha mantenuto la stessa risoluzione del primo degli iPad che è di 1024 x 768 pixels.
    Poichè non è sempre semplice trovare i documenti ufficali di  Apple , in questo articolo ho nuovamente raccolto tutte le informazioni di cui abbiamo bisogno per aggiornare le icone, le immagini di intro o splash, e così via.

    Innanzi tutto partiamo da questa utile tabella:

    Device/Screen File Name (PNG) Icon Size (pixels)
    iPhone and iPod
    Application Icon for iPhone (retina display) Icon@2x.png 114 x 114
    Application Icon icon for iPhone Icon.png 57 x 57
    Settings/Spotlight icon for iPhone (retina display) Icon-Small@2x.png 58 x 58
    Settings/Spotlight icon for iPhone Icon-Small.png 29 x 29
    Launch image Portrait (retina display) Default@2x.png 640 x 960
    Launch image Portrait Default.png 320 x 480
    iPhone 5
    Launch image for iPhone 5 Portrait (retina display) Default-568h@2x.png 640 x 1136
    iPad
    Application Icon for the new iPad (retina display) Icon-72@2x.png 144 x 144
    Application Icon for the iPad Icon-72.png 72 x 72
    Settings/Spotlight icon for iPad Icon-Small-50@2x.png 100 x 100
    Settings/Spotlight icon for iPad Icon-Small-50.png 50 x 50
    Launch image Portrait (retina display) Default-Portrait@2x.png 1536 x 2008
    Launch image Portrait Default-Portrait.png 768 x 1004
    Launch image Landscape (retina display) Default-Landscape@2x.png 2048 x 1496
    Launch image Landscape Default-Landscape.png 1024 x 748
    iTunes App Store
    App icon for the App Store (retina display) iTunesArtwork@2x.png 1024 x 1024
    App icon for the App Store iTunesArtwork.png 512 x 512

     

    Ricordiamo che con il passaggio da iOS 5 a iOS 6 è nato il nuovo iPhone 5, insieme con l’iPod touch di 5 ° generazione.
    Questi nuovi dispositivi Apple hanno solo un grande cambiamento che aggravia il lavoro di sviluppo delle App: la risoluzione dello schermo.
    Questi dispositivi hanno un ampio schermo 4″ , WDVGA (Wide VGA doppia) 640 × 1136 pixels, 326 DPI-Retina display.
    Questi dispositivi hanno la stessa larghezza 4/4S iPhone ma più 176 pixel di altezza in modalità Portrait.

    App Icon Template

    Segnalo nuovamente, come ho gia fatto in un’altro articolo, questo utilissimo tool scaricabile direttamente dal sito “appicontemplate.com” .

    Scaricando il file otterrete un modello PSD del’ icona dell’App che, attraverso oggetti avanzati in Photoshop, vi permette di automatizzare il processo di esportazione delle varie dimensioni del file icon.png che devono essere necessariamente incluse nel bundle di ogni iOS App.

    Attraverso questo modello Photoshop potremo modificare solo l’icona di dimensione più grande e verrà automaticamente eseguito il rendering che permetterà di avere le icone di dimensioni minori attraverso un veloce flusso di lavoro.
    Questo modello è stato creato dal designer danese Michael Flarup.

    Come si usa (How to) App Icon Template ?
    Il modello funziona con Photoshop CS2 o versioni successive.
    Basta aprire il file PSD con la vostra versione di Photoshop e fare “clic destro” sul LAYER (Livello) chiamato “EDIT THIS SMART OBJECT” (MODIFICARE QUESTO OGGETTO SMART) e premere  su ’Edit Contents’ (“Modifica contenuto”).
    Verrà aperto il file Icon.psb e potrete creare il vostro Artwork  in questo canvas (quadro).
    Dopo aver salvato il Icon.psb, dovrebbe essere automaticamente eseguito il rendering per le diverse dimensioni del file PSD principale .
    E’ possibile utilizzere le Actions (azioni automatizzate) di Photoshop che sono in bundle con la risorsa per esportare i file dell’icona nelle versioni squared and rounded corner (squadrate e arrotondate).

    Buon Design!

      Perché parliamo di Produzioni video cenematografiche

      Si potrebbe pensare che la gestione video sia limitata ad applicazioni come iMovie o Vimeo e a una nicchia di esperti video. Invece può essere esteso ad una gamma più ampia di applicazioni, non è essenzialmente limitato a editing video. In questo articolo forniremo una panoramica del Framework AV Foundation applicato su un esempio pratico.

      Nel nostro caso particolare, la sfida era quella di creare un’applicazione che, partendo da una serie di clip video esistenti, fosse stata in grado di costruire una storia fatta collegando un sottoinsieme di queste clip sulla base di decisioni prese dall’utente durante l’interazione con l’applicazione.
      Il gioco finale è un insieme di scene, girato in luoghi diversi, che compongono una storia. Ogni scena è composto da un prologo, una conclusione (epilogo) e una serie di piccole clip che verranno eseguite dall’applicazione sulla base di alcune scelte fatte dagli spettatori – utenti- giocatori.  Se le scelte sono corrette, lo spettatore sarà in grado di riprodurre tutta la scena fino al suo lieto fine, ma in caso di errore dovrà tornare sulla scena prologo iniziale o in una certa scena intermedia. Lo schema seguente mostra un possibile schema di una tipica scena: un prologo, un flusso vincente (verde) alcuni rami (giallo sono intermedie, il rosso stanno perdendo filiali) e di un lieto fine. Così gli spettatori da qualche parte nel TRACK1 saranno chiamati a prendere una decisione, se lui / lei è in quel momento in gioco continuerà con TRACK2, se non entrerà nel giallo Track4, e così via

       

      iPhone & iPad: Movie Game Storyboard
      Quello che abbiamo tra le mani è la serie completa di tracce, ogni traccia rappresenta una sottosezione specifica di una scena, e uno storyboard che ci fornisce le regole da seguire per costruire la storia finale. Così lo storyboard è fatto dalle scene, dalle tracce del compongono ogni scena e dalle norme che stabiliscono il flusso attraverso queste tracce.
      La sfida principale per lo sviluppatore è quello di mettere insieme queste clip e riprodurre un video in base allo stato attuale dello storyboard, quindi passare alla successiva, selezionare un nuovo clip di nuovo e così via: tutto deve trascorrere fluidamente senza interruzioni.
      Lo spettatore deve prendere le decisioni, interagendo con l’applicazione-gioco e questo può essere fatto sovrapponendo al film con alcuni controlli personalizzati.

      AV Foundation Framework

      Sarebbe impossible raggiungere gli obiettivi spiegati nel paragrafo precedente utilizziando lo standard Media Framework view controllers, MPMoviePlayerController e MPMoviePlayerViewController. Questi conrollers sono buoni per riprodurre un filmato e fornire i controlli di sistema, a schermo intero e la rotazione del dispositivo di sostegno, ma assolutamente non adatti per i controlli avanzati.
      Dopo il rilascio di iPhone 3GS dell’utility per la fotocomara avevamo la possibilità di fare un po ‘di tagli e l’esportazione, ma queste capacità non sono state date agli sviluppatori attraverso le funzioni pubbliche del SDK. Con l’introduzione di iOS 4, l’attività svolta da Apple con lo sviluppo delle app iMovie ha dato agli sviluppatori un ricco insieme di classi che consentono la manipolazione completa dei video . Tutte queste classi sono state raccolte ed esportate in un unico framework pubblico, denominato AV Foundation. Questo framework esiste da iOS 2.2, a quel tempo era dedicato alla gestione audio con la ben nota classe AVAudioPlayer, poi è stato esteso in iOS 3 con il AVAudioRecorder e le classi AVAudioSession ma il set completo di funzionalità che consentono capacità video avanzate ha avuto luogo solo a partire dal iOS 4 e sono stati pienamente presentati al WWDC 2010.

      La posizione della AV Foundation nello iOS Frameworks stack si trova  sotto UIKit, dietro l’application layer, e immediatamente sopra i basic Core Services frameworks, in particolare Core Media che viene utilizzato da AV Foundation per importare strutture di temporizzazione e le funzioni necessarie per la gestione dei media . In ogni caso si può notare la diversa posizione nello stack rispetto Media Player di alto livello. Ciò significa che questo tipo di struttura non è in grado di offrire una classe plug-and-play  per la riproduzione di semplici video , ma si potranno apprezzare i moderni concetti di alto livello che sono alla base di questo framework, di sicuro non siamo allo stesso livello dei vecchi framework come core Audio.

       

      (image source: from Apple iOS Developer Library)

      Building blocks

      L’organizzazione dele classi di AV Fondation è abbastanza intuitiva. Il punto di partenza e il building block principale è data da AVAsset. AVAsset rappresenta un oggetto statico multimediale ed è essenzialmente un aggregato di tracce che sono rappresentazioni temporizzate  di una parte de media. Tutti i brani sono di tipo uniforme, in modo che possiamo avere tracce audio, tracce video, tracce sottotitoli, e un complesso di attività può essere fatto di più tracce dello stesso tipo, ad esempio siamo in grado di avere più tracce audio. Nella maggior parte dei casi un asset è fatto di un audio e una traccia video. Si noti che AVAsset è una classe astratta per cui è indipendente dalla rappresentazione fisica dei media che rappresenta, inoltre la creazione di un’istanza AVAsset non significa che noi abbiamo tutti i media pronti per essere riprodotti, si tratta di un puro oggetto astratto.


      Ci sono due classi di attività disponibili: AVURLAsset, per rappresentare un supporto in un file locale o in rete, e AVComposition (insieme con la sua variante mutevole AVMutableComposition ) per un’attività composta da più supporti. Per creare una risorsa da un file abbiamo bisogno di fornire l’URL del file:

      NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];
      AVURLAsset *myAsset = [AVURLAsset URLAssetWithURL:assetURL options:optionsDictionary];

      L’ options dictionary poò risultare nullo ma per i nostri scopi – per fare una composizione film – abbiamo bisogno di calcolare la durata esatta e fornire l’accesso casuale ai media. Questa opzione extra, che è l’impostazione su YES della chiave AVURLAssetPreferPreciseDurationAndTimingKey, potrebbe richiedere più tempo durante l’inizializzazione delle attività, e questo dipende dal formato di film. Se questo film è in QuickTime o MPEG-4, il file contiene informazioni aggiuntive che in sintesi annulla il tempo in più, ma ci sono in altri formati, come MP3, in cui queste informazioni possono essere estratte solo dopo la decodifica del media file, in tal caso l’inizializzazione del tempo non è trascurabile. Si tratta di una prima raccomandazione che diamo agli sviluppatori: si prega di utilizzare il formato del file a seconda dell’applicazione.
      Nella nostra applicazione dobbiamo già conoscere le caratteristiche dei film che stiamo usando, ma in un diverso tipo di applicazione, in cui è necessario fare un po ‘di editing dei filmati, si può essere interessati a ispezionare le proprietà delle risorse. In tal caso si deve ricordare la regola di base che l’inizializzazione di un asset non significa aver caricato e decodificato in memoria: questo significa che ogni proprietà del file multimediale può essere ispezionata, ma questo potrebbe richiedere un poco di tempo in più. Per completezza abbiamo semplicemente introdotto il modo asset inspection che può essere fatto lasciando l’utente interessato alla documentazione di riferimento (vedere l’elenco proposto letture alla fine di questo post). Fondamentalmente ogni proprietà dell’attività può essere verificata utilizzando un protocollo asincrono chiamato AVAsynchronousKeyValueLoadingwhich che definisce due metodi:

      - (AVKeyValueStatus)statusOfValueForKey:(NSString *)key error:(NSError **)outError
      – (void)loadValuesAsynchronouslyForKeys:(NSArray *)keys completionHandler:(void (^)(void))handler

      Il primo metodo è sincrono e restituisce immediatamente lo stato di conoscenza del valore specificato. Ad esempio si può chiedere lo status di “durata” e il metodo restituisce uno di questi stati possibili: carico, carico, fallito, sconosciuto, annullato. Nel primo caso il valore di chiave è noto e quindi il valore può essere immediatamente recuperato. Nel caso in cui il valore è ignoto è opportuno richiamare le loadValuesAsynchronouslyForKeys:completionHandler: metodo che alla fine dell’operazione chiamerà il callback dato nel completionHandlerblock, che a sua volta interroga lo stato di nuovo per l’azione appropriata.

      Video composition

      Come abbiam detto all’inizio, il nostro storyboard è composto da una serie di scene e ogni scena è composta da diverse clip il cui ordine di riproduzione non è nota a priori. Ogni scena si comporta indipendentemente dalle altre in modo da creare una composizione per ogni scena. Quando abbiamo un insieme di attività, o tracce, e da loro si costruisce una composizione nel complesso stiamo creando un altro asset. Questo è il motivo per cui le classi AVComposition e AVMutableComposition sono sottoclassi della classe  AVAsset base.
      È possibile aggiungere contenuti multimediali all’interno di una composizione mutevole, semplicemente selezionando un segmento di un bene, e l’aggiunta di una gamma specifica di nuova composizione:

      - (BOOL)insertTimeRange:(CMTimeRange)timeRange ofAsset:(AVAsset *)asset atTime:(CMTime)startTime error:(NSError **)outError

      Nel nostro esempio abbiamo una serie di tracce che si desidera aggiungere una dopo l’altra per generare un insieme continuo di clip. Così il codice può essere semplicemente scritto in questo modo:

      AVMutableComposition = [AVMutableComposition composition];
      CMTime current = kCMTimeZero;
      NSError *compositionError = nil;
      for(AVAsset *asset in listOfMovies) {
      BOOL result = [composition insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration])
      ofAsset:asset
      atTime:current
      error:&compositionError];
      if(!result) {
      if(compositionError) {
      // manage the composition error case
      }
      } else {
      current = CMTimeAdd(current, [asset duration]);
      }
      }

      Prima di tutto abbiamo introdotto il concetto di tempo. Si noti che tutti i media hanno un concetto di tempo diverso dal solito. Prima di tutto il tempo può muoversi avanti e indietro, oltre il lasso di tempo può essere superiore o inferiore a 1x se si sta visionndo il filmato al rallentatore o in avanzamento rapido. Inoltre si ritiene più conveniente  rappresentare il tempo non come virgola mobile o un numero intero, ma come numeri razionali. Per tale ragioneil framework  Core Media  fornisce la CMTimestructure e un insieme di funzioni e macro che semplificano la manipolazione di queste strutture. Quindi, al fine di costruire una specifica istanza time instance:

      CMTime myTime = CMTimeMake(value,timescale);

      che infatti specifica un numero di secondi proposto dal value/timescale. La ragione principale di questa scelta è che i film sono fatti di frames e i fotogrammi sono dati ad una razione fissa al secondo. Così, per esempio, se abbiamo una clip che è stata ripresa a 25 fps, allora sarebbe conveniente per rappresentare l’intervallo singolo fotogramma come un insieme variabile CMTime con valore = 1 e tempi = 25, corrispondente a 1/25th di secondo. 1 secondo  è dato da un CMTime con valore = 25 e timescale = 25, e così via (ovviamente si può ancora lavorare con i secondi, se volete, è sufficiente utilizzare i CMTimeMakeWithSeconds (seconds) function). Quindi, il codice di cui sopra inizialmente imposta l’ora corrente a 0 secondi (kCMTimeZero) quindi avvia l’iterazione su tutti i nostri film che sono assets in. Poi si aggiunge ciascuna di questi asset nella posizione corrente della nostra composizione con la loro gamma completa ([asset duration]). Per ogni asset spostiamo la composition head (current) per la lunghezza (in CMTime) dell’asset. A questo punto la composizione è fatta di un set completo di brani aggiunti in sequenza. Ora possiamo giocare.

      Playing an asset

      Il framework AVFoundation non offre alcuna player integrato, come siamo abituati a vedere con MPMovieViewController. Il motore che gestisce lo stato di riproduzione di un asset è fornito dalla classe AVPlayer. Questa classe si occupa di tutti gli aspetti relativi al play dell’asset ed essenzialmente è l’unica classe in AV Foundation che interagisce con i controller di visualizzazione dell’applicazione per mantenere in sincronia la logica dell’applicazione con lo stato di riproduzione: questo è rilevante per il tipo di applicazione che stiamo prendendo in considerazione in questo esempio, come lo stato di riproduzione può cambiare durante l’esecuzione del filmato base alle specifiche interazioni dell’utente  in momenti specifici all’interno del film. Tuttavia non abbiamo una relazione diretta tra AVAsset e AVPlayer, la loro connessione è mediata da un’altra classe denominata AVPlayerItem. Questa organizzazione delle classi ha lo scopo di separarel’asset, considerato come un’entità statica, dal player, puramente dinamico, fornendo un oggetto intermedio, che rappresenta uno stato specifico di presentazione di un asset. Ciò significa che per un determinat e unicoo asset  possiamo associare elementi di più players, tutti  rappresentano diversi stati dello stesso asset e eseguito da diversi players. Quindi, il flusso in questo caso è dato da un determinato asset che crea un elemento di player e poi lo assegna al pleyer finale.

      AVPlayerItem *compositionPlayerItem = [AVPlayerItem playerItemWithAsset:composition];
      AVPlayer *compositionPlayer = [AVPlayer playerWithPlayerItem:compositionPlayerItem];

       

      Al fine di eseguire il rendering sullo schermo, dobbiamo fornire una view in grado di rendere lo stato attuale di player. Abbiamo già detto che iOS non offre on-the-shelf una vista per questo scopo, ma quello che offre è un livello speciale CoreAnimation chiamato AVPlayerLayer. Quindi è possibile inserire questo livello nella gerarchia a livello di Anteprima del player o, come nel seguente esempio, utilizziamo questo come livello di base per questa view. Quindi, l’approccio suggerito in tal caso è quello di creare un MovieViewer personalizzato e il  set AVPlayerLayeras base layer class:

      // MovieViewer.h

      #import <UIKit/UIKit.h>
      #import <AVFoundation/AVFoundation.h>
      @interface MovieViewer : UIView {
      }
      @property (nonatomic, retain) AVPlayer *player;
      @end

      // MovieViewer.m

      @implementation MovieViewer
      + (Class)layerClass {
      return [AVPlayerLayer class];
      }
      – (AVPlayer*)player {
      return [(AVPlayerLayer *)[self layer] player];
      }
      – (void)setPlayer:(AVPlayer *)player {
      [(AVPlayerLayer *)[self layer] setPlayer:player];
      }
      @end

      // Intantiating MovieViewer in the scene view controller
      // We suppose “viewer” has been loaded from a nib file
      // MovieViewer *viewer
      [viewer setPlayer:compositionPlayer];

      A questo punto siamo in grado di riprodurre il filmato, che è abbastanza semplice:

      [[view player] play];
      Osservando il playback status

      È rilevante per la nostra applicazione  monitorare lo stato della riproduzione e osservare alcuni particolari eventi temporizzati  durante la riproduzione.
      Per quanto riguarda il monitoraggio dello stato, si seguirà l’approccio standard basato KVO osservando i cambiamenti nella proprietà dello stato del player:

      // inside the SceneViewController.m class we’ll register to player status changes
      [viewer.player addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:NULL];

      // and then we implement the observation callback
      -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
      if(object==viewer.player) {
      AVPlayer *player = (AVPlayer *)object;
      if(player.status==AVPlayerStatusFailed) {
      // manage failure
      } else if(playe.status==AVPlayerStatusReadyToPlay) {
      // player ready: manage success state (e.g. by playing the movie)
      } else if(player.status==AVPlayerStatusUnknown) {
      // the player is still not ready: manage this waiting status
      }
      }
      }

      Diversamente dalle KVO-observable properties l’ osservazione di eventi  non è basata su KVO: la ragione di questo è che la player head si muove continuamente e solitamente la riproduzione viene effettuata su un thread dedicato. Quindi il sistema preferisce certamente  inviare notifiche suoi attraverso un canale dedicato, che in questo caso consiste in un block-based callback che possiamo registrare per monitorare tali eventi. Ci sono due modi per osservare eventi programmati:

      • registering for periodic intervals notifications
      • registering when particular times are traversed

      In entrambi i metodi l’utente sarà in grado di specificare una serial queue in cui i richiami saranno spediti (e il default è la coda principale) e, naturalmente, il blocco callblack. E ‘importante notare il comportamento della serial queue: ciò significa che tutti gli eventi verranno messi in coda ed eseguiti uno dopo l’altro, per gli eventi frequenti è necessario assicurarsi che questi blocchi sono eseguiti abbastanza velocemente da permettere alla coda si elaborare i blocchi successivi, e questo è particolarmente vero se si sta eseguendo il blocco nel thread principale, al fine di evitare all’applicazione di non rispondere. Non dimenticate di programmare questo blocco da eseguire nel thread principale se si aggiorna l’interfaccia utente.
      La registrazione ad intervalli periodici è fatta in questo modo, dove chiediamo un callback 1 secondo il cui scopo principale sarà quello di aggiornare l’interfaccia utente (in genere l’aggiornamento di un barra di avanzamento e il tempo di riproduzione corrente):

      // somewhere inside SceneController.m
      id periodicObserver = [viewer.player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1.0) queue:NULL usingBlock:^(CMTime time){
      [viewer updateUI];
      }];
      [periodicObserver retain];

      // and in the clean up method
      -(void)cleanUp {
      [viewer.player removeTimeObserver:periodicObserver];
      [periodicObserver release];
      }

      // inside MovieViewer.m
      -(void)updateUI {
      // do other stuff here
      // …
      // we calculate the playback progress ratio by dividing current position of playhead into the total movie duration
      float progress = CMTimeGetSeconds(player.currentTime)/CMTimeGetSeconds(player.currentItem.duration);
      // then we update the movie viewer progress bar
      [progressBar setProgress:progress];
      }

       

      LA eegistrazione agli  timed events viene fatta usando un metodo simile che prende come argomento una lista di rappresentazioni NSValue di CMTime (AVFoundation fornisce una categoria NSValue che aggiunge il supporto a CMTime NSValue):

      // somewhere inside SceneController.m
      id boundaryObserver = [viewer.player addBoundaryTimeObserverForTimes:timedEvents queue:NULL usingBlock:^{
      [viewer processTimedEvent];
      }];
      [boundaryObserver retain];// inside MovieViewer.m
      -(void)processTimedEvent {
      // do something in the UI
      }
      In both cases we need to unregister and deallocate somewhere in our scene controller the two observer opaque objects; we may suppose the existence of a cleanup method that will be assigned this task:
      -(void)cleanUp {
      [viewer.player removeTimeObserver:periodicObserver];
      [periodicObserver release];
      [viewer.player removeTimeObserver:boundaryObserver];
      [boundaryObserver release];
      }

      Anche se questo codice è il modo generale di chiamare un evento, nella nostra applicazione è più opportuno assegnare ad ogni evento una specifica azione,  abbiamo bisogno di personalizzare ogni blocco di comunicazione. Guardando l’immagine qui sotto, si può vedere che a specifici intervalli di tempo all’interno di ciascuna delle nostre clip abbiamo assegnato un evento specifico.


      La figura è piuttosto complesso e non tutte le relazioni sono state evidenziate. Essenzialmente quello che potete vedere è la sequenza  “vincente” in tutti i blocchi verdi: sono stati posizionati in modo consecutivo, al fine di evitare il salto dell’indicatore di riproduzione sei diversi segmenti in cui il giocatore prende le decisioni giuste, in modo che la riproduzione continua senza interruzioni e sarà liscio. Con l’eccezione della traccia prologo, che è solo un prologo della storia e nessuna interazione con l’utente è richiesta in questa fase, ed è la conclusione corrispondente, semplicemente un epilogo quando l’utente è invitato a passare alla scena successiva, tutte le altre tracce sono stato caratterizzate da alcuni eventi temporizzati, identificati con le linee rosse tratteggiate verticali. In sostanza abbiamo individuato 4 tipi di eventi:

      • segment (clip) starting point: this will be used as a destination point for the playhead in case of jump;
      • show controls: all user controls will be displayed on screen, user intercation is expected;
      • hide controls: all user controls are hidden, and no more user interaction is allowed;
      • decision point, usually coincident with the hide controls event: the controller must decide which movie segment must be played based on the user decision.

      Si noti che questo approccio è molto flessibile e, in teoria, è possibile qualsiasi tipo di evento, questo dipende dalla fantasia dei game designer. Dal punto di vista del codice, abbiamo infatti la sottoclasse AVURLAsset aggiungendo una serie di eventi cronometrati. Al momento della  composizione, questo evento sarà nuovamente temporizzata secondo la base di un nuovo tempo (ad esempio: se un evento viene giocato al secondo 0:35 di una clip, ma il punto di partenza della clip è esattamente a 1: 45 della intera sequenza, il caso deve essere ri-programmato per 1:45 + 0:35 = 2,20). A questo punto, con l’elenco completo degli eventi è possibile riscrivere la registrazione confine:

      // events is the array of all re-timed events in the complete composition
      __block __typeof__(self) _self = self; // avoids retain cycle on self when used inside the block
      [events enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
      TimedEvent *ev = (TimedEvent *)obj;
      [viewer.player addBoundaryTimeObserverForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:ev.time]]
      queue:dispatch_get_main_queue()
      usingBlock:^{
      // send event to interactiveView
      [viewer performTimedEvent:ev];
      [_self performTimedEvent:ev];
      }];
      }];

       

      Come si può vedere il codice è molto semplice: per ogni evento programmato si registra l’unico limite che chiama semplicemente due metodi, uno per il lettore di film e uno per il controllo delle scene, in entrambi i casi dobbiamo inviare l’evento specifico in modo che il ricevitore sappia esattamente cosa fare. Il visualizzatore di norma prenderà cura dell’ interazione utente (che si sovrapporrà un paio di controlli sulla parte superiore dello strato di giocatore, quindi a seconda degli eventi  questi controlli saranno visualizzati o nascosti, inoltre lo spettatore sa che il controllo è stato selezionato dall’utente), mentre lo scene controller gestirà la logica del gioco, specialmente nel caso degli eventi decisione. Quando il controller rileva un evento di decisione, deve spostare la barra nella giusta posizione nella composizione:

       

      CMTime goToTime = # determines the starting time of the next segment #
      [viewer hide];
      [viewer.player seekToTime:goToTime toleranceBefore:kCMTimeZero toleranceAfter:kCMTimePositiveInfinity completionHandler:^(BOOL finished) {
      if(finished) {
      dispatch_async(dispatch_get_main_queue(), ^{
      [viewer show];
      });
      );
      }];

       

      Che cosa succede nel codice qui sopra nel caso in cui abbiamo bisogno di spostare la barra di un timing specifico, per prima cosa determiniamo questo tempo e poi chiediamo all’istanza AVPlayer di cercare , questa volta cercando di spostare la testina (head) in questa posizione o dopo con un po ‘tolleranza (kCMTimePositiveInfinity) ma non prima (kCMTimeZero nel toleranceBefore: parametro; abbiamo bisogno di questo perché la composizione è fatta di tutti i clip consecutivi e quindi spostando la testina prima dell’ora di partenza della clip potrebbe mostrare una piccola porzione del clip precedente). Notare che questa operazione non è immediata e anche se abbastanza veloce potrebbe richiedere un secondo circa. Cosa succede durante questa transizione , il livello player mostrerà una cornice ancora da qualche parte nella regione di timing di destinazione, che inizierà la clip completa di decodifica e riprende la riproduzione a partire da un altro frame, in genere diverso da quello precedente. L’effetto finale non è veramente buono e, dopo una sperimentazione abbiam deciso di nascondere il livello player immediatamente prima di iniziare la ricerca e mostralo di nuovo non appena il la classe player ci informa (attraverso il blocco di callback completionHandler) che il film è pronto per essere riprodotto .

      Conclusioni e references

      Speriamo che questo lungo articolo spingerà altri sviluppatori ad iniziare a lavorare su applicazioni per film interattivi e  che cercheranno di sfruttare le funzionalità avanzate di editing video per iOS. Il framework AVFoundation ci offre strumenti molto potenti e che non sono difficili da usare. In questo post non abbiamo esplorato alcune classi più avanzate, come ad esempio AVVideoComposition e AVSynchronizedLayer. La prima è utilizzata per creare transizioni, l’ultima è utilizzato per sincronizzare effetti di animazione di base con la temporizzazione interna media.

      Grandi riferimenti sull’argomento si possono trovare nella  iOS Developer Library o i video WWDC con codice di esempio:

      • For a general overview: AVFoundation Programming Guide in the iOS Developer Library
      • For the framework classes documentation: AVFoundation Framework Reference in the iOS Developer Library
      • Video: Session 405 – Discovering AV Foundation from WWDC 2010, available in iTunesU to registered developers
      • Video: Session 407 – Editing Media with AV Foundation from WWDC 2010, available in iTunesU to registered developers
      • Video: Session 405 – Exploring AV Foundation from WWDC 2010, available in iTunesU to registered developers
      • Video: Session 415 – Working with Media in AV Foundation from WWDC 2011, available in iTunesU to registered developers
      • Sample code: AVPlayDemo from WWDC 2010 sample code repository
      • Sample code: AVEditDemo from WWDC 2010 sample code repository

       

      Translated from Carlo’s post

        Pentiti dell'aggiornamento IOS5, downgrade di iPhone e iPad al sistema precedente

        Questa procedura è dedicata a tutti gli utilizzatori sui iPhone 4 e 3GS, iPad 1 e 2 e iPod Touch che hanno aggiornato il proprio sistema operativo e che, per diversi motivi, vogliono tornare indietro.

        Ho scritto questa breve guida dopo aver aggiornato il mio vecchio iPad 1 con la versione 5 di IOS. Dopo questa operazione l’iPad 1 sembra essere molto piu’ lento di prima e la batteria sembra anche durare meno, per cui ho deciso di ritornare alla versione 4.x dato che un “vecchio” dispositivo funziona sicuramente meglio con un “vecchio” sistema operativo.

        Tutto questo vi sembrerà assurdo, dato che ho definito vecchio un dispositivo che  ho acquistato un anno fa; a questo proposito Vi consiglio un documentario che fa capire cosa e’ esattamente la “obsolescenza programmata” e che potete visionare su questo blog: http://energiasi.com/obsolescenza-programmata/

        Avete Aggiornato il firmware del vostro iPhone, iPad o iPod touch?

        Qualora abbiate aggiornato il vostro device Apple ad iOS 5.0.1 ma volete tornare indietro siete ancora in tempo per effettuare il cosidetto downgrade di sistema operativo.
        Limitazione: se siete dei developer e i vostro dispositivo è stato aggiornato alla versione di iOS 5.1 (disponibile per il momento solo per gli sviluppatori iscritti al Developer Program) non potete effettuare il downgrade dato che  questo tipo di operazione è stata direttamente bloccata da Apple.

        Prima di tutto
        Se non avete salvato i certificati SHSH del vostro dispositivo non potrete andare avanti.

        I certificati SHSH sono indispensabili per le procedure di downgrade ad un firmware meno recente.Consigliamo dunque a tutti gli utenti interessati  di salvare i propri certificati SHSH con il software TinyUmbrella, che potete scaricare da questa pagina.

        TinyUmbrella, è un’ utility sviluppata da Notcom che permetterà di salvare i certificati SHSH sul computer.
        Disponibile sia in vesione Mac che Win necessita di  Java installato sul proprio pc.

        Procedura per salavare i dcertificati SHSH

        • Avviare TinyUmbrella
        • Collegare il dispositivo iPhone o iPad o iPod al computer
        • Cliccare su Save SHSH. Il software salverà  i certificati SHSH sul vostro disco.

        Solo ora possiamo procedere ad effettuare il  downgrade.

        Downgrade di firmaware iOS

        Mettete il Vostro iPhone, iPod Touch o iPad  in modalità DFU:

        • Spegnere il dispositivo
        • Riaccendere tenendo premuto contemporaneamente gli unici 2 tasti ( Power + Home) per circa 10 secondi,quindi  rilasciare il tasto Power e continuare a tenere premuto il tasto Home per altri 10 secondi
        •     A questo punto non vi resta che collegare l’iPhone, o l’iPad, al  computer:

        Su Windows o Mac, andiamo ad aprire il file hosts  (ad esempio, il percorso potrebbe essere su windows  Sistema -> Driver -> Etc. -> Hosts mentre su Mac per modificare il file host su Mac Os x dovete seguire questi passi:

        1. Clicca su Finder
        2. Clicca su Applicazioni
        3. Entra nella cartella Utility
        4. Clicca due volte su Terminale
        5. Copia e Incolla la seguente stringa nel terminale:  sudo /Applications/TextEdit.app/Contents/MacOS/TextEdit /etc/hosts
        6. A questo punto inserisci la password di sistema e premete invio
        7. Il file Hosts verrà aperto in textEdit dove potrai editarlo e successivamente salvarlo

        NB: Effettuiamo un copia di questo file per sicurezza, poi apriamolo con un qualsiasi editor di testo

        •     Con il file aperto alla fine del testo, incolliamo questo codice :
          74.208.105.171    gs.apple.com
        •    Salviamo il file
        •     Apriamo iTunes e procediamo con il Restore del nostro device premendo il tasto Shift (Windows) o Alt (Mac)
        •     Verrà richiesto di scegliere un nuovo firmware da caricare: quindi precedentemente dobbiamo aver scaricato la versione di iOS che vogliamo sul nostro device (possiamo scegliere iOS 4.3.3, 4.3.4, 4.3.5, …).

        In questo modo, abbiamo effettuato il downgrade di iOS!

        NB: Qualora comparisse un messaggio d’ errore dopo aver selezionato il firmware dovrete aprire TinyUmbrella e cliccare sull’ opzione Exit Recovery.

        Allego un Video tra i tanti presenti su youtube, in lingua inglese:

         

          Il costo di un' App per iPhone & iPad

          Riportiamo la traduzione integrale dell’articolo Dear business people, an iOS app actually takes a lot of work!, scritto da Kent Nguyen che ringraziamo per averci concesso il permesso.

          This is the italian translation of the article Dear business people, an iOS app actually takes a lot of work!, written by Kent Nguyen. Thanks Kent for giving us permission to publish this translated article.

          Il grande quesito: quanto costa un’app per iPhone?

          Questa è una domanda estremamente comune che viene sempre chiesta da un sacco di persone che lavorano nel mondo degli affari oppure da clienti non molto esperti di tecnologia. Senza dubbio, ogni volta che ho fornito una stima iniziale prima ancora di formalizzare e analizzare in dettaglio le specifiche, ho potuto vedere sui loro volti l’espressione di shock a causa della inaspettatamente alta quotazione.

          Inoltre nessuna delle mie quotazioni si è lontanamente avvicinata ai valori discussi in, nel quale vengono discussi i costi di sviluppo dell’app Twitterific. Nonostante il fatto che la domanda originale fosse stata posta nel 2008 e la migliore risposta (da uno degli sviluppatori di Twitterific) fosse arrivata nel 2010, è ancora molto precisa all’inizio del 2012 ed è facile prevedere che lo sarà almeno fino alla fine dell’anno.

          Cosí, con il crescere del numero di imprese che desiderano avere un’app per iOS, penso che sia una buona idea spiegare perché i costi siano effettivamente alti cercando di dividere i vari passi e spiegare le variabili coinvolte. Spero che questo articolo sia di beneficio per i non sviluppatori e gli uomini d’affari che devono prendere delle decisioni o semplicemente vogliono comprendere il processo. Le idee in questo articolo ovviamente non sono ristrette al solo mondo iOS ma possono essere estese ad altre piattaforme (Android, Windows Mobile, forse Blackberry).

          Checklist: prepararsi ad un’app per iPhone

          Il procedimento non è affatto semplice e cerco innanzitutto di informare il cliente a fare tutte le considerazioni guidandolo attraverso questi passi:

          PRIMO: Una delle maggiori scoperte che ottengo parlando con i clienti è quanto siano inconsapevoli delle grande infrastruttura necessaria per un’app per iPhone. Dato che essi assumono che un’app sia semplicemente un’app, si aspettano che gli venga fornito il prezzo di fare qualunque cosa con l’app senza tener conto di problematiche quali: avere un server di supporto col quale l’iPhone comunichi, dove immagazzinare i dati dell’utente. La prima volta che incontrai un tale cliente ero furioso ma in seguito ho realizzato il fatto che il concetto di client-server non deve essere dato per scontato tra i non programmatori. Avevo sbagliato, i manager di solito non hanno il senso-tecnico comune che noi programmatori ci attendiamo.

          Perciò, cari lettori non tecnici: è necessario che disponiate di un server nel quale memorizzare i dati per qualunque tipo di app che come minimo debba fare qualche autenticazione (login) o qualunque tipo di personalizzazione che volete cambiare in seugito o comunque qualunque operazione che richieda il recepimento di informazioni dall’utente (sto cercando di usare il linguaggio il più semplice possibile).

          SECONDO: Dato che avete bisogno di un server, bisogna fare in modo che l’iPhone possa comunicare con tale server, inviando e ricevendo dati. Non esiste una maniera standard, non esiste nessun componente plug-and-play per fare questo, ogni cosa va customizzata. Questo è analogo a creare il vostro linguaggio personalizzato: non volete che gli altri comprendano ciò che state dicendo ma le due estremità, telefono e server, devono capirsi.

          Questo processo consiste nella creazione di API (Application Programming Interface) per la vostra app. Queste API devono esistere prima che si proceda con lo sviluppo dell’app. Perché? perché prima di cominciare a comunicare occorre definire il linguaggio! Questo ci porta al prossimo passo, come creare queste API.

          TERZO: Non prendere questo passo alla leggera, le API hanno un’importanza pari al 50% dell’intera soluzione. Fare un’API è come mettere in piedi un sito web. Prima devi definire i dati, quindi la logica di business, quali sono i parametri di ingresso a tale logica, come interagiscono fra loro i vari moduli quando accade un evento. Per semplificare, il risultato finale è un sito web completo dove però le pagine non mostrano risultati grafici ma solamente del testo che verrà compreso dalla nostra app: ad esempio una pagina di autenticazione conterrà, in caso di successo, la semplice parola YES.

          L’iPhone quindi farà una serie di richieste a questi punti terminali predefiniti (pagina di login) usando il formato di ingresso predefinito dall’API (nome utente + password) e quindi interpreterà il risultato fornito da queste pagine in risposta alla sua richiesta (YES/NO). L’app senza questo non potrà mai registrarsi e fare il login magicamente da sola.

          Ci sono *un sacco* di variabili che devono essere prese in considerazione in questa fase, come preparare un server, selezionare il linguaggio di programmazione con cui scrivere le API, dove immagazzinare i dati per minimizzare i tempi di comunicazione, ecc.

          QUARTO: Queste API o sono già pronte e ben documentate dal vostro team interno per essere fornite allo sviluppatore iPhone oppure preparatevi a pagare di più che solo per la pura app. In funzione delle conoscenze dello sviluppatore che avrete contattato per farvi l’app, egli/ella potrebbe avere o meno le capacità per fare ciò di cui avete bisogno. Se lo sviluppatore è in grado di fare questo lavoro, allora vi consiglio fortemente di affidargli anche questa parte del progetto dato che egli sa esattamente quali API servono per far funzionare l’app al meglio.

          Nel caso abbiate già le API dovrete dare allo sviluppatore la possibilità di parlare apertamente e liberamente con il vostro team di back-end e non limitarvi a dargli la documentazione; questo perché il più delle volte egli richiederà che venga fatto del lavoro in più (più API) per supportare l’applicazione mobile in maniera appropriata.

          Adesso, la parte iPhone

          Caspita, tutto questo per essere appena pronti a sviluppare l’app e non siamo ancora partiti! In generale, qualunque cosa riguardo iOS è molto restrittiva. Dovete quasi sempre aver definito circa il 100% dello scopo e del design prima che lo sviluppatore possa partire con la programmazione; diversamente dallo sviluppo di siti web, lo sviluppo di un’app per iOS sotto contratto ha pochissimi margini di cambiamento:

          Disegnare l’interfaccia: La scelta se si devono utilizzare i componenti grafici standard o personalizzati deve essere presa già dall’inizio, dato che l’architettura dell’intera app dipende da come si vuole l’interfaccia e da come la utilizzeranno gli utenti.Un esempio è la Tab Bar in basso: se si vogliono i bottoncini colorati invece di quelli monocromatici standard, la modifica al codice è sostanziale!

          Il codice è fortemente integrato: Con i siti web voi potete aggiungere semplicemente una pagina in più, quindi create un link a quella pagina ove richiesto. Non potete fare questo con un’app per iOS, dato che ogni cosa va decisa all’inizio e ogni cambiamento può risultare in cambiamenti significativi in altre parti dell’app. Il modo in cui il codice iOS è strutturato è come quello di una breadboard (le basette sperimentali per circuiti elettrici), dove ogni cosa è collegata con fili: voi potete sempre cambiare delle cose qui e là ma se tocchi il filo sbagliato allora l’intero circuito smetterà di funzionare. Anche se viene usato del codice estremamente ben strutturato la flessibilità non aumenterà molto. L’aggiunta di un bottone email addizionale nella schermata “About” potrebbe richiedere un ridotto numero di linee di codice addizionali, ma l’aggiunto di un bottone “Facebook Like” sulla stessa pagina è una cosa completamente differente e non ci può attendere che venga fatto in poche ore.

          Convertire un’app per iPhone in un’app iPhone/iPad universale: Questa è la peggiore ‘funzionalità aggiuntiva’ presente nei contratti di sviluppo di app per iPhone. Questo perché un’app per iPad non è una banale funzionalità aggiuntiva. Le app per iPad sono di solito molto più complesse delle app per iPhone e il più delle volte sono richiesti un’interfaccia e un meccanismo di interazione completamente differenti. Non solo quello, dato che anche le API potrebbero essere diverse: l’app Denso, che ho sviluppato (e quindi conosco), ha alcune funzionalità esclusive dell’app per iPad che richiedono dati addizionali dal server. Inoltre l’iPhone e l’iPad richiedono esperienze utente differenti.

          Dunque siete pronti a partire?

          Spero che dopo aver letto questo abbiate un’idea più chiara di quel che è necessario alla vostra ditta per sviluppare un’app per il mondo mobile. A meno che non facciate un’app completamente offline (come una Calcolatrice!) che non raccoglie dati dagli utenti, non potrete pretendere che questa vi venga sviluppata a un prezzo basso. Dopo aver considerato le variabili elencate sopra, se non potrete giustificare lo sviluppo a contratto allora l’altra opzione è assumere a tempo determinato dei progettisti a tempo pieno che lavorino a tempo pieno per l’intera durata del progetto.

          D’altro canto, se decidete di andare avanti e affidare in outsourcing il lavoro, c’e’ un’altra cosa da aggiungere: le lungaggini burocratiche. Se lavorate in una grande azienda o in un ambiente molto regolamentato, il vostro lavoro sarà essenzialmente di aiutare lo sviluppatore ad evitare le lungaggini burocratiche che potrebbe incontrare lungo la strada e talvolta avrete necessità di aggirare un pochino le regole. Ho parlato con molti clienti e ho potuto notare il loro scetticismo quando ho cercato di saperne di più sulle loro API, dato che essi o non desideravano esporsi maggiormente per non violare le loro regole di segretezza, e non potevo biasimarli, oppure non possono portare certi dati al di fuori del perimetro aziendale, oppure semplicemente (e questa è la cosa peggiore) le regole di branding aziendale richiedono che ogni singola pagina dell’app presenti il logo dell’azienda (!!!). Alla fine ho preferito non lavorare con questi clienti dato che non potevo immaginare quando a lungo avrei penato per ottenere anche un minimo supporto sulle API di cui avrei avuto bisogno.

          P.S. Avrete bisogno di tempo, un sacco, per cui siate pazienti.

            iOS 5 Tech Talk World Tour, Rome 9-11-2011

            i3Factory ha partecipato all’evento organizzato da Apple a Roma, iOs Tech Talk World Tour 2011 .

            Senza badare a spese Apple inc. ha organizzato un evento gratuito dedicato a tutti gli sviluppatori e a cui hanno partecipato diversi esperti che provenivano dalle sedi Apple del mondo.
            L’evento era a numero chiuso e ne sono stati preselezionati i partecipanti.

            L’evento iOS 5 Tech Talk World Tour si e’ tenuto il 9 novembre 2011 al Marriott Park Hotel di Roma; Appena arrivati ci siamo registrati alla velocita’ della luce (intelligentemente hanno trovato il modo di non farti fare noiose file per ottenere il badge) , quindi diretti nella sala “Michelangelo” inziavamo a riconoscerele persone dello staff Apple. Senza troppi convenevoli si poteva far colazione liberamente con il tipico caffé americano e connettersi alla rete Wi-Fi gratuitamente offerta.

            Verso le 8:45 è stata aperta la “Room A” dove si tenevano le sessioni mattutine. Tutte le sessioni erano il lingua Inglese come anche ogni interazione con il personale Apple avveniva in English.
            Dopo pranzo ci si divideva nelle altre stanze in base agli argomenti trattati.
            Nella prima stanza si discuteva di iCloud, ed in seguito delle innovazioni portate da iOS 5 e da Xcode 4.2 come le Storyboards ed ARC, la   2 stanza era per lo più dedicata agli sviluppatori di giochi,  Audio, Video e OpenGL, mentre la terza stanza era diretta prevalentemente a chi intendeva sfruttare  iOS 5 per i contenuti, si parlava di Edicola, Acquisti In-App, localizzazioni.
            Nel frattempo si poteva approffittare della presenza di specialisti presso la stanza adibita a Lab, dove si poteva richiedere un colloquio con diversi tecnici, ognuno specializzato in un argomento specifico. Abbiamo avuto modo di parlare con i Tecnici Apple e mostrargli il nostro nuovo gioco in preparazione, il Fuggitivo.Una bella esperienza, soprattutto nel partecipare in Italia ad un tipo di evento che siamo abituati a vedere all’estero,  in cui una grande azienda come Apple si pone a disposizione con i propri “evangelisti” senza formalita’ di alcun tipo con massima disponibilita’ e sopratutto in grado di dominare il mercato con un prodotto che e’ di gran lunga piu’ avanzato dei propri concorrenti.

            Di seguito la galleria foto: