จดจำจุดสังเกตได้อย่างปลอดภัยด้วย Cloud Vision โดยใช้การตรวจสอบสิทธิ์และฟังก์ชัน Firebase บนแพลตฟอร์ม Apple

หากต้องการเรียกใช้ Google Cloud API จากแอป คุณต้องสร้าง REST API ระดับกลาง ที่จัดการการให้สิทธิ์และปกป้องค่าลับ เช่น คีย์ API จากนั้นคุณต้อง เขียนโค้ดในแอปบนอุปกรณ์เคลื่อนที่เพื่อตรวจสอบสิทธิ์และสื่อสารกับบริการระดับกลางนี้

วิธีหนึ่งในการสร้าง REST API นี้คือการใช้ Firebase Authentication และ Functions ซึ่งจะมอบเกตเวย์แบบไม่มีเซิร์ฟเวอร์ที่จัดการให้คุณเพื่อเข้าถึง Google Cloud API ที่จัดการการตรวจสอบสิทธิ์และเรียกใช้จากแอปบนอุปกรณ์เคลื่อนที่ได้ด้วย SDK ที่สร้างไว้ล่วงหน้า

คู่มือนี้แสดงวิธีใช้เทคนิคนี้เพื่อเรียกใช้ Cloud Vision API จากแอป วิธีนี้จะช่วยให้ผู้ใช้ที่ผ่านการตรวจสอบสิทธิ์ทุกคนเข้าถึงบริการ Cloud Vision ที่มีการเรียกเก็บเงินผ่านโปรเจ็กต์ที่อยู่ในระบบคลาวด์ของคุณได้ ดังนั้น โปรดพิจารณาว่ากลไกการตรวจสอบสิทธิ์นี้เพียงพอสำหรับ Use Case ของคุณหรือไม่ก่อนดำเนินการต่อ

ก่อนเริ่มต้น

กำหนดค่าโปรเจ็กต์

หากยังไม่ได้เพิ่ม Firebase ลงในแอป ให้ทำตาม ขั้นตอนในคู่มือเริ่มต้นใช้งาน

ใช้ Swift Package Manager เพื่อติดตั้งและจัดการทรัพยากร Dependency ของ Firebase

  1. เปิดโปรเจ็กต์แอปใน Xcode แล้วไปที่ File > Add Packages
  2. เมื่อได้รับข้อความแจ้ง ให้เพิ่มที่เก็บ Firebase Apple Platforms SDK ดังนี้
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. เลือกไลบรารี Firebase ML
  5. เพิ่มแฟล็ก -ObjC ลงในส่วน Other Linker Flags ของการตั้งค่าบิลด์ของเป้าหมาย
  6. เมื่อเสร็จแล้ว Xcode จะเริ่มจับคู่ข้อมูลและดาวน์โหลด ทรัพยากร Dependency ในเบื้องหลังโดยอัตโนมัติ

จากนั้นทำการตั้งค่าบางอย่างในแอป ดังนี้

  1. นำเข้า Firebase ในแอปโดยใช้คำสั่งต่อไปนี้

    Swift

    import FirebaseMLModelDownloader

    Objective-C

    @import FirebaseMLModelDownloader;

ทำตามขั้นตอนการกำหนดค่าอีก 2-3 ขั้นตอน แล้วคุณก็จะพร้อมใช้งาน

  1. หากยังไม่ได้เปิดใช้ Cloud-based API สำหรับโปรเจ็กต์ ให้ทำดังนี้

    1. เปิดหน้า Firebase ML APIs ในคอนโซล Firebase
    2. หากยังไม่ได้อัปเกรดโปรเจ็กต์เป็น แพ็กเกจราคา Blaze แบบจ่ายเมื่อใช้ ให้คลิก อัปเกรด เพื่อดำเนินการ (ระบบจะ แจ้งให้คุณอัปเกรดก็ต่อเมื่อโปรเจ็กต์ไม่ได้ใช้ แพ็กเกจราคา Blaze)

      เฉพาะโปรเจ็กต์ที่ใช้แพ็กเกจราคา Blaze เท่านั้นที่ใช้ Cloud-based API ได้

    3. หากยังไม่ได้เปิดใช้ Cloud-based API ให้คลิก เปิดใช้ Cloud-based API
  2. กำหนดค่าคีย์ Firebase API ที่มีอยู่เพื่อไม่อนุญาตการเข้าถึง Cloud Vision API:
    1. เปิดหน้า ข้อมูลเข้าสู่ระบบ ของ Cloud Console
    2. สำหรับคีย์ API แต่ละรายการในรายการ ให้เปิดมุมมองการแก้ไข แล้วในส่วนข้อจำกัดคีย์ ให้เพิ่ม 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. ติดตั้งทรัพยากร Dependency โดยใช้คำสั่งต่อไปนี้
    cd functions
    npm install
    cd ..
  3. หากยังไม่มี Firebase CLI ให้ติดตั้ง
  4. เริ่มต้นโปรเจ็กต์ Firebase ใน vision-annotate-image ไดเรกทอรี เมื่อได้รับข้อความแจ้ง ให้เลือกโปรเจ็กต์ในรายการ
    firebase init
  5. ทำให้ฟังก์ชันใช้งานได้โดยใช้คำสั่งต่อไปนี้
    firebase deploy --only functions:annotateImage

