SlideShare una empresa de Scribd logo
1 de 62
Francesco Novelli
iOS e il Cloud


francesco.nove@gmail.com - Run Code
Chi Sono?
          Francesco Novelli   francesco.nove@gmail.com - Run Code




- iOS Developer
- Web Developer
- Autore di Programmare applicazioni per
   iPhone ed iPad
-Autore di Programamre applicazioni per
   Mac OS X
Chi Sono?
Francesco Novelli   francesco.nove@gmail.com - Run Code
Di cosa parliamo oggi?
Francesco Novelli        francesco.nove@gmail.com - Run Code




CLOUD!
Di cosa parliamo oggi?
Francesco Novelli        francesco.nove@gmail.com - Run Code




                    e iOS...
Di cosa parliamo oggi?
           Francesco Novelli        francesco.nove@gmail.com - Run Code




-   iCloud
-   DropBox
-   Google Drive
-   Amazon S3
iCloud
           Francesco Novelli   francesco.nove@gmail.com - Run Code




-   Caratteristiche principali
-   Come implementarlo in un App
-   Pro
-   Contro
iCloud – Caratteristiche principali
          Francesco Novelli                 francesco.nove@gmail.com - Run Code




                              I numeri

- 250 milioni di utenti
- 500 milioni di iOS Device attivi
- 50% degli utenti usa iCloud
iCloud – Caratteristiche principali
            Francesco Novelli                 francesco.nove@gmail.com - Run Code




-   Sincronizzazione automatica
-   Implementazione nativa nell’OS
-   Risoluzione conflitti automatica
-   5 GB di spazio gratuito
-   Disponibile per Mac OS X
iCloud – Come implementarlo in un App
           Francesco Novelli             francesco.nove@gmail.com - Run Code




-   Non necessita di framework
-   Certificati necessari
-   iCloud Storage
-   iCloud Key-Value Data Storage
iCloud – Come implementarlo in un App
          Francesco Novelli             francesco.nove@gmail.com - Run Code




Certificati:
  Entitlement attivo nell’app
iCloud – Come implementarlo in un App
          Francesco Novelli             francesco.nove@gmail.com - Run Code




Certificati:
  AppID in iOS Dev Portal
iCloud – Come implementarlo in un App
          Francesco Novelli             francesco.nove@gmail.com - Run Code




Certificati:
  Provisioning Profile dedicato
iCloud – Come implementarlo in un App
           Francesco Novelli             francesco.nove@gmail.com - Run Code




iCloud Data Storage:
  Archiviazione file
  Salvataggio Database
  Salvataggio CoreData
  Condivisione file tra devices
iCloud – Come implementarlo in un App
           Francesco Novelli             francesco.nove@gmail.com - Run Code




iCloud Data Storage:
   // Controllare che iCloud sia attivo
id currentToken =
[[NSFileManager defaultManager]
  ubiquityIdentityToken];
   if (!currentToken) {
       // Alert user
   }
iCloud – Come implementarlo in un App
              Francesco Novelli             francesco.nove@gmail.com - Run Code




self.query = [[NSMetadataQuery alloc] init];

[self.query setSearchScopes:
   [NSArray arrayWithObject:
   NSMetadataQueryUbiquitousDocumentsScope]];

NSPredicate *pred = [NSPredicate
   predicateWithFormat:@"%K like 'Note_*'",
   NSMetadataItemFSNameKey];
[self.query setPredicate:pred];
iCloud – Come implementarlo in un App
                   Francesco Novelli                francesco.nove@gmail.com - Run Code




for (NSMetadataItem *item in [query results]) {

     NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
     Note *nota = [[Note alloc] initWithFileURL:url];

     [nota openWithCompletionHandler:^(BOOL success) {
        if (success) {
            [self.notes addObject:nota];
        }

     }];
 }
iCloud – Come implementarlo in un App
                           Francesco Novelli                                   francesco.nove@gmail.com - Run Code




// CREARE UN FILE

   NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
   NSURL *ubiquitousPackage = [[ubiq URLByAppendingPathComponent:@"Documents"]
   URLByAppendingPathComponent:fileName];

   Note *nota = [[Note alloc] initWithFileURL:ubiquitousPackage];

   [nota saveToURL:[nota fileURL]
        forSaveOperation:UIDocumentSaveForCreating
      completionHandler:^(BOOL success) {
       if (success) {
            [self.notes addObject:nota];
            [self.tableView reloadData];
         }
     }];
         ];
iCloud – Come implementarlo in un App
          Francesco Novelli             francesco.nove@gmail.com - Run Code




            DA RICORDARE
- NSFileManager per le operazioni di I/O
- NSMetadataQuery per la ricerca dei file
- I file vengono scaricati solo in caso di
  necessità
- Caricare solo le differenze!
iCloud – Come implementarlo in un App
           Francesco Novelli             francesco.nove@gmail.com - Run Code




iCloud Key-Value Storage
  Salvataggio impostazioni
  Salvataggio stato dell’applicazione
  Salvataggio piccoli dati
iCloud – Come implementarlo in un App
        Francesco Novelli             francesco.nove@gmail.com - Run Code




