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. Dopodiché, devi scrivere codice nella tua app mobile per autenticarti e comunicare con questo servizio intermedio.
Un modo per creare questa API REST è utilizzare Firebase Authentication e Functions, che ti offre un gateway serverless gestito per le API Cloud di Google 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 a pagamento di Cloud Vision tramite il tuo progetto Cloud, quindi prima di procedere valuta se questo meccanismo di autenticazione è sufficiente per il tuo caso d'uso.
Prima di iniziare
Configura il tuo progetto
Se non hai ancora aggiunto Firebase alla tua app, fallo seguendo i passaggi della guida introduttiva.Utilizza Swift Package Manager per installare e gestire le dipendenze di Firebase.
- In Xcode, con il progetto dell'app aperto, vai a File > Add Packages (File > Aggiungi pacchetti).
- Quando richiesto, aggiungi il repository dell'SDK delle piattaforme Apple di Firebase:
- Scegli la libreria Firebase ML.
- Aggiungi il flag
-ObjCalla sezione Other Linker Flags (Altri flag del linker) delle impostazioni di compilazione della destinazione. - Al termine, Xcode inizierà automaticamente a risolvere e scaricare le tue dipendenze in background.
https://github.com/firebase/firebase-ios-sdk.git
Come passaggio successivo, esegui alcune configurazioni nell'app:
- Nella tua app, importa Firebase:
Swift
import FirebaseMLModelDownloader
Objective-C
@import FirebaseMLModelDownloader;
Mancano ancora alcuni passaggi di configurazione e siamo pronti per iniziare:
-
Se non l'hai ancora fatto, abilita le API basate sul cloud per il tuo progetto: ora:
- Apri la pagina delle Firebase ML API nella console Firebase.
-
Se non hai ancora eseguito l'upgrade del tuo progetto al piano tariffario Blaze con pagamento a consumo, fai clic su Esegui l'upgrade per farlo. Ti verrà chiesto di eseguire l'upgrade solo se il tuo progetto non è incluso nel piano tariffario Blaze.
Solo i progetti inclusi nel piano tariffario Blaze possono utilizzare le API basate sul cloud.
- Se le API basate sul cloud non sono ancora abilitate, fai clic su Abilita API basate sul cloud.
- Configura le chiavi API Firebase esistenti in modo da non consentire l'accesso all'API Cloud
Vision:
- Apri la pagina Credenziali della console Cloud.
- Per ogni chiave API nell'elenco, apri la visualizzazione di modifica e, nella sezione Limitazioni chiave, aggiungi all'elenco tutte le API disponibili tranne l'API Cloud Vision.
Esegui il deployment della funzione richiamabile
Come passaggio successivo, esegui il deployment della 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. Puoi modificare la funzione per requisiti diversi.
Per eseguire il deployment della funzione:
- Clona o scarica il repository functions-samples
e passa alla directory
Node-1st-gen/vision-annotate-image:git clone https://github.com/firebase/functions-samplescd Node-1st-gen/vision-annotate-image - Installa le dipendenze:
cd functionsnpm installcd .. - Se non hai l'interfaccia a riga di comando di Firebase, installala.
- Inizializza un progetto Firebase nella
vision-annotate-imagedirectory. Quando richiesto, seleziona il progetto nell'elenco.firebase init
- Esegui il deployment della funzione:
firebase deploy --only functions:annotateImage
Aggiungi Firebase Authentication alla tua app
La funzione richiamabile di cui hai eseguito il deployment sopra rifiuterà qualsiasi richiesta da utenti non autenticati della tua app. Se non l'hai ancora fatto, dovrai aggiungere Firebase Authentication alla tua app.
Aggiungi le dipendenze necessarie alla tua app
Utilizza Swift Package Manager per installare la libreria Cloud Functions per Firebase.
Ora puoi iniziare a riconoscere il testo nelle immagini.
1. Prepara l'immagine di input
Per chiamare Cloud Vision, l'immagine deve essere formattata come stringa con codifica base64. Per elaborare unUIImage:
Swift
guard let imageData = uiImage.jpegData(compressionQuality: 1.0) else { return } let base64encodedImage = imageData.base64EncodedString()
Objective-C
NSData *imageData = UIImageJPEGRepresentation(uiImage, 1.0f); NSString *base64encodedImage = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];
2. Richiama la funzione richiamabile per riconoscere il testo
Per riconoscere i punti di riferimento in un'immagine, richiama la funzione richiamabile passando una richiesta JSON di Cloud Vision.Innanzitutto, inizializza un'istanza di Cloud Functions:
Swift
lazy var functions = Functions.functions()Objective-C
@property(strong, nonatomic) FIRFunctions *functions;Crea la richiesta. L'API Cloud Vision supporta due tipi di rilevamento del testo:
TEXT_DETECTIONeDOCUMENT_TEXT_DETECTION. Consulta la documentazione sull'OCR di Cloud Vision per conoscere la differenza tra i due casi d'uso.Swift
let requestData = [ "image": ["content": base64encodedImage], "features": ["type": "TEXT_DETECTION"], "imageContext": ["languageHints": ["en"]] ]Objective-C
NSDictionary *requestData = @{ @"image": @{@"content": base64encodedImage}, @"features": @{@"type": @"TEXT_DETECTION"}, @"imageContext": @{@"languageHints": @[@"en"]} };Infine, richiama la funzione:
Swift
do { let result = try await functions.httpsCallable("annotateImage").call(requestData) print(result) } catch { 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] } // ... } }Objective-C
[[_functions HTTPSCallableWithName:@"annotateImage"] callWithObject:requestData completion:^(FIRHTTPSCallableResult * _Nullable result, NSError * _Nullable error) { if (error) { if ([error.domain isEqualToString:@"com.firebase.functions"]) { FIRFunctionsErrorCode code = error.code; NSString *message = error.localizedDescription; NSObject *details = error.userInfo[@"details"]; } // ... } // Function completed succesfully // Get information about labeled objects }];
3. Estrai il testo dai blocchi di testo riconosciuto
Se l'operazione di riconoscimento del testo ha esito positivo, nel risultato dell'attività viene restituita una risposta JSON di
BatchAnnotateImagesResponse. Le annotazioni di testo sono disponibili nell'
fullTextAnnotation oggetto.
Puoi ottenere il testo riconosciuto come stringa nel campo text. Ad esempio:
Swift
let annotation = result.flatMap { $0.data as? [String: Any] }
.flatMap { $0["fullTextAnnotation"] }
.flatMap { $0 as? [String: Any] }
guard let annotation = annotation else { return }
if let text = annotation["text"] as? String {
print("Complete annotation: \(text)")
}
Objective-C
NSDictionary *annotation = result.data[@"fullTextAnnotation"];
if (!annotation) { return; }
NSLog(@"\nComplete annotation:");
NSLog(@"\n%@", annotation[@"text"]);
Puoi anche ottenere informazioni specifiche per le regioni dell'immagine. Per ogni block, paragraph, word e symbol, puoi ottenere il testo riconosciuto nella regione e le coordinate del riquadro di delimitazione della regione. Ad esempio:
Swift
guard let pages = annotation["pages"] as? [[String: Any]] else { return }
for page in pages {
var pageText = ""
guard let blocks = page["blocks"] as? [[String: Any]] else { continue }
for block in blocks {
var blockText = ""
guard let paragraphs = block["paragraphs"] as? [[String: Any]] else { continue }
for paragraph in paragraphs {
var paragraphText = ""
guard let words = paragraph["words"] as? [[String: Any]] else { continue }
for word in words {
var wordText = ""
guard let symbols = word["symbols"] as? [[String: Any]] else { continue }
for symbol in symbols {
let text = symbol["text"] as? String ?? ""
let confidence = symbol["confidence"] as? Float ?? 0.0
wordText += text
print("Symbol text: \(text) (confidence: \(confidence)%n")
}
let confidence = word["confidence"] as? Float ?? 0.0
print("Word text: \(wordText) (confidence: \(confidence)%n%n")
let boundingBox = word["boundingBox"] as? [Float] ?? [0.0, 0.0, 0.0, 0.0]
print("Word bounding box: \(boundingBox.description)%n")
paragraphText += wordText
}
print("%nParagraph: %n\(paragraphText)%n")
let boundingBox = paragraph["boundingBox"] as? [Float] ?? [0.0, 0.0, 0.0, 0.0]
print("Paragraph bounding box: \(boundingBox)%n")
let confidence = paragraph["confidence"] as? Float ?? 0.0
print("Paragraph Confidence: \(confidence)%n")
blockText += paragraphText
}
pageText += blockText
}
}
Objective-C
for (NSDictionary *page in annotation[@"pages"]) {
NSMutableString *pageText = [NSMutableString new];
for (NSDictionary *block in page[@"blocks"]) {
NSMutableString *blockText = [NSMutableString new];
for (NSDictionary *paragraph in block[@"paragraphs"]) {
NSMutableString *paragraphText = [NSMutableString new];
for (NSDictionary *word in paragraph[@"words"]) {
NSMutableString *wordText = [NSMutableString new];
for (NSDictionary *symbol in word[@"symbols"]) {
NSString *text = symbol[@"text"];
[wordText appendString:text];
NSLog(@"Symbol text: %@ (confidence: %@\n", text, symbol[@"confidence"]);
}
NSLog(@"Word text: %@ (confidence: %@\n\n", wordText, word[@"confidence"]);
NSLog(@"Word bounding box: %@\n", word[@"boundingBox"]);
[paragraphText appendString:wordText];
}
NSLog(@"\nParagraph: \n%@\n", paragraphText);
NSLog(@"Paragraph bounding box: %@\n", paragraph[@"boundingBox"]);
NSLog(@"Paragraph Confidence: %@\n", paragraph[@"confidence"]);
[blockText appendString:paragraphText];
}
[pageText appendString:blockText];
}
}