הוספת תוויות לתמונות באופן מאובטח באמצעות Cloud Vision באמצעות Firebase Auth ו-Functions בפלטפורמות של Apple

כדי לקרוא ל-Google Cloud API מהאפליקציה, צריך ליצור API ל-REST ביניים שמטפל באימות ומגן על ערכים סודיים כמו מפתחות API. לאחר מכן צריך לכתוב קוד באפליקציה לנייד כדי לבצע אימות של השירות המתווך הזה ולתקשר איתו.

אחת הדרכים ליצור את ממשק ה-API ל-REST היא באמצעות Firebase Authentication and Functions, שמספק שער מנוהל ללא שרת לממשקי Google Cloud API שמטפל באימות, ואפשר לקרוא אליו מהאפליקציה לנייד באמצעות ערכות SDK מוכנות מראש.

במדריך הזה נסביר איך להשתמש בשיטה הזו כדי לבצע קריאה ל-Cloud Vision API מהאפליקציה. השיטה הזו תאפשר לכל המשתמשים המאומתים לגשת לשירותים של Cloud Vision שמוגדרים לחיוב דרך הפרויקט שלכם ב-Cloud. לכן, לפני שממשיכים, כדאי לבדוק אם מנגנון האימות הזה מספיק לתרחיש לדוגמה שלכם.

לפני שמתחילים

הגדרת הפרויקט

אם עדיין לא הוספתם את Firebase לאפליקציה, תוכלו לפעול לפי השלבים שמפורטים במדריך לתחילת העבודה.

שימוש ב-Swift Package Manager כדי להתקין ולנהל יחסי תלות ב-Firebase.

  1. ב-Xcode, כשפרויקט האפליקציה פתוח, עוברים אל קובץ > הוספת חבילות.
  2. כשמופיעה בקשה, מוסיפים את המאגר של Firebase SDK לפלטפורמות של Apple:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. בוחרים את הספרייה Firebase ML.
  5. מוסיפים את הדגל -ObjC לקטע Other Linker Flags (דגלים אחרים של קישור) בהגדרות ה-build של היעד.
  6. בסיום, Xcode יתחיל לפתור את יחסי התלות ולהוריד אותם באופן אוטומטי ברקע.

בשלב הבא מבצעים כמה הגדרות באפליקציה:

  1. באפליקציה, מייבאים את Firebase:

    Swift

    import FirebaseMLModelDownloader

    Objective-C

    @import FirebaseMLModelDownloader;

עוד כמה שלבים בהגדרה, ואנחנו מוכנים:

  1. אם עדיין לא הפעלתם ממשקי API מבוססי-Cloud בפרויקט, עליכם לעשות זאת עכשיו:

    1. פותחים את דף ממשקי ה-API של Firebase ML במסוף Firebase.
    2. אם עדיין לא שדרגתם את הפרויקט לתוכנית התמחור Blaze, לוחצים על שדרוג. (הבקשה לשדרוג תוצג רק אם הפרויקט לא בתוכנית Blaze).

      רק בפרויקטים ברמת Blaze אפשר להשתמש בממשקי API מבוססי-Cloud.

    3. אם ממשקי ה-API מבוססי-הענן עדיין לא מופעלים, לוחצים על Enable Cloud-based APIs.
  2. מגדירים את מפתחות ה-API הקיימים של Firebase כך שלא יאפשרו גישה ל-Cloud Vision API:
    1. פותחים את הדף Credentials במסוף Cloud.
    2. לכל מפתח API ברשימה, פותחים את תצוגת העריכה ובקטע Key Restrictions מוסיפים לרשימת כל ממשקי ה-API הזמינים למעט Cloud Vision API.

פריסת הפונקציה שניתן להפעיל

בשלב הבא, פורסים את Cloud Function שתשמש כגשר בין האפליקציה ל-Cloud Vision API. המאגר functions-samples מכיל דוגמה שאפשר להשתמש בה.

כברירת מחדל, הגישה ל-Cloud Vision API דרך הפונקציה הזו תאפשר רק למשתמשים מאומתים באפליקציה שלכם לגשת ל-Cloud Vision API. אפשר לשנות את הפונקציה בהתאם לדרישות שונות.

כדי לפרוס את הפונקציה:

  1. משכפלים או מורידים את מאגר functions-samples ומעבירים את הנתיב לספרייה Node-1st-gen/vision-annotate-image:
    git clone https://github.com/firebase/functions-samples
    cd Node-1st-gen/vision-annotate-image
    
  2. יחסי תלות של התקנות:
    cd functions
    npm install
    cd ..
  3. אם ה-CLI של Firebase לא מותקן, מתקינים אותו.
  4. מפעילים את הפרויקט ב-Firebase בספרייה vision-annotate-image. כשמוצגת בקשה, בוחרים את הפרויקט ברשימה.
    firebase init
  5. פורסים את הפונקציה:
    firebase deploy --only functions:annotateImage

הוספת Firebase Auth לאפליקציה

הפונקציה הניתנת לקריאה שפרסמתם למעלה תדחה כל בקשה ממשתמשים לא מאומתים באפליקציה. אם עדיין לא עשיתם זאת, תצטרכו להוסיף את Firebase Auth לאפליקציה.

הוספת יחסי התלות הנדרשים לאפליקציה

משתמשים ב-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.

  1. קודם צריך לאתחל מכונה של Cloud Functions:

    Swift

    lazy var functions = Functions.functions()
    

    Objective-C

    @property(strong, nonatomic) FIRFunctions *functions;
    
  2. יוצרים בקשה עם 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"}
    };
    
  3. לבסוף, מפעילים את הפונקציה:

    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. אחזור מידע על אובייקטים מתויגים

אם פעולת התיוג של התמונות תצליח, תתקבל תגובה בפורמט JSON מסוג BatchAnnotateImagesResponse בתוצאה של המשימה. כל אובייקט במערך labelAnnotations מייצג משהו שסומן בתמונה. לכל תווית אפשר לקבל את תיאור הטקסט שלה, את מזהה הישות ב-Knowledge Graph (אם הוא זמין) ואת דירוג האמון בהתאמה. לדוגמה:

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"];
}