Classi ammesse:
• NSData
• NSString
• NSNumber
• NSDate
• NSArray
• NSDictionary
iCloud – Come implementarlo in un App
          Francesco Novelli             francesco.nove@gmail.com - Run Code




Scrivere un dato

[[NSUbiquitousKeyValueStore defaultStore]
   setObject:@"testo"
forKey:@"key"];
iCloud – Come implementarlo in un App
          Francesco Novelli             francesco.nove@gmail.com - Run Code




Sincronizzare i dati

[[NSUbiquitousKeyValueStore defaultStore]
synchronize];
iCloud – Come implementarlo in un App
         Francesco Novelli             francesco.nove@gmail.com - Run Code




Leggere i dati

NSLog(@"%@",[[NSUbiquitousKeyValueSto
re defaultStore] objectForKey:@"key"]);
iCloud – Come implementarlo in un App
    Francesco Novelli             francesco.nove@gmail.com - Run Code




NSUbiquitousKeyValueStore

                        ==

        NSUserDefaults
iCloud – Come implementarlo in un App
          Francesco Novelli             francesco.nove@gmail.com - Run Code




PRO
  Profondamente integrato con l’OS
  Poco codice e nessuna dipendenza
  Compatibilità da iOS 5
  Compatibilità perfetta con OS X
iCloud – Come implementarlo in un App
          Francesco Novelli             francesco.nove@gmail.com - Run Code




CONTRO
   Disponibile SOLO con device Apple
   Sandbox impedisce spazio condiviso
   L’utente non può accedere direttamente ai
file
Dropbox
           Francesco Novelli   francesco.nove@gmail.com - Run Code




-   Caratteristiche principali
-   Come implementarlo in un App
-   Pro
-   Contro
Dropbox– Caratteristiche principali
            Francesco Novelli                francesco.nove@gmail.com - Run Code




-   100 milioni di utenti
-   Gratis fino a 16 Gb di spazio
-   LAN Sync
-   Condivisione cartelle tra utenti
Dropbox– Come implementarlo in un App
         Francesco Novelli            francesco.nove@gmail.com - Run Code




Registrazione nell’App Console:
https://www.dropbox.com/developers/apps

- APP Type: API
- APP Name Univoco
- Access: App Folder
Dropbox– Come implementarlo in un App
Francesco Novelli            francesco.nove@gmail.com - Run Code
Dropbox– Come implementarlo in un App
       Francesco Novelli            francesco.nove@gmail.com - Run Code




App key
App secret
Dropbox– Come implementarlo in un App
         Francesco Novelli            francesco.nove@gmail.com - Run Code




Download Dropbox iOS SDK
https://www.dropbox.com/developers/sync/
tutorial/ios



      Dropbox.framework in Xcode
Dropbox– Come implementarlo in un App
         Francesco Novelli            francesco.nove@gmail.com - Run Code




Altri framework necessari:
• CFNetwork.framework
• Security.framework
• SystemConfiguration.framework
• QuartzCore.framework
Dropbox– Come implementarlo in un App
                             Francesco Novelli                                     francesco.nove@gmail.com - Run Code




#import <Dropbox/Dropbox.h>



- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)opts {

    ...

    // The account manager stores all the account info. Create this when your app launches
    DBAccountManager* accountMgr =
    [[DBAccountManager alloc] initWithAppKey:@"APP_KEY" secret:@"APP_SECRET"];
    [DBAccountManager setSharedManager:accountMgr];
    DBAccount *account = accountMgr.linkedAccount;

    if (account) {
       DBFilesystem *filesystem = [[DBFilesystem alloc] initWithAccount:account];
       [DBFilesystem setSharedFilesystem:filesystem];
    }

    ...
}
Dropbox– Come implementarlo in un App
             Francesco Novelli            francesco.nove@gmail.com - Run Code




Info.plist

<key>CFBundleURLTypes</key>
 <array>
  <dict>
   <key>CFBundleURLSchemes</key>
    <array>
     <string>db-APP_KEY</string>
    </array>
  </dict>
 </array>
Dropbox– Come implementarlo in un App
                      Francesco Novelli                         francesco.nove@gmail.com - Run Code

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url
  sourceApplication:(NSString *)source annotation:(id)annotation {

    DBAccount *account = [[DBAccountManager sharedManager] handleOpenURL:url];
    if (account) {
        DBFilesystem *filesystem = [[DBFilesystem alloc] initWithAccount:account];
        [DBFilesystem setSharedFilesystem:filesystem];
        NSLog(@"App linked successfully!");
        return YES;
    }

    ...
}
Dropbox– Come implementarlo in un App
                     Francesco Novelli                       francesco.nove@gmail.com - Run Code




// ELENCARE FILE



NSArray *contents =
 [[DBFilesystem sharedFilesystem] listFolder:[DBPath root]
     error:nil];
for (DBFileInfo *info in contents) {
   NSLog(@"%@", info.path);
}
Dropbox– Come implementarlo in un App
                      Francesco Novelli                         francesco.nove@gmail.com - Run Code

// SCRIVERE UN FILE

DBPath *newPath = [[DBPath root] childPath:@"hello.txt"];
DBFile *file = [[DBFilesystem sharedFilesystem] createFile:newPath error:nil];
[file writeString:@"Hello World!" error:nil];