เพิ่ม Firebase Auth ลงในแอป

ฟังก์ชันที่เรียกใช้ได้ซึ่งทำให้ใช้งานได้ข้างต้นจะปฏิเสธคำขอจากผู้ใช้แอปที่ไม่ได้ผ่านการตรวจสอบสิทธิ์ คุณจะต้องเพิ่ม Firebase Auth ลงในแอปหากยังไม่ได้ดำเนินการ

เพิ่มทรัพยากร Dependency ที่จำเป็นลงในแอป

ใช้ Swift Package Manager เพื่อติดตั้งไลบรารี Cloud Functions for Firebase

1. เตรียมรูปภาพอินพุต

หากต้องการเรียกใช้ Cloud Vision รูปภาพต้องจัดรูปแบบเป็นสตริงที่มีการเข้ารหัสฐาน 64 วิธีประมวลผล 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. เรียกใช้ฟังก์ชันที่เรียกใช้ได้เพื่อจดจำสถานที่สำคัญ

หากต้องการจดจำสถานที่สำคัญในรูปภาพ ให้เรียกใช้ฟังก์ชันที่เรียกใช้ได้โดยส่งคำขอ Cloud Vision ในรูปแบบ JSON

  1. ขั้นแรก ให้เริ่มต้นอินสแตนซ์ของ Cloud Functions โดยใช้คำสั่งต่อไปนี้

    Swift

    lazy var functions = Functions.functions()
    

    Objective-C

    @property(strong, nonatomic) FIRFunctions *functions;
    
  2. สร้างคำขอโดยตั้งค่า ประเภท เป็น LANDMARK_DETECTION

    Swift

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

    Objective-C

    NSDictionary *requestData = @{
      @"image": @{@"content": base64encodedImage},
      @"features": @{@"maxResults": @5, @"type": @"LANDMARK_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 ในผลลัพธ์ของงาน ออบเจ็กต์แต่ละรายการในอาร์เรย์ landmarkAnnotations จะแสดงสถานที่สำคัญที่จดจำได้ในรูปภาพ สำหรับสถานที่สำคัญแต่ละแห่ง คุณจะดูพิกัดขอบเขตในรูปภาพอินพุต ชื่อของสถานที่สำคัญ ละติจูดและลองจิจูด รหัสเอนทิตี กราฟความรู้ (หากมี) และคะแนนความเชื่อมั่นของการจับคู่ได้ ตัวอย่างเช่น

Swift

if let labelArray = (result?.data as? [String: Any])?["landmarkAnnotations"] as? [[String:Any]] {
  for labelObj in labelArray {
    let landmarkName = labelObj["description"]
    let entityId = labelObj["mid"]
    let score = labelObj["score"]
    let bounds = labelObj["boundingPoly"]
    // Multiple locations are possible, e.g., the location of the depicted
    // landmark and the location the picture was taken.
    guard let locations = labelObj["locations"] as? [[String: [String: Any]]] else { continue }
    for location in locations {
      let latitude = location["latLng"]?["latitude"]
      let longitude = location["latLng"]?["longitude"]
    }
  }
}

Objective-C

NSArray *labelArray = result.data[@"landmarkAnnotations"];
for (NSDictionary *labelObj in labelArray) {
  NSString *landmarkName = labelObj[@"description"];
  NSString *entityId = labelObj[@"mid"];
  NSNumber *score = labelObj[@"score"];
  NSArray *bounds = labelObj[@"boundingPoly"];
  // Multiple locations are possible, e.g., the location of the depicted
  // landmark and the location the picture was taken.
  NSArray *locations = labelObj[@"locations"];
  for (NSDictionary *location in locations) {
    NSNumber *latitude = location[@"latLng"][@"latitude"];
    NSNumber *longitude = location[@"latLng"][@"longitude"];
  }
}