Crie um aplicativo HealthKit usando SwiftUI

Nov 29 2022
Obter dados de contagem de passos do HealthKit Durante meu último projeto, criei um aplicativo de dieta que requer a contagem de passos dos usuários do aplicativo Health em seus iPhones. Então, usei a estrutura HealthKit da Apple para fazer o trabalho.

Obtenha dados de contagem de passos do HealthKit

Foto de Bruno Nascimento no Unsplash

Durante meu último projeto, criei um aplicativo de dieta que requer a contagem de passos dos usuários do aplicativo Saúde em seus iPhones. Então, usei a HealthKitestrutura da Apple para fazer o trabalho.

Deseja saber como obter os dados de contagem de passos dos usuários do Health usando o HealthKit? Bem, vamos entrar nisso!

Vários passos precisam ser feitos para obter a contagem de passos, ou seja:

  • Ativando os recursos do HealthKit em nosso projeto
  • Solicitando permissão do aplicativo Saúde dos usuários
  • Buscar os dados de contagem de passos
  • Verifique o status da autorização de saúde
  • Criando e atualizando a IU

1. Ativando os recursos do HealthKit em nosso projeto

Para habilitar os recursos do HealthKit em nosso aplicativo, abra seu projeto, acesse Assinatura e recursos, clique no botão de adição no canto superior direito e escolha HealthKit.

Você pode verificar os registros clínicos de saúde se precisar acessar os registros clínicos dos usuários e a entrega em segundo plano para permitir a observação de alterações de dados em tempo real.

Não vou colocar pontos aqui, porque a contagem de passos não é um registro médico e não preciso dos dados de contagem de passos em tempo real.

Adicionando recursos do HealthKit ao projeto

Depois disso, vá para a guia Informações e precisamos adicionar uma chave para usar o HealthKit. A chave que precisamos é NSHealthShareUsageDescriptione NSHealthUpdateUsageDescription.

Adicionar chaves do HealthKit na guia Informações

2. Solicitação de permissão do aplicativo de saúde dos usuários

Antes de obtermos a contagem de passos, precisamos obter a permissão dos usuários para acessar o aplicativo Health.

Para fazer isso, criei um novo arquivo chamado HealthKitManager, com uma HealthKitManagerclasse dentro dele.

Não se esqueça de import HealthKitno topo e crie uma função chamada setupHealthRequest.

func setUpHealthRequest(healthStore: HKHealthStore, readSteps: @escaping () -> Void) {
    if HKHealthStore.isHealthDataAvailable(), let stepCount = HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount) {
        healthStore.requestAuthorization(toShare: [stepCount], read: [stepCount]) { success, error in
            if success {
                readSteps()
            } else if error != nil {
                // handle your error here
            }
        }
    }
    
}

  • A primeira linha HKHealthStore.isHealthDataAvailable()verifica se o Health está disponível no dispositivo.
  • Em seguida, especifique os dados que queremos obter - ou seja, a contagem de passos usando HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)e desempacote-a usando if let.
  • Depois de especificar os dados, chamamos a função requestAuthorization(). Isso acionará o pop-up de permissão do aplicativo Health, que solicitará que você dê permissão. Também especificamos a contagem de etapas como os dados a serem gravados e lidos. Posteriormente, se o usuário der sua permissão, faremos a leitura da contagem de passos, caso contrário, trataremos o erro.

Agora que criamos o setupHealthRequest()método, vamos configurá-lo para obter a contagem de passos dos usuários — readStepCount():

func readStepCount(forToday: Date, healthStore: HKHealthStore, completion: @escaping (Double) -> Void) {
    guard let stepQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount) else { return }
    let now = Date()
    let startOfDay = Calendar.current.startOfDay(for: now)
    
    let predicate = HKQuery.predicateForSamples(withStart: startOfDay, end: now, options: .strictStartDate)
    
    let query = HKStatisticsQuery(quantityType: stepQuantityType, quantitySamplePredicate: predicate, options: .cumulativeSum) { _, result, error in
        
        guard let result = result, let sum = result.sumQuantity() else {
            completion(0.0)
            return
        }
        
        completion(sum.doubleValue(for: HKUnit.count()))
    
    }
    
    healthStore.execute(query)
    
}

  • A segunda coisa é preparar uma data como predicado para ler os dados de contagem de passos de hoje. Depois de especificar a data, adiciono um predicado com a opção , o .strictStartDateque significa que os dados lidos devem estar dentro do intervalo de tempo especificado para que eu obtenha os dados exatos da contagem de passos de hoje.
  • A próxima coisa é uma consulta, eu uso opções .cumulativeSumpara calcular a soma de todos os passos registrados em um dia, porque se você abrir o Health e entrar em passos, poderá ver que os passos são registrados por hora, então precisamos somar todos dele para obter a contagem total de passos.
  • Depois de desempacotar o valor do resultado, retorno a conclusão com a soma da contagem de etapas convertida em um valor duplo.
  • Por fim, execute a consulta usando healthStore.execute(query).