// LEGGERE UN FILE

DBPath *newPath = [[DBPath root] childPath:@"hello.txt"];
DBFile *file = [[DBFilesystem sharedFilesystem] createFile:newPath error:nil];
NSString *fileContent [file readString:@"Hello World!" error:nil];
Dropbox– Come implementarlo in un App
                                      Francesco Novelli                               francesco.nove@gmail.com - Run Code

// CONTROLLARE LE MODIFICHE

DBPath *path = [[DBPath root] childPath:@"change-me.txt"];
 self.file = [[DBFilesystem sharedFilesystem] createFile:path error:nil];

 // Next, register for changes on that file
 [self.file addObserver:self block:^() {

       // This block will be called every time your file changes

       // if newerStatus is not nil, it means a newer version is available
       DBFileStatus *newerStatus = file.newerStatus;
       if (newerStatus) {

           if (!newerStatus.cached) {
               NSLog(@"newerStatus.cached == NO; this means the file downloading");
           } else {

               // Update to the newly available version and print it out
               [file update:nil];
               NSLog(@"The file is done downloading: %@", [file readString:nil]);
           }
       }
 }];
Dropbox - PRO
           Francesco Novelli    francesco.nove@gmail.com - Run Code




PRO
  Disponibile su tutte le piattaforme
  File accessibili da qualsiasi app
  Possibilità di ampliare lo spazio
gratuitamente
Dropbox - CONTRO
          Francesco Novelli   francesco.nove@gmail.com - Run Code




CONTRO
 Necessità di diverse dipendenze
 Codice più complesso di iCloud
Google Drive
           Francesco Novelli   francesco.nove@gmail.com - Run Code




-   Caratteristiche principali
-   Come implementarlo in un App
-   Pro
-   Contro
Google Drive
          Francesco Novelli   francesco.nove@gmail.com - Run Code




- TUTTI hanno un account Google
- Integrato benissimo con Android..
- …ed ha le API per iOS
Google Drive
          Francesco Novelli            francesco.nove@gmail.com - Run Code




- Registrare l’app nel Google API Console:
  https://code.google.com/apis/console/
- Importare svariati framework
- Importare i framework di Google Drive

                              OPPURE
Google Drive
           Francesco Novelli      francesco.nove@gmail.com - Run Code




  Seguire alla lettera le istruzioni di questa
                    pagina:

https://developers.google.com/drive/quickst
                   art-ios

      (non il video, l’app non compila!)
Google Drive
                  Francesco Novelli                        francesco.nove@gmail.com - Run Code




GTLDriveFile *file = [GTLDriveFile object];
 file.title = [dateFormat stringFromDate:[NSDate date]];
 file.descriptionProperty = @”Desc";
 file.mimeType = @"image/png";

 NSData *data = …; // DATA TO UPLOAD
 GTLUploadParameters *uploadParameters = [GTLUploadParameters
  uploadParametersWithData:data MIMEType:file.mimeType];

 GTLQueryDrive *query = [GTLQueryDrive queryForFilesInsertWithObject:file
  uploadParameters:uploadParameters];
Google Drive
                 Francesco Novelli                francesco.nove@gmail.com - Run Code




[self.driveService executeQuery:query
completionHandler:^(GTLServiceTicket *ticket,
                            GTLDriveFile *insertedFile,
                            NSError *error) {
       if (error == nil)
    {
      NSLog(@"File ID: %@", insertedFile.identifier);
       }
}];
iCloud – Come implementarlo in un App
           Francesco Novelli             francesco.nove@gmail.com - Run Code




PRO
  Tutti hanno un account Google
  Disponibile in tutte le piattaforme
  €/Gb più basso della concorrenza
iCloud – Come implementarlo in un App
          Francesco Novelli             francesco.nove@gmail.com - Run Code




CONTRO
 TANTE dipendenze
 Codice complesso
 Live Sync non disponibile
Amazon S3
           Francesco Novelli   francesco.nove@gmail.com - Run Code




-   Caratteristiche principali
-   Come implementarlo in un App
-   Pro
-   Contro
Amazon S3
            Francesco Novelli      francesco.nove@gmail.com - Run Code




-   Spazio dello sviluppatore
-   L’utente non ha bisogno di un account
-   Servizio totalmente differente dagli altri
-   Supporto a CoreData
Amazon S3
          Francesco Novelli       francesco.nove@gmail.com - Run Code




- Scaricare l’SDK dal sito AWS:

    http://aws.amazon.com/sdkforios/

- Importare AWSiOSSDK.framework nel
  progetto
Amazon S3
       Francesco Novelli    francesco.nove@gmail.com - Run Code




     AWSPersistence.framework

CoreData tramite S3, ma ancora in beta
Amazon S3
                   Francesco Novelli                      francesco.nove@gmail.com - Run Code




self.s3 = [[[AmazonS3Client alloc] initWithAccessKey:ACCESS_KEY_ID
   withSecretKey:SECRET_KEY] autorelease];
self.s3.endpoint = [AmazonEndpoints s3Endpoint:US_WEST_2];

S3CreateBucketRequest *createBucketRequest = [[[S3CreateBucketRequest alloc]
  initWithName:[Constants pictureBucket] andRegion:[S3Region USWest2]]
  autorelease];

