Etichetta le immagini in modo sicuro con Cloud Vision utilizzando Firebase Auth and Functions su piattaforme Apple

Per chiamare un'API Google Cloud dalla tua app, devi creare un'API REST intermedia che gestisca l'autorizzazione e protegga i valori segreti come le chiavi API. È quindi necessario scrivere il codice nell'app mobile per autenticarsi e comunicare con questo servizio intermedio.

Un modo per creare questa API REST è utilizzare l'autenticazione e le funzioni Firebase, che ti offre un gateway gestito e serverless per le API di Google Cloud che gestisce l'autenticazione e può essere chiamato dalla tua app mobile con SDK predefiniti.

Questa guida mostra come utilizzare questa tecnica per chiamare l'API Cloud Vision dalla tua app. Questo metodo consentirà a tutti gli utenti autenticati di accedere ai servizi fatturati Cloud Vision tramite il tuo progetto Cloud, quindi valuta se questo meccanismo di autenticazione è sufficiente per il tuo caso d'uso prima di procedere.

Prima di iniziare

Configura il tuo progetto

Se non hai già aggiunto Firebase alla tua app, fallo seguendo i passaggi nella Guida introduttiva .

Usa Swift Package Manager per installare e gestire le dipendenze di Firebase.

  1. In Xcode, con il progetto dell'app aperto, vai su File > Aggiungi pacchetti .
  2. Quando richiesto, aggiungi il repository SDK delle piattaforme Apple Firebase:
  3.   https://github.com/firebase/firebase-ios-sdk
  4. Scegli la libreria Firebase ML.
  5. Al termine, Xcode inizierà automaticamente a risolvere e scaricare le tue dipendenze in background.

Quindi, esegui alcune impostazioni in-app:

  1. Nella tua app, importa Firebase:

    Veloce

    import FirebaseMLModelDownloader

    Obiettivo-C

    @import FirebaseMLModelDownloader;