private var healthStore = HKHealthStore()
private var healthKitManager = HealthKitManager()
@Published var userStepCount = ""
@Published var isAuthorized = false

  • healthKitManageré a instância da HealthKitManagerclasse que possui o método de autorização e busca de dados
  • userStepCounté uma variável para a contagem de passos que buscamos
  • isAuthorizedpara verificar se o usuário deu acesso ao Health ou não, marquei ambos userStepCounte isAuthorizedcomo Published.

func healthRequest() {
    healthKitManager.setUpHealthRequest(healthStore: healthStore) {
        self.changeAuthorizationStatus()
        self.readStepsTakenToday()
    }
}

Segue o código do readStepsTakenToday()método:

func readStepsTakenToday() {
    healthKitManager.readStepCount(forToday: Date(), healthStore: healthStore) { step in
        if step != 0.0 {
            DispatchQueue.main.async {
                self.userStepCount = String(format: "%.0f", step)
            }
        }
    }
}

Usamos DispatchQueue.main.asyncporque a função delimitadora é executada em um thread em segundo plano e precisamos atualizar o valor do thread principal.

4. Verifique o status da autorização de saúde

Em seguida, precisamos verificar o status de autorização para atualizar a IU. Para isso, criei um método chamado changeAuthorizationStatus().

func changeAuthorizationStatus() {
    guard let stepQtyType = HKObjectType.quantityType(forIdentifier: .stepCount) else { return }
    let status = self.healthStore.authorizationStatus(for: stepQtyType)
    
    switch status {
    case .notDetermined:
        isAuthorized = false
    case .sharingDenied:
        isAuthorized = false
    case .sharingAuthorized:
        isAuthorized = true
    @unknown default:
        isAuthorized = false
    }
}

Observação: precisamos especificar a contagem de etapas como uma variável no setupHealthRequest() método, porque defini-la como tipo somente leitura ( let) retorna um .sharingDeniedstatus. Encontrei isso no StackOverflow e você pode ler mais sobre isso aqui .

5. Criando a IU

Todos os nossos métodos estão definidos! Então, vamos criar a IU agora.

É uma interface simples. Se o usuário não autorizou, exibiremos um Textque diz "Por favor, autorize a saúde!" e a Buttonpara acionar o método de autorização. Caso contrário, ele exibirá a contagem de passos na tela.

import SwiftUI

struct ContentView: View {
    @EnvironmentObject var vm: HealthKitViewModel
    
    var body: some View {
        VStack {
            if vm.isAuthorized {
                VStack {
                    Text("Today's Step Count")
                        .font(.title3)
                    
                    Text("\(vm.userStepCount)")
                        .font(.largeTitle)
                        .fontWeight(.bold)
                }
            } else {
                VStack {
                    Text("Please Authorize Health!")
                        .font(.title3)
                    
                    Button {
                        vm.healthRequest()
                    } label: {
                        Text("Authorize HealthKit")
                            .font(.headline)
                            .foregroundColor(.white)
                    }
                    .frame(width: 320, height: 55)
                    .background(Color(.orange))
                    .cornerRadius(10)
                }
            }
            
        }
        .padding()
        .onAppear {
            vm.readStepsTakenToday()
        }
    }
}

Agora vamos executá-lo no simulador.

Demonstração de aplicativo para buscar dados

Buscamos com sucesso os dados de contagem de passos e os exibimos. Mas observe que quando eu saio do aplicativo e o abro novamente, preciso tocar no botão autorizar para que a visualização atualize a contagem de buscas.

Para corrigir isso, invocaremos o changeAuthorizationStatus() método no método ViewModel's init.

init() {
    changeAuthorizationStatus()
}

Demonstração do aplicativo após corrigir o bug

E é isso! Concluímos com sucesso todas as 5 etapas a serem executadas.

Para o projeto concluído, você pode verificar meu repositório GitHub aqui .

E para ler mais sobre o que você pode fazer com o HealthKit, leia a documentação aqui .

Você pode fazer muito mais com o HealthKit, desde obter o sexo dos usuários até obter análises do sono e até exercícios.

Obrigado e espero que este artigo ajude!