S3CreateBucketResponse *createBucketResponse = [self.s3
  createBucket:createBucketRequest];
   if(createBucketResponse.error != nil)
   {
       NSLog(@"Error: %@", createBucketResponse.error);
   }
Amazon S3
                    Francesco Novelli                       francesco.nove@gmail.com - Run Code




S3PutObjectRequest *por = [[[S3PutObjectRequest alloc] initWithKey:PICTURE_NAME
                                   inBucket:[Constants pictureBucket]] autorelease];
 por.contentType = @"image/jpeg";
 por.data     = imageData;

S3PutObjectResponse *putObjectResponse = [self.s3 putObject:por];
 [self performSelectorOnMainThread:@selector(showCheckErrorMessage:)
               withObject:putObjectResponse.error
              waitUntilDone:NO];
Amazon S3
                        Francesco Novelli                           francesco.nove@gmail.com - Run Code




S3ResponseHeaderOverrides *override = [[[S3ResponseHeaderOverrides alloc] init] autorelease];
   override.contentType = @"image/jpeg";

// Request a pre-signed URL to picture that has been uplaoded.
S3GetPreSignedURLRequest *gpsur =
 [[[S3GetPreSignedURLRequest alloc] init] autorelease];
gpsur.key             = PICTURE_NAME;
gpsur.bucket           = [Constants pictureBucket];
gpsur.expires          =
 [NSDate dateWithTimeIntervalSinceNow:(NSTimeInterval) 3600];
gpsur.responseHeaderOverrides = override;

// Get the URL
NSError *error;
NSURL *url = [self.s3 getPreSignedURL:gpsur error:&error];
Amazon S3 – PRO
          Francesco Novelli   francesco.nove@gmail.com - Run Code




PRO
  Spazio praticamente illimitato
  Semplice implementazione
  File condivisi con tutti
  L’utente non ha bisogno di un account
Amazon S3 – CONTRO
          Francesco Novelli    francesco.nove@gmail.com - Run Code




CONTRO
 Lo spazio non è personale
 Per grandi progetti da valutare il €/Gb
 Costi per il trasferimento dei file
In conclusione
Francesco Novelli   francesco.nove@gmail.com - Run Code
In conclusione
            Francesco Novelli     francesco.nove@gmail.com - Run Code




-   iCloud per progetti iOS-Only (o Mac)
-   Dropbox per applicazioni su più OS
-   Google Drive come alternativa a Dropbox
-   Amazon S3 per far caricare file all’utente
In conclusione
      Francesco Novelli   francesco.nove@gmail.com - Run Code




Q&A Time…
 francesco.nove@gmail.com
            @iF9
    www.9lli.it/francesco
  www.facebook.com/fnove

Más contenido relacionado

Similar a Cloud e iOS - Codemotion2013 Roma

Progettazione per Apple Watch - Todi Appy Days 2015
Progettazione per Apple Watch - Todi Appy Days 2015Progettazione per Apple Watch - Todi Appy Days 2015
Progettazione per Apple Watch - Todi Appy Days 2015Todi Appy Days
 
Wearable Lab: Progettazione per Apple Watch
Wearable Lab: Progettazione per Apple WatchWearable Lab: Progettazione per Apple Watch
Wearable Lab: Progettazione per Apple WatchPaolo Musolino
 
Introduzione a GAE - Alessandro Aglietti e Lorenzo Bugiani
Introduzione a GAE - Alessandro Aglietti e Lorenzo BugianiIntroduzione a GAE - Alessandro Aglietti e Lorenzo Bugiani
Introduzione a GAE - Alessandro Aglietti e Lorenzo Bugianifirenze-gtug
 
Le novità di Ionic 4- Il framework basato su Angular per sviluppare applicazi...
Le novità di Ionic 4- Il framework basato su Angular per sviluppare applicazi...Le novità di Ionic 4- Il framework basato su Angular per sviluppare applicazi...
Le novità di Ionic 4- Il framework basato su Angular per sviluppare applicazi...Antonio Gallo
 
Modi innovativi per costruire App
Modi innovativi per costruire AppModi innovativi per costruire App
Modi innovativi per costruire AppCommit University
 
Sviluppo apps multipiattaforma con visual studio e xamarin
Sviluppo apps multipiattaforma con visual studio e xamarinSviluppo apps multipiattaforma con visual studio e xamarin
Sviluppo apps multipiattaforma con visual studio e xamarinFabio Cozzolino
 
Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02
Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02
Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02Alberto Pasca
 
High specialized vm on open stack cloud
High specialized vm on open stack cloudHigh specialized vm on open stack cloud
High specialized vm on open stack cloudGabriele Baldoni
 
Sviluppare software a colpi di test – II appuntamento: “mani in pasta col BDD.
Sviluppare software a colpi di test – II appuntamento: “mani in pasta col BDD.Sviluppare software a colpi di test – II appuntamento: “mani in pasta col BDD.
Sviluppare software a colpi di test – II appuntamento: “mani in pasta col BDD.Open Campus Tiscali
 
Xcode - Just do it
Xcode - Just do itXcode - Just do it
Xcode - Just do itpragmamark
 
