В цикле статей наши коллеги из Techmas поделятся опытом работы с HealthKit и созданием приложений для фитнеса. Первая статья является вводной по технологии и рассматривает приложение, которое выбирает персональные данные из Health.

Платформа HealthKit была опубликована компанией Apple в iOS 8. Она представляет собой API для сторонних приложений, который позволяет использовать собирать информацию о состояние здоровья пользователя. HealthKit включает в себя предустановленное по умолчанию на iOS8 и iOS9 приложение Health, которое отображает все имеющиеся данные: физическая нагрузка, питание, давление, калории, время сна и прочие персональные характеристики.

Сразу после запуска платформы разработчики столкнулись с рядом проблем, которые привели к временному запрету на ее интеграцию. Сейчас все исправлено и отлажено, а приложений в AppStore с использованием HealthKit становится все больше.



Общие сведения


Итак, HealthKit является агрегатом с интерфейсом для доступа ко всей информации:
Преимущества его использования для разработчиков приложений:
  • HealthKit служит общим хранилищем данных для набора приложений. Например, для подсчета количества шагов пользователи могут использовать как разные приложения, так и разные устройства. При установке каждого нового приложения история будет сохраняться.
  • Разные приложения могут обмениваться данными друг с другом без использования дополнительных интеграционных решений. Вся информация доступна в приложение Health.
  • HealthKit дает возможность для настройки отдельных прав каждому приложению по определенным показателям.
  • Расширения функционала приложений за счет использования дополнительных данных о здоровье от сторонних приложений.

Отметим, что HealthKit и приложение Health пока недоступны для iPad.

Немного теории


Сам HealthKit представляет собой иерархию неизменяемых классов, наследуемых от абстрактного класса HKObject.

Каждый объект имеет свойства:
  • UUID. Уникальный идентификатор записи.
  • Source. Источник данных (может быть как устройство, так и приложение).
  • Metadata. Дополнительные данные о записи. Предоставляет собой словарь, содержащий как предопределенные, так и пользовательские ключи.

Объекты в HealthKit могут быть двух типов: характеристики (characteristics) и выборки (samples). Характеристики представляют собой данные, которые не изменяются со временем: пол, дата рождения, группа крови. Сторонние приложения не могут изменять эти данные. Выборки же доступны для добавления новых данных. Это объекты классов, наследуемых от HKSample. Они имеют следующие свойства:
  • Type. Тип выборки: количество шагов, время сна, пр.
  • Start time. Начало времени выборки.
  • End time. Конец времени расчета выборки. Если выборка в моменте, то значение совпадает с началом времени.

Пример приложения


Ниже мы рассмотрим создание приложения, которое запрашивает использование HealthKit и выводит данные по характеристикам пользователя.

Права на использование HealthKit


Использовать HealthKit могут только те приложения, для которых использование HealthKit APIs является основным функционалом. Например, приложение для органайзера и ведения записей не будет отображать данные о состояние здоровья. Кроме этого, есть и ряд других ограничений:
  • Данные о здоровье не могут быть использованы в рекламных целях. При этом сами приложения с HealthKit могут использовать рекламные блоки и зарабатывать на объявлениях.
  • Приложение может делиться информацией из HealthKit только с разрешения пользователя и только с тем приложением, которое также авторизовано и использует HealthKit.


Весь список ограничений доступен на сайте Apple.

Теперь добавим HealthKit в тестовое приложение. Для этого, во-первых, установим расширение для HealthKit в настройках проекта.
Важно, что App ID должен сдержать строку HealthKit, иначе опция будет недоступна.

Далее добавим разрешение пользователя на использование данных о состояние здоровья.

Импортируем расширение для использования HealthKit:
import HealthKit

Теперь необходимо определить объект класса HKHealthStore, который является одним из основных в HealthKit. HealthKitStore позволяет получить права на доступ к данным HealthKit, возможность считывать характеристики и записывать новые выборки:
let healthKitStore: HKHealthStore = HKHealthStore()

Как мы отмечали ранее, пользователь выбирает только отдельные характеристики, к которым приложение имеет доступ. Все типы являются потомками HKObjectType.

Создадим функцию
 authorizeHealthKit(completion: ((success:Bool, error:NSError!) -> Void)!)


В ней определим данные для чтения и записи.

Данные для чтения (характеристики):

let healthKitTypesToRead = Set(arrayLiteral:
    HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierDateOfBirth)!,
    HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierBiologicalSex)!
)

Данные для чтения и записи (выборки):

let healthKitTypesToWrite = Set(arrayLiteral:
    HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierActiveEnergyBurned)!,
    HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceWalkingRunning)!
)

Кроме этого, добавим проверку на использование HKHealthStore на устройстве (на данный момент HealthKit недоступен на iPad):

if !HKHealthStore.isHealthDataAvailable()
{
    let error = NSError(domain: "ru.techmas.techmasHealthKit", code: 2, userInfo: [NSLocalizedDescriptionKey:"HealthKit is not available in this Device"])
    if( completion != nil )
    {
        completion(success:false, error:error)
    }
    return;
}

Наконец, запросим авторизацию передав в параметрах два набора с типами Set<HKSampleType> и Set<HKObjectType> для чтения и записи соответственно:

healthKitStore.requestAuthorizationToShareTypes(healthKitTypesToWrite, readTypes: healthKitTypesToRead) {
    (success, error) -> Void in
    if( completion != nil )
    {
        completion(success:success,error:error)
    }
}

Добавим вызов функции в viewDidLoad():

authorizeHealthKit { (authorized,  error) -> Void in
if authorized {
    print("HealthKit authorization received.")
}
else
{
    print("HealthKit authorization denied!")
    if error != nil {
        print("\(error)")
    }
}

При запуске приложения будет доступно окно:

Чтение характеристик


Следующим шагом получим характеристики. Добавим пол и возраст в приложение Health:

Создадим функцию readProfile(). Ее код приведен ниже:

func readProfile() -> (age:NSDate?, bioSex:HKBiologicalSexObject?)
{
    // Reading Characteristics
    var bioSex : HKBiologicalSexObject?
    var dateOfBirth : NSDate?
    
    do {
        dateOfBirth = try healthKitStore.dateOfBirth()
        bioSex = try healthKitStore.biologicalSex()
    }
    catch {
        print(error)
    }
    return (dateOfBirth, bioSex)
}

Для доступа к характеристикам мы воспользовались созданным объектом healthKitStore.
Возможные идентификаторы и их типы для получения характеристик доступы в документации по ссылке.

Теперь используя следующее обращение мы получаем набор характеристик пользователя:
let profile = readProfile()

Код примера доступен в git.

В следующих статьях мы отдельно опишем способы получения выборок и добавления данных по тренировкам.

Комментарии (2)


  1. sojik
    18.11.2015 13:39

    Наверное, просто забыли унести бОльшую часть статьи под cut? :)


    1. barsuga
      18.11.2015 13:40
      +1

      уже ;)