O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Reconheça pontos de referência com segurança com o Cloud Vision usando o Firebase Auth e o Functions no iOS

Para chamar uma API do Google Cloud usando seu app, crie uma API REST intermediária que gerencie a autorização e proteja valores secretos, como chaves de API. Em seguida, escreva o código no seu app para dispositivos móveis a fim de autenticar e se comunicar com esse serviço intermediário.

Uma maneira de criar essa API REST é usar o Firebase Authentication e o Functions, que oferecem um gateway gerenciado sem servidor para as APIs do Google Cloud. Ele lida com a autenticação e pode ser chamado no seu app para dispositivos móveis com SDKs pré-criados.

Neste guia, você verá como usar essa técnica para chamar a API Cloud Vision do seu app. Esse método permitirá que todos os usuários autenticados acessem os serviços faturados do Cloud Vision no projeto do Cloud. Sendo assim, considere se esse mecanismo de autenticação é suficiente para seu caso de uso antes de continuar.

Antes de começar

Configurar seu projeto

  1. Se você ainda não adicionou o Firebase ao seu app, siga as etapas no guia de primeiros passos.
  2. Inclua o Firebase no seu Podfile: Após instalar ou atualizar os pods do seu projeto, abra o projeto do Xcode usando o .xcworkspace dele.
  3. Importe o Firebase para seu app:

    Swift

    import Firebase

    Objective-C

    @import Firebase;
  4. Se você ainda não ativou APIs baseadas em nuvem para seu projeto, siga estas etapas:

    1. Abra a página de APIs do Firebase ML no Console do Firebase.
    2. Se você ainda não fez o upgrade de seu projeto ao plano de preços do Blaze, clique em Fazer upgrade para fazer isso. Você só receberá uma mensagem para fazer upgrade se o projeto não estiver no plano Blaze.

      Apenas projetos no nível Blaze podem usar APIs baseadas na nuvem.

    3. Caso as APIs baseadas na nuvem ainda não estejam ativadas, clique em Ativar APIs baseadas na nuvem.
  5. Configure as chaves de API do Firebase para proibir o acesso à API Cloud Vision:
    1. Abra a página Credenciais do Console do Cloud.
    2. Para cada chave de API na lista, abra a visualização de edição e, na seção "Restrições de chave", adicione à lista todas as APIs disponíveis, exceto a API Cloud Vision.

Como implantar a função chamável

Agora, você implantará a função do Cloud que será usada para conectar seu app e a API Cloud Vision. O repositório functions-samples contém um exemplo que pode ser usado.

Por padrão, essa função permitirá que apenas usuários autenticados do seu app acessem a API Cloud Vision. É possível modificar a função para requisitos diferentes.

Para implantar a função, siga estas etapas:

  1. Clone ou faça o download do repositório functions-samples e mude para o diretório vision-annotate-image:
    git clone https://github.com/firebase/functions-samples
    cd vision-annotate-image
    
  2. Instale as dependências:
    cd functions
    npm install
    cd ..
    
  3. Se você não tiver a CLI do Firebase, faça a instalação.
  4. Inicialize um novo projeto do Firebase no diretório vision-annotate-image. Quando solicitado, selecione o projeto na lista.
    firebase init
  5. Implante a função:
    firebase deploy --only functions:annotateImage

Adicionar o Firebase Auth ao seu app

A função chamável implementada acima rejeitará qualquer solicitação de usuários não autenticados do seu app. Adicione o Firebase Authentication ao app, caso ainda não tenha feito isso.

Adicionar as dependências necessárias ao app

  1. Adicione as dependências da biblioteca do Firebase Functions ao seu Podfile:
    pod 'Firebase/Functions'
  2. Instale as dependências:
    pod install

1. Preparar a imagem de entrada

Para chamar o Cloud Vision, a imagem precisa ser formatada como uma string codificada em base64. Para processar um UIImage:

Swift

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

Objective-C

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

2. Invocar a função chamável para reconhecer pontos de referência

Para reconhecer pontos de referência em uma imagem, invoque a função chamável transmitindo uma solicitação JSON do Cloud Vision.

  1. Inicialize uma instância do Cloud Functions:

    Swift

    lazy var functions = Functions.functions()
    

    Objective-C

    @property(strong, nonatomic) FIRFunctions *functions;
    
  2. Crie uma solicitação com Type definido como 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. Por fim, invoque a função:

    Swift

    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
    }
    

    Objective-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. Ver informações sobre os pontos de referência reconhecidos

Se a operação de reconhecimento de ponto de referência for bem-sucedida, uma resposta JSON de BatchAnnotateImagesResponse será retornada no resultado da tarefa. Cada objeto na matriz landmarkAnnotations representa um ponto de referência reconhecido na imagem. Para cada ponto de referência, é possível receber as coordenadas delimitadoras na imagem de entrada, o nome do ponto de referência, a latitude e a longitude, o ID da entidade do Mapa de informações dele (se disponível) e a pontuação de confiança da correspondência. Exemplo:

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