Livin' with Docker - dallo sviluppo alla produzione
Livin' with Docker - dallo sviluppo alla produzioneLivin' with Docker - dallo sviluppo alla produzione
Livin' with Docker - dallo sviluppo alla produzionegiacomos
 
IOS 3.1.3 export vs icloud
IOS 3.1.3 export vs icloudIOS 3.1.3 export vs icloud
IOS 3.1.3 export vs icloudSimone Galiano
 
Csp@scuola smarttv corso1
Csp@scuola smarttv corso1Csp@scuola smarttv corso1
Csp@scuola smarttv corso1CSP Scarl
 
Codice iPhone lavato a caldo: come "restringere" la tua app per Apple Watch
Codice iPhone lavato a caldo: come "restringere" la tua app per Apple WatchCodice iPhone lavato a caldo: come "restringere" la tua app per Apple Watch
Codice iPhone lavato a caldo: come "restringere" la tua app per Apple WatchCodemotion
 
Linux Embedded per l'automazione
Linux Embedded per l'automazioneLinux Embedded per l'automazione
Linux Embedded per l'automazioneDaniele Costarella
 

Similar a Cloud e iOS - Codemotion2013 Roma (20)

Silex, iniziamo
Silex, iniziamoSilex, iniziamo
Silex, iniziamo
 
Progettazione per Apple Watch - Todi Appy Days 2015
Progettazione per Apple Watch - Todi Appy Days 2015Progettazione per Apple Watch - Todi Appy Days 2015
Progettazione per Apple Watch - Todi Appy Days 2015
 
Wearable Lab: Progettazione per Apple Watch
Wearable Lab: Progettazione per Apple WatchWearable Lab: Progettazione per Apple Watch
Wearable Lab: Progettazione per Apple Watch
 
Wp app studio_new
Wp app studio_newWp app studio_new
Wp app studio_new
 
Introduzione a GAE - Alessandro Aglietti e Lorenzo Bugiani
Introduzione a GAE - Alessandro Aglietti e Lorenzo BugianiIntroduzione a GAE - Alessandro Aglietti e Lorenzo Bugiani
Introduzione a GAE - Alessandro Aglietti e Lorenzo Bugiani
 
WordCamp Catania 2019 PWA e TWA
WordCamp Catania 2019 PWA e TWAWordCamp Catania 2019 PWA e TWA
WordCamp Catania 2019 PWA e TWA
 
Le novità di Ionic 4- Il framework basato su Angular per sviluppare applicazi...
Le novità di Ionic 4- Il framework basato su Angular per sviluppare applicazi...Le novità di Ionic 4- Il framework basato su Angular per sviluppare applicazi...
Le novità di Ionic 4- Il framework basato su Angular per sviluppare applicazi...
 
Modi innovativi per costruire App
Modi innovativi per costruire AppModi innovativi per costruire App
Modi innovativi per costruire App
 
Programming iOS lezione 4
Programming iOS lezione 4Programming iOS lezione 4
Programming iOS lezione 4
 
Sviluppo apps multipiattaforma con visual studio e xamarin
Sviluppo apps multipiattaforma con visual studio e xamarinSviluppo apps multipiattaforma con visual studio e xamarin
Sviluppo apps multipiattaforma con visual studio e xamarin
 
Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02
Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02
Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02
 
High specialized vm on open stack cloud
High specialized vm on open stack cloudHigh specialized vm on open stack cloud
High specialized vm on open stack cloud
 
Sviluppare software a colpi di test – II appuntamento: “mani in pasta col BDD.
Sviluppare software a colpi di test – II appuntamento: “mani in pasta col BDD.Sviluppare software a colpi di test – II appuntamento: “mani in pasta col BDD.
Sviluppare software a colpi di test – II appuntamento: “mani in pasta col BDD.
 
Xcode - Just do it
Xcode - Just do itXcode - Just do it
Xcode - Just do it
 
Livin' with Docker - dallo sviluppo alla produzione
Livin' with Docker - dallo sviluppo alla produzioneLivin' with Docker - dallo sviluppo alla produzione
Livin' with Docker - dallo sviluppo alla produzione
 
IOS 3.1.3 export vs icloud
IOS 3.1.3 export vs icloudIOS 3.1.3 export vs icloud
IOS 3.1.3 export vs icloud
 
Csp@scuola smarttv corso1
Csp@scuola smarttv corso1Csp@scuola smarttv corso1
Csp@scuola smarttv corso1
 
Codice iPhone lavato a caldo: come "restringere" la tua app per Apple Watch
Codice iPhone lavato a caldo: come "restringere" la tua app per Apple WatchCodice iPhone lavato a caldo: come "restringere" la tua app per Apple Watch
Codice iPhone lavato a caldo: come "restringere" la tua app per Apple Watch
 
Programming iOS lezione 1
Programming iOS lezione 1Programming iOS lezione 1
Programming iOS lezione 1
 
Linux Embedded per l'automazione
Linux Embedded per l'automazioneLinux Embedded per l'automazione
Linux Embedded per l'automazione
 

Último

Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...Associazione Digital Days
 
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...Associazione Digital Days
 
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...Associazione Digital Days
 
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...Associazione Digital Days
 
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...Associazione Digital Days
 
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”Associazione Digital Days
 
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...Associazione Digital Days
 