Ancora pochi passaggi di configurazione e siamo pronti per partire:

  1. Se non hai già abilitato le API basate su cloud per il tuo progetto, fallo ora:

    1. Apri la pagina delle API Firebase ML della console Firebase.
    2. Se non hai già aggiornato il tuo progetto al piano tariffario Blaze, fai clic su Aggiorna per farlo. (Ti verrà richiesto di eseguire l'aggiornamento solo se il tuo progetto non è nel piano Blaze.)

      Solo i progetti di livello Blaze possono utilizzare le API basate su cloud.

    3. Se le API basate su cloud non sono già abilitate, fai clic su Abilita API basate su cloud .
  2. Configura le tue chiavi API Firebase esistenti per impedire l'accesso all'API Cloud Vision:
    1. Apri la pagina Credenziali della console Cloud.
    2. Per ciascuna chiave API nell'elenco, apri la visualizzazione di modifica e, nella sezione Restrizioni chiave, aggiungi all'elenco tutte le API disponibili tranne l'API Cloud Vision.

Distribuire la funzione richiamabile

Quindi, distribuisci la funzione cloud che utilizzerai per collegare la tua app e l'API Cloud Vision. Il repository functions-samples contiene un esempio che puoi utilizzare.

Per impostazione predefinita, l'accesso all'API Cloud Vision tramite questa funzione consentirà solo agli utenti autenticati della tua app di accedere all'API Cloud Vision. È possibile modificare la funzione per esigenze diverse.

Per distribuire la funzione:

  1. Clona o scarica il repository functions-samples e passa alla directory vision-annotate-image :
    git clone https://github.com/firebase/functions-samples
    cd vision-annotate-image
    
  2. Installa le dipendenze:
    cd functions
    npm install
    cd ..
    
  3. Se non hai la CLI di Firebase, installala .
  4. Inizializza un progetto Firebase nella directory vision-annotate-image . Quando richiesto, seleziona il tuo progetto nell'elenco.
    firebase init
  5. Distribuire la funzione:
    firebase deploy --only functions:annotateImage

Aggiungi Firebase Auth alla tua app

La funzione richiamabile distribuita sopra rifiuterà qualsiasi richiesta da utenti non autenticati della tua app. Se non l'hai già fatto, dovrai aggiungere Firebase Auth alla tua app.

Aggiungi le dipendenze necessarie alla tua app

Usa Swift Package Manager per installare la libreria Cloud Functions per Firebase.

Ora sei pronto per etichettare le immagini.

1. Preparare l'immagine di input

Per poter chiamare Cloud Vision, l'immagine deve essere formattata come stringa con codifica base64. Per elaborare UIImage :

Veloce

guard let imageData = uiImage.jpegData(compressionQuality: 1.0f) else { return }
let base64encodedImage = imageData.base64EncodedString()

Obiettivo-C

NSData *imageData = UIImageJPEGRepresentation(uiImage, 1.0f);
NSString *base64encodedImage =
  [imageData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];

2. Richiamare la funzione richiamabile per etichettare l'immagine

Per etichettare oggetti in un'immagine, richiama la funzione richiamabile passando una richiesta JSON Cloud Vision .

  1. Innanzitutto, inizializza un'istanza di Cloud Functions:

    Veloce

    lazy var functions = Functions.functions()
    

    Obiettivo-C

    @property(strong, nonatomic) FIRFunctions *functions;
    
  2. Crea una richiesta con Tipo impostato su LABEL_DETECTION :

    Veloce

    let requestData = [
      "image": ["content": base64encodedImage],
      "features": ["maxResults": 5, "type": "LABEL_DETECTION"]
    ]
    

    Obiettivo-C

    NSDictionary *requestData = @{
      @"image": @{@"content": base64encodedImage},
      @"features": @{@"maxResults": @5, @"type": @"LABEL_DETECTION"}
    };
    
  3. Infine, invoca la funzione:

    Veloce

    functions.httpsCallable("annotateImage").call(requestData) { (result, error) in
      if let error = error as NSError? {
        if error.domain == FunctionsErrorDomain {
          let code = FunctionsErrorCode(rawValue: error.code)
          let message = error.localizedDescription
          let details = error.userInfo[FunctionsErrorDetailsKey]
        }
        // ...
      }
      // Function completed succesfully
    }
    

    Obiettivo-C

    [[_functions HTTPSCallableWithName:@"annotateImage"]
                              callWithObject:requestData
                                  completion:^(FIRHTTPSCallableResult * _Nullable result, NSError * _Nullable error) {
            if (error) {
              if (error.domain == FIRFunctionsErrorDomain) {
                FIRFunctionsErrorCode code = error.code;
                NSString *message = error.localizedDescription;
                NSObject *details = error.userInfo[FIRFunctionsErrorDetailsKey];
              }
              // ...
            }
            // Function completed succesfully
            // Get information about labeled objects
    
          }];
    

3. Ottieni informazioni sugli oggetti etichettati

Se l'operazione di etichettatura dell'immagine ha esito positivo, nel risultato dell'attività verrà restituita una risposta JSON di BatchAnnotateImagesResponse . Ogni oggetto nella matrice labelAnnotations rappresenta qualcosa che è stato etichettato nell'immagine. Per ogni etichetta, puoi ottenere la descrizione testuale dell'etichetta, il suo ID entità Knowledge Graph (se disponibile) e il punteggio di affidabilità della corrispondenza. Per esempio:

Veloce

if let labelArray = (result?.data as? [String: Any])?["labelAnnotations"] as? [[String:Any]] {
  for labelObj in labelArray {
    let text = labelObj["description"]
    let entityId = labelObj["mid"]
    let confidence = labelObj["score"]
  }
}

Obiettivo-C

NSArray *labelArray = result.data[@"labelAnnotations"];
for (NSDictionary *labelObj in labelArray) {
  NSString *text = labelObj[@"description"];
  NSString *entityId = labelObj[@"mid"];
  NSNumber *confidence = labelObj[@"score"];
}
,

Per chiamare un'API Google Cloud dalla tua app, devi creare un'API REST intermedia che gestisca l'autorizzazione e protegga i valori segreti come le chiavi API. È quindi necessario scrivere il codice nell'app mobile per autenticarsi e comunicare con questo servizio intermedio.

Un modo per creare questa API REST è utilizzare l'autenticazione e le funzioni Firebase, che ti offre un gateway gestito e serverless per le API di Google Cloud che gestisce l'autenticazione e può essere chiamato dalla tua app mobile con SDK predefiniti.

Questa guida mostra come utilizzare questa tecnica per chiamare l'API Cloud Vision dalla tua app. Questo metodo consentirà a tutti gli utenti autenticati di accedere ai servizi fatturati Cloud Vision tramite il tuo progetto Cloud, quindi valuta se questo meccanismo di autenticazione è sufficiente per il tuo caso d'uso prima di procedere.

Prima di iniziare

Configura il tuo progetto

Se non hai già aggiunto Firebase alla tua app, fallo seguendo i passaggi nella Guida introduttiva .

Usa Swift Package Manager per installare e gestire le dipendenze di Firebase.

  1. In Xcode, con il progetto dell'app aperto, vai su File > Aggiungi pacchetti .
  2. Quando richiesto, aggiungi il repository SDK delle piattaforme Apple Firebase:
  3.   https://github.com/firebase/firebase-ios-sdk
  4. Scegli la libreria Firebase ML.
  5. Al termine, Xcode inizierà automaticamente a risolvere e scaricare le tue dipendenze in background.

Quindi, esegui alcune impostazioni in-app:

  1. Nella tua app, importa Firebase:

    Veloce

    import FirebaseMLModelDownloader

    Obiettivo-C

    @import FirebaseMLModelDownloader;

Ancora pochi passaggi di configurazione e siamo pronti per partire:

  1. Se non hai già abilitato le API basate su cloud per il tuo progetto, fallo ora:

    1. Apri la pagina delle API Firebase ML della console Firebase.
    2. Se non hai già aggiornato il tuo progetto al piano tariffario Blaze, fai clic su Aggiorna per farlo. (Ti verrà richiesto di eseguire l'aggiornamento solo se il tuo progetto non è nel piano Blaze.)

      Solo i progetti di livello Blaze possono utilizzare le API basate su cloud.

    3. Se le API basate su cloud non sono già abilitate, fai clic su Abilita API basate su cloud .
  2. Configura le tue chiavi API Firebase esistenti per impedire l'accesso all'API Cloud Vision:
    1. Apri la pagina Credenziali della console Cloud.
    2. Per ciascuna chiave API nell'elenco, apri la visualizzazione di modifica e, nella sezione Restrizioni chiave, aggiungi all'elenco tutte le API disponibili tranne l'API Cloud Vision.

Distribuire la funzione richiamabile

Quindi, distribuisci la funzione cloud che utilizzerai per collegare la tua app e l'API Cloud Vision. Il repository functions-samples contiene un esempio che puoi utilizzare.

Per impostazione predefinita, l'accesso all'API Cloud Vision tramite questa funzione consentirà solo agli utenti autenticati della tua app di accedere all'API Cloud Vision. È possibile modificare la funzione per esigenze diverse.

Per distribuire la funzione:

  1. Clona o scarica il repository functions-samples e passa alla directory vision-annotate-image :
    git clone https://github.com/firebase/functions-samples
    cd vision-annotate-image
    
  2. Installa le dipendenze:
    cd functions
    npm install
    cd ..
    
  3. Se non hai la CLI di Firebase, installala .
  4. Inizializza un progetto Firebase nella directory vision-annotate-image . Quando richiesto, seleziona il tuo progetto nell'elenco.
    firebase init
  5. Distribuire la funzione:
    firebase deploy --only functions:annotateImage

Aggiungi Firebase Auth alla tua app

La funzione richiamabile distribuita sopra rifiuterà qualsiasi richiesta da utenti non autenticati della tua app. Se non l'hai già fatto, dovrai aggiungere Firebase Auth alla tua app.

Aggiungi le dipendenze necessarie alla tua app

Usa Swift Package Manager per installare la libreria Cloud Functions per Firebase.

Ora sei pronto per etichettare le immagini.

1. Preparare l'immagine di input

Per poter chiamare Cloud Vision, l'immagine deve essere formattata come stringa con codifica base64. Per elaborare UIImage :

Veloce

guard let imageData = uiImage.jpegData(compressionQuality: 1.0f) else { return }
let base64encodedImage = imageData.base64EncodedString()

Obiettivo-C

NSData *imageData = UIImageJPEGRepresentation(uiImage, 1.0f);
NSString *base64encodedImage =
  [imageData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];

2. Richiamare la funzione richiamabile per etichettare l'immagine

Per etichettare oggetti in un'immagine, richiama la funzione richiamabile passando una richiesta JSON Cloud Vision .

  1. Innanzitutto, inizializza un'istanza di Cloud Functions:

    Veloce

    lazy var functions = Functions.functions()
    

    Obiettivo-C

    @property(strong, nonatomic) FIRFunctions *functions;
    
  2. Crea una richiesta con Tipo impostato su LABEL_DETECTION :

    Veloce

    let requestData = [
      "image": ["content": base64encodedImage],
      "features": ["maxResults": 5, "type": "LABEL_DETECTION"]
    ]
    

    Obiettivo-C

    NSDictionary *requestData = @{
      @"image": @{@"content": base64encodedImage},
      @"features": @{@"maxResults": @5, @"type": @"LABEL_DETECTION"}
    };
    
  3. Infine, invoca la funzione:

    Veloce

    functions.httpsCallable("annotateImage").call(requestData) { (result, error) in
      if let error = error as NSError? {
        if error.domain == FunctionsErrorDomain {
          let code = FunctionsErrorCode(rawValue: error.code)
          let message = error.localizedDescription
          let details = error.userInfo[FunctionsErrorDetailsKey]
        }
        // ...
      }
      // Function completed succesfully
    }
    

    Obiettivo-C

    [[_functions HTTPSCallableWithName:@"annotateImage"]
                              callWithObject:requestData
                                  completion:^(FIRHTTPSCallableResult * _Nullable result, NSError * _Nullable error) {
            if (error) {
              if (error.domain == FIRFunctionsErrorDomain) {
                FIRFunctionsErrorCode code = error.code;
                NSString *message = error.localizedDescription;
                NSObject *details = error.userInfo[FIRFunctionsErrorDetailsKey];
              }
              // ...
            }
            // Function completed succesfully
            // Get information about labeled objects
    
          }];
    

3. Ottieni informazioni sugli oggetti etichettati

Se l'operazione di etichettatura dell'immagine ha esito positivo, nel risultato dell'attività verrà restituita una risposta JSON di BatchAnnotateImagesResponse . Ogni oggetto nella matrice labelAnnotations rappresenta qualcosa che è stato etichettato nell'immagine. Per ogni etichetta, puoi ottenere la descrizione testuale dell'etichetta, il suo ID entità Knowledge Graph (se disponibile) e il punteggio di affidabilità della corrispondenza. Per esempio:

Veloce

if let labelArray = (result?.data as? [String: Any])?["labelAnnotations"] as? [[String:Any]] {
  for labelObj in labelArray {
    let text = labelObj["description"]
    let entityId = labelObj["mid"]
    let confidence = labelObj["score"]
  }
}

Obiettivo-C

NSArray *labelArray = result.data[@"labelAnnotations"];
for (NSDictionary *labelObj in labelArray) {
  NSString *text = labelObj[@"description"];
  NSString *entityId = labelObj[@"mid"];
  NSNumber *confidence = labelObj[@"score"];
}