如要從應用程式呼叫 Google Cloud API,您必須建立用於處理授權並保護密鑰值 (例如 API 金鑰) 的中繼 REST API。接著,您必須在行動應用程式中編寫程式碼,以便驗證這個中繼服務並與其通訊。
建立此 REST API 的其中一種方法是使用 Firebase 驗證和函式。這個 API 為 Google Cloud API 提供代管的無伺服器閘道,可處理驗證作業,並透過預先建構的 SDK 從行動應用程式呼叫。
本指南示範如何使用這項技巧,從應用程式呼叫 Cloud Vision API。這個方法會允許所有通過驗證的使用者透過您的 Cloud 專案存取 Cloud Vision 付費服務,因此請先評估這項驗證機制是否足以滿足您的用途,再繼續操作。
事前準備
設定專案
使用 Swift Package Manager 安裝及管理 Firebase 依附元件。
- 在 Xcode 中保持開啟應用程式專案,然後依序點選「File」>「Add Packages」。
- 在系統提示時,新增 Firebase Apple 平台 SDK 存放區:
- 選擇 Firebase ML 程式庫。
- 在目標建構設定的「Other Linker Flags」部分中新增
-ObjC
標記。 - 完成後,Xcode 會自動開始在背景解析並下載依附元件。
https://github.com/firebase/firebase-ios-sdk.git
接下來,進行一些應用程式內設定:
- 在應用程式中匯入 Firebase:
Swift
import FirebaseMLModelDownloader
Objective-C
@import FirebaseMLModelDownloader;
還差幾個步驟就可以開始使用了:
-
如果您尚未為專案啟用雲端式 API,請立即啟用:
- 開啟 Firebase 控制台的 Firebase ML API 頁面。
-
如果您尚未將專案升級至 Blaze 定價方案,按一下「升級」即可進行升級 (只有在專案未採用 Blaze 方案時,系統才會提示您升級)。
只有 Blaze 層級的專案可以使用以雲端為基礎的 API。
- 如果雲端型 API 尚未啟用,請點選「啟用雲端式 API」。
- 設定現有的 Firebase API 金鑰以禁止存取 Cloud Vision API:
部署可呼叫函式
接下來,請部署要用來橋接應用程式和 Cloud Vision API 的 Cloud 函式。functions-samples
存放區包含可使用的範例。
根據預設,透過此函式存取 Cloud Vision API,只會允許經過驗證的應用程式使用者存取 Cloud Vision API。您可以依據不同的需求修改函式。
如何部署函式:
- 複製或下載 functions-samples 存放區,並變更為
Node-1st-gen/vision-annotate-image
目錄:git clone https://github.com/firebase/functions-samples
cd Node-1st-gen/vision-annotate-image
- 安裝依附元件:
cd functions
npm install
cd ..
- 如果沒有 Firebase CLI,請安裝。
- 初始化
vision-annotate-image
目錄中的 Firebase 專案。系統出現提示時,請在清單中選取您的專案。firebase init
- 部署函式:
firebase deploy --only functions:annotateImage
將 Firebase 驗證新增至應用程式
上方部署的可呼叫函式會拒絕應用程式中未經驗證使用者的任何要求。如果您尚未這麼做,您必須將 Firebase 驗證新增至應用程式。
為應用程式新增必要的依附元件
使用 Swift Package Manager 安裝 Cloud Functions for Firebase 程式庫。
您現在可以開始為圖片加上標籤。
1. 準備輸入圖片
為了呼叫 Cloud Vision,圖片必須採用 Base64 編碼字串格式。如何處理UIImage
: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. 叫用可呼叫的函式,為圖片加上標籤
如要為圖片中的物件加上標籤,請叫用傳遞 JSON Cloud Vision 要求的可呼叫函式。首先,請初始化 Cloud Functions 的執行個體:
Swift
lazy var functions = Functions.functions()
Objective-C
@property(strong, nonatomic) FIRFunctions *functions;
建立要求,並將 Type 設為
LABEL_DETECTION
:Swift
let requestData = [ "image": ["content": base64encodedImage], "features": ["maxResults": 5, "type": "LABEL_DETECTION"] ]
Objective-C
NSDictionary *requestData = @{ @"image": @{@"content": base64encodedImage}, @"features": @{@"maxResults": @5, @"type": @"LABEL_DETECTION"} };
最後,叫用函式:
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. 取得加上標籤的物件相關資訊
如果圖片標籤作業成功,工作結果中會傳回 BatchAnnotateImagesResponse 的 JSON 回應。labelAnnotations
陣列中的每個物件都代表圖片中加上標籤的內容。您可以取得每個標籤的文字說明、知識圖譜實體 ID (如有),以及比對的可信度分數。例如:
Swift
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"]
}
}
Objective-C
NSArray *labelArray = result.data[@"labelAnnotations"];
for (NSDictionary *labelObj in labelArray) {
NSString *text = labelObj[@"description"];
NSString *entityId = labelObj[@"mid"];
NSNumber *confidence = labelObj[@"score"];
}