Programma Biennale Tecnologia 2024 Torino
Programma Biennale Tecnologia 2024 TorinoProgramma Biennale Tecnologia 2024 Torino
Programma Biennale Tecnologia 2024 TorinoQuotidiano Piemontese
 
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...Associazione Digital Days
 

Último (9)

Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
 
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
 
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
Alessandro Nasi, COO @Djungle Studio – “Cosa delegheresti alla copia di te st...
 
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
 
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
Alessio Mazzotti, Aaron Brancotti; Writer, Screenwriter, Director, UX, Autore...
 
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
Edoardo Di Pietro – “Virtual Influencer vs Umano: Rubiamo il lavoro all’AI”
 
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
Gabriele Mittica, CEO @Corley Cloud – “Come creare un’azienda “nativa in clou...
 
Programma Biennale Tecnologia 2024 Torino
Programma Biennale Tecnologia 2024 TorinoProgramma Biennale Tecnologia 2024 Torino
Programma Biennale Tecnologia 2024 Torino
 
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
Federico Bottino, Lead Venture Builder – “Riflessioni sull’Innovazione: La Cu...
 

Cloud e iOS - Codemotion2013 Roma

  • 1. Francesco Novelli iOS e il Cloud francesco.nove@gmail.com - Run Code
  • 2. Chi Sono? Francesco Novelli francesco.nove@gmail.com - Run Code - iOS Developer - Web Developer - Autore di Programmare applicazioni per iPhone ed iPad -Autore di Programamre applicazioni per Mac OS X
  • 3. Chi Sono? Francesco Novelli francesco.nove@gmail.com - Run Code
  • 4. Di cosa parliamo oggi? Francesco Novelli francesco.nove@gmail.com - Run Code CLOUD!
  • 5. Di cosa parliamo oggi? Francesco Novelli francesco.nove@gmail.com - Run Code e iOS...
  • 6. Di cosa parliamo oggi? Francesco Novelli francesco.nove@gmail.com - Run Code - iCloud - DropBox - Google Drive - Amazon S3
  • 7. iCloud Francesco Novelli francesco.nove@gmail.com - Run Code - Caratteristiche principali - Come implementarlo in un App - Pro - Contro
  • 8. iCloud – Caratteristiche principali Francesco Novelli francesco.nove@gmail.com - Run Code I numeri - 250 milioni di utenti - 500 milioni di iOS Device attivi - 50% degli utenti usa iCloud
  • 9. iCloud – Caratteristiche principali Francesco Novelli francesco.nove@gmail.com - Run Code - Sincronizzazione automatica - Implementazione nativa nell’OS - Risoluzione conflitti automatica - 5 GB di spazio gratuito - Disponibile per Mac OS X
  • 10. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code - Non necessita di framework - Certificati necessari - iCloud Storage - iCloud Key-Value Data Storage
  • 11. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code Certificati: Entitlement attivo nell’app
  • 12. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code Certificati: AppID in iOS Dev Portal
  • 13. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code Certificati: Provisioning Profile dedicato
  • 14. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code iCloud Data Storage: Archiviazione file Salvataggio Database Salvataggio CoreData Condivisione file tra devices
  • 15. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code iCloud Data Storage: // Controllare che iCloud sia attivo id currentToken = [[NSFileManager defaultManager] ubiquityIdentityToken]; if (!currentToken) { // Alert user }
  • 16. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code self.query = [[NSMetadataQuery alloc] init]; [self.query setSearchScopes: [NSArray arrayWithObject: NSMetadataQueryUbiquitousDocumentsScope]]; NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K like 'Note_*'", NSMetadataItemFSNameKey]; [self.query setPredicate:pred];
  • 17. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code for (NSMetadataItem *item in [query results]) { NSURL *url = [item valueForAttribute:NSMetadataItemURLKey]; Note *nota = [[Note alloc] initWithFileURL:url]; [nota openWithCompletionHandler:^(BOOL success) { if (success) { [self.notes addObject:nota]; } }]; }
  • 18. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code // CREARE UN FILE NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; NSURL *ubiquitousPackage = [[ubiq URLByAppendingPathComponent:@"Documents"] URLByAppendingPathComponent:fileName]; Note *nota = [[Note alloc] initWithFileURL:ubiquitousPackage]; [nota saveToURL:[nota fileURL] forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) { if (success) { [self.notes addObject:nota]; [self.tableView reloadData]; } }]; ];
  • 19. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code DA RICORDARE - NSFileManager per le operazioni di I/O - NSMetadataQuery per la ricerca dei file - I file vengono scaricati solo in caso di necessità - Caricare solo le differenze!
  • 20. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code iCloud Key-Value Storage Salvataggio impostazioni Salvataggio stato dell’applicazione Salvataggio piccoli dati
  • 21. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code Classi ammesse: • NSData • NSString • NSNumber • NSDate • NSArray • NSDictionary
  • 22. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code Scrivere un dato [[NSUbiquitousKeyValueStore defaultStore] setObject:@"testo" forKey:@"key"];
  • 23. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code Sincronizzare i dati [[NSUbiquitousKeyValueStore defaultStore] synchronize];
  • 24. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code Leggere i dati NSLog(@"%@",[[NSUbiquitousKeyValueSto re defaultStore] objectForKey:@"key"]);
  • 25. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code NSUbiquitousKeyValueStore == NSUserDefaults
  • 26. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code PRO Profondamente integrato con l’OS Poco codice e nessuna dipendenza Compatibilità da iOS 5 Compatibilità perfetta con OS X
  • 27. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code CONTRO Disponibile SOLO con device Apple Sandbox impedisce spazio condiviso L’utente non può accedere direttamente ai file
  • 28. Dropbox Francesco Novelli francesco.nove@gmail.com - Run Code - Caratteristiche principali - Come implementarlo in un App - Pro - Contro
  • 29. Dropbox– Caratteristiche principali Francesco Novelli francesco.nove@gmail.com - Run Code - 100 milioni di utenti - Gratis fino a 16 Gb di spazio - LAN Sync - Condivisione cartelle tra utenti
  • 30. Dropbox– Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code Registrazione nell’App Console: https://www.dropbox.com/developers/apps - APP Type: API - APP Name Univoco - Access: App Folder
  • 31. Dropbox– Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code
  • 32. Dropbox– Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code App key App secret
  • 33. Dropbox– Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code Download Dropbox iOS SDK https://www.dropbox.com/developers/sync/ tutorial/ios Dropbox.framework in Xcode
  • 34. Dropbox– Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code Altri framework necessari: • CFNetwork.framework • Security.framework • SystemConfiguration.framework • QuartzCore.framework
  • 35. Dropbox– Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code #import <Dropbox/Dropbox.h> - (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)opts { ... // The account manager stores all the account info. Create this when your app launches DBAccountManager* accountMgr = [[DBAccountManager alloc] initWithAppKey:@"APP_KEY" secret:@"APP_SECRET"]; [DBAccountManager setSharedManager:accountMgr]; DBAccount *account = accountMgr.linkedAccount; if (account) { DBFilesystem *filesystem = [[DBFilesystem alloc] initWithAccount:account]; [DBFilesystem setSharedFilesystem:filesystem]; } ... }
  • 36. Dropbox– Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code Info.plist <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>db-APP_KEY</string> </array> </dict> </array>
  • 37. Dropbox– Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url sourceApplication:(NSString *)source annotation:(id)annotation { DBAccount *account = [[DBAccountManager sharedManager] handleOpenURL:url]; if (account) { DBFilesystem *filesystem = [[DBFilesystem alloc] initWithAccount:account]; [DBFilesystem setSharedFilesystem:filesystem]; NSLog(@"App linked successfully!"); return YES; } ... }
  • 38. Dropbox– Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code // ELENCARE FILE NSArray *contents = [[DBFilesystem sharedFilesystem] listFolder:[DBPath root] error:nil]; for (DBFileInfo *info in contents) { NSLog(@"%@", info.path); }
  • 39. Dropbox– Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code // SCRIVERE UN FILE DBPath *newPath = [[DBPath root] childPath:@"hello.txt"]; DBFile *file = [[DBFilesystem sharedFilesystem] createFile:newPath error:nil]; [file writeString:@"Hello World!" error:nil]; // LEGGERE UN FILE DBPath *newPath = [[DBPath root] childPath:@"hello.txt"]; DBFile *file = [[DBFilesystem sharedFilesystem] createFile:newPath error:nil]; NSString *fileContent [file readString:@"Hello World!" error:nil];
  • 40. Dropbox– Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code // CONTROLLARE LE MODIFICHE DBPath *path = [[DBPath root] childPath:@"change-me.txt"]; self.file = [[DBFilesystem sharedFilesystem] createFile:path error:nil]; // Next, register for changes on that file [self.file addObserver:self block:^() { // This block will be called every time your file changes // if newerStatus is not nil, it means a newer version is available DBFileStatus *newerStatus = file.newerStatus; if (newerStatus) { if (!newerStatus.cached) { NSLog(@"newerStatus.cached == NO; this means the file downloading"); } else { // Update to the newly available version and print it out [file update:nil]; NSLog(@"The file is done downloading: %@", [file readString:nil]); } } }];
  • 41. Dropbox - PRO Francesco Novelli francesco.nove@gmail.com - Run Code PRO Disponibile su tutte le piattaforme File accessibili da qualsiasi app Possibilità di ampliare lo spazio gratuitamente
  • 42. Dropbox - CONTRO Francesco Novelli francesco.nove@gmail.com - Run Code CONTRO Necessità di diverse dipendenze Codice più complesso di iCloud
  • 43. Google Drive Francesco Novelli francesco.nove@gmail.com - Run Code - Caratteristiche principali - Come implementarlo in un App - Pro - Contro
  • 44. Google Drive Francesco Novelli francesco.nove@gmail.com - Run Code - TUTTI hanno un account Google - Integrato benissimo con Android.. - …ed ha le API per iOS
  • 45. Google Drive Francesco Novelli francesco.nove@gmail.com - Run Code - Registrare l’app nel Google API Console: https://code.google.com/apis/console/ - Importare svariati framework - Importare i framework di Google Drive OPPURE
  • 46. Google Drive Francesco Novelli francesco.nove@gmail.com - Run Code Seguire alla lettera le istruzioni di questa pagina: https://developers.google.com/drive/quickst art-ios (non il video, l’app non compila!)
  • 47. Google Drive Francesco Novelli francesco.nove@gmail.com - Run Code GTLDriveFile *file = [GTLDriveFile object]; file.title = [dateFormat stringFromDate:[NSDate date]]; file.descriptionProperty = @”Desc"; file.mimeType = @"image/png"; NSData *data = …; // DATA TO UPLOAD GTLUploadParameters *uploadParameters = [GTLUploadParameters uploadParametersWithData:data MIMEType:file.mimeType]; GTLQueryDrive *query = [GTLQueryDrive queryForFilesInsertWithObject:file uploadParameters:uploadParameters];
  • 48. Google Drive Francesco Novelli francesco.nove@gmail.com - Run Code [self.driveService executeQuery:query completionHandler:^(GTLServiceTicket *ticket, GTLDriveFile *insertedFile, NSError *error) { if (error == nil) { NSLog(@"File ID: %@", insertedFile.identifier); } }];
  • 49. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code PRO Tutti hanno un account Google Disponibile in tutte le piattaforme €/Gb più basso della concorrenza
  • 50. iCloud – Come implementarlo in un App Francesco Novelli francesco.nove@gmail.com - Run Code CONTRO TANTE dipendenze Codice complesso Live Sync non disponibile
  • 51. Amazon S3 Francesco Novelli francesco.nove@gmail.com - Run Code - Caratteristiche principali - Come implementarlo in un App - Pro - Contro
  • 52. Amazon S3 Francesco Novelli francesco.nove@gmail.com - Run Code - Spazio dello sviluppatore - L’utente non ha bisogno di un account - Servizio totalmente differente dagli altri - Supporto a CoreData
  • 53. Amazon S3 Francesco Novelli francesco.nove@gmail.com - Run Code - Scaricare l’SDK dal sito AWS: http://aws.amazon.com/sdkforios/ - Importare AWSiOSSDK.framework nel progetto
  • 54. Amazon S3 Francesco Novelli francesco.nove@gmail.com - Run Code AWSPersistence.framework CoreData tramite S3, ma ancora in beta
  • 55. Amazon S3 Francesco Novelli francesco.nove@gmail.com - Run Code self.s3 = [[[AmazonS3Client alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY] autorelease]; self.s3.endpoint = [AmazonEndpoints s3Endpoint:US_WEST_2]; S3CreateBucketRequest *createBucketRequest = [[[S3CreateBucketRequest alloc] initWithName:[Constants pictureBucket] andRegion:[S3Region USWest2]] autorelease]; S3CreateBucketResponse *createBucketResponse = [self.s3 createBucket:createBucketRequest]; if(createBucketResponse.error != nil) { NSLog(@"Error: %@", createBucketResponse.error); }
  • 56. Amazon S3 Francesco Novelli francesco.nove@gmail.com - Run Code S3PutObjectRequest *por = [[[S3PutObjectRequest alloc] initWithKey:PICTURE_NAME inBucket:[Constants pictureBucket]] autorelease]; por.contentType = @"image/jpeg"; por.data = imageData; S3PutObjectResponse *putObjectResponse = [self.s3 putObject:por]; [self performSelectorOnMainThread:@selector(showCheckErrorMessage:) withObject:putObjectResponse.error waitUntilDone:NO];
  • 57. Amazon S3 Francesco Novelli francesco.nove@gmail.com - Run Code S3ResponseHeaderOverrides *override = [[[S3ResponseHeaderOverrides alloc] init] autorelease]; override.contentType = @"image/jpeg"; // Request a pre-signed URL to picture that has been uplaoded. S3GetPreSignedURLRequest *gpsur = [[[S3GetPreSignedURLRequest alloc] init] autorelease]; gpsur.key = PICTURE_NAME; gpsur.bucket = [Constants pictureBucket]; gpsur.expires = [NSDate dateWithTimeIntervalSinceNow:(NSTimeInterval) 3600]; gpsur.responseHeaderOverrides = override; // Get the URL NSError *error; NSURL *url = [self.s3 getPreSignedURL:gpsur error:&error];
  • 58. Amazon S3 – PRO Francesco Novelli francesco.nove@gmail.com - Run Code PRO Spazio praticamente illimitato Semplice implementazione File condivisi con tutti L’utente non ha bisogno di un account
  • 59. Amazon S3 – CONTRO Francesco Novelli francesco.nove@gmail.com - Run Code CONTRO Lo spazio non è personale Per grandi progetti da valutare il €/Gb Costi per il trasferimento dei file
  • 60. In conclusione Francesco Novelli francesco.nove@gmail.com - Run Code
  • 61. In conclusione Francesco Novelli francesco.nove@gmail.com - Run Code - iCloud per progetti iOS-Only (o Mac) - Dropbox per applicazioni su più OS - Google Drive come alternativa a Dropbox - Amazon S3 per far caricare file all’utente
  • 62. In conclusione Francesco Novelli francesco.nove@gmail.com - Run Code Q&A Time… francesco.nove@gmail.com @iF9 www.9lli.it/francesco www.facebook.com/fnove