Статьи

Начало работы с HealthKit: часть 1

Платформа HealthKit была представлена ​​в прошлом году на WWDC 2014 как единое место, где приложения могут хранить, обмениваться и читать данные, связанные со здоровьем. Новое приложение Health, которое представляет собой просмотр этих данных пользователем, было одной из флагманских функций iOS 8.

Одним из основных преимуществ HealthKit является то, что приложения для фитнеса и связанные со здоровьем приложения могут легко обмениваться данными друг с другом. В течение прошлого года многие разработчики внедрили HealthKit в свои приложения, и опытные пользователи ожидают, что любое фитнес-приложение интегрируется с HealthKit.

Есть много преимуществ, ошибок и лучших практик при работе с этой новой и интересной структурой. Недавно у меня был непосредственный опыт работы со средой HealthKit, когда я добавил поддержку HealthKit в одно из моих приложений, Routie . Если вы планируете использовать HealthKit в своем приложении, этот учебник для вас.

Я уже упоминал о некоторых преимуществах HealthKit, но если вы еще не проданы, позвольте мне сказать, что интегрировать HealthKit действительно не так сложно. Я бы даже пошел дальше и сказал, что это проще, чем большинство других новых фреймворков, которые представила Apple. Очевидно, это во многом зависит от того, чего вы хотите достичь с его помощью. Но в целом я бы сказал, что соотношение усилий, необходимых для интеграции HealthKit, и преимуществ, которые он приносит вашим пользователям, очень благоприятно.

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

Моя цель в этом уроке — научить вас основам создания примера приложения. Кроме того, я дам вам несколько полезных советов и рекомендаций о том, как вы можете или должны интегрировать HealthKit в свои собственные приложения. Прочитав эту статью, вы должны иметь базовые знания о HealthKit, готовые использовать его в своих приложениях.

В следующем списке приведен ряд основных фактов о HealthKit, о которых вам следует знать:

  • Платформа HealthKit доступна начиная с iOS 8. Обратите внимание, что она доступна только на iPhone, а не на iPad.
  • Apple серьезно относится к конфиденциальности, и поэтому вы должны явно запрашивать доступ для чтения и / или записи в HealthKit для каждого типа данных, к которым вам нужен доступ. У пользователя есть возможность разрешить доступ для некоторых типов и запретить его для других.
  • Платформа HealthKit интенсивно использует подклассы.
  • Существует два основных типа данных: характеристики и образцы . Характеристики, такие как дата рождения пользователя или группа крови, обычно не меняются. Образец представляет данные в определенный момент времени.
  • Количественные выборки являются наиболее распространенными типами данных. Они включают рост и вес пользователя, предпринятые шаги, температуру пользователя, частоту пульса и т. Д.
  • Тренировки , которые относятся к категории образцов, предназначены специально для представления пробежек, прогулок, поездок и т. Д.

Для получения дополнительной информации о платформе HealthKit посетите справочник Apple HealthKit Framework .

Я знаю, что вы, вероятно, уже готовы начать с примера проекта, но есть несколько важных вещей, о которых вы должны знать, прежде чем погрузиться.

  • Магазин HealthKit зашифрован, когда телефон пользователя заблокирован. Это означает, что вы не сможете читать с него, когда ваше приложение находится в фоновом режиме. Однако запись в HealthKit работает, даже когда телефон заблокирован.
  • Вы должны объяснить в своем описании App Store и в своем приложении, как ваше приложение будет использовать данные, полученные из HealthKit. Невыполнение этого требования может привести к отклонению вашего приложения.
  • В обзорах App Store есть новый раздел, посвященный HealthKit. Вы должны обязательно прочитать его, прежде чем решить, добавлять ли поддержку HealthKit или нет.
  • Как только ваше приложение интегрируется с HealthKit, вы должны предоставить для него политику конфиденциальности. Apple даже рекомендует некоторые документы, в которых указано, как должны выглядеть политики конфиденциальности, связанные со здравоохранением. Важно, чтобы политика конфиденциальности сообщала пользователю, как ваше приложение обрабатывает их данные.

Теперь, когда мы решили это, давайте начнем с учебника.

Мы создадим простое приложение, которое интегрируется с HealthKit и объясняет некоторые основные понятия инфраструктуры. В частности, мы будем:

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

Запустите Xcode и выберите « Файл» > « Создать» > « Проект». В разделе « iOS»> «Приложение » выберите шаблон приложения с вкладками и нажмите « Далее» .

Создание нового проекта - Выбор шаблона

Введите HealthBasics в качестве имени продукта проекта и нажмите « Далее» . Выберите, куда вы хотите сохранить проект и нажмите « Создать» .

Создание нового проекта - последний шаг

В Навигаторе проектов слева щелкните проект, выберите цель HealthBasics и откройте вкладку « Возможности » в верхней части. Прокрутите вниз до раздела HealthKit и включите HealthKit, переключая переключатель справа. За кулисами Xcode сделает все необходимое для включения HealthKit.

Включение HealthKit

Для этого проекта мы не будем использовать классы размера. Поскольку классы размеров включены по умолчанию, мы должны вручную отключить их в XCode. В навигаторе проекта слева выберите Main.storyboard . Откройте инспектор файлов справа и снимите флажок « Использовать классы размера» .

Xcode покажет вам диалоговое окно с предупреждением. Отключите его, нажав Отключить классы размеров , но сделайте так, чтобы сохранить данные классов размеров для iPhone, как показано ниже.

Xcode - отключение классов размеров

Удалите две метки в контроллере первого вида . Затем перетащите метку и переключатель из библиотеки объектов справа на первый контроллер вида. Измените текст метки на Интеграция работоспособности и отключите состояние переключателя.

Первая вкладка интерфейса - часть 1

Добавьте еще две метки и кнопку к контроллеру первого вида. Измените текст первой метки на возраст пользователя : измените текст второй метки на ?? и выровняйте их по горизонтали, как показано на скриншоте ниже. Наконец, измените заголовок кнопки на « Читать» и поместите его справа от второй метки. Первая сцена теперь должна выглядеть так:

Первая вкладка интерфейса - часть 2

Мы еще не закончили. Добавьте еще одну метку, текстовое поле и кнопку к контроллеру первого вида, выровняв их по горизонтали, как показано ниже. Измените текст метки на Вес пользователя: и измените заголовок кнопки на Запись .

Выберите только что добавленное текстовое поле и в инспекторе атрибутов измените его тип клавиатуры на « Числа и пунктуация» . Вот и все. Первая сцена теперь должна выглядеть так:

Первая вкладка интерфейса - часть 3

Мы собираемся хранить код, связанный с HealthKit, в отдельном классе, классе GSHealthKitManager . Давайте создадим этот класс сейчас.

В Навигаторе проектов щелкните правой кнопкой мыши группу HealthBasics и выберите « Новый файл …» . Убедитесь, что Cocoa Touch Class выбран из списка шаблонов, и нажмите « Далее» . Назовите класс GSHealthKitManager и нажмите « Далее» .

Создание класса GSHealthKitManager

Откройте файл GSHealthKitManager класса GSHealthKitManager и замените содержимое файла следующим кодом. Позже мы будем вызывать эти методы из класса FirstViewController .

01
02
03
04
05
06
07
08
09
10
11
12
#import <UIKit/UIKit.h>
 
@interface GSHealthKitManager : NSObject
 
+ (GSHealthKitManager *)sharedManager;
 
— (void)requestAuthorization;
 
— (NSDate *)readBirthDate;
— (void)writeWeightSample:(CGFloat)weight;
 
@end

Затем GSHealthKitManager файл GSHealthKitManager класса GSHealthKitManager и замените его содержимое следующим:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#import «GSHealthKitManager.h»
#import <HealthKit/HealthKit.h>
 
 
@interface GSHealthKitManager ()
 
@property (nonatomic, retain) HKHealthStore *healthStore;
 
@end
 
 
@implementation GSHealthKitManager
 
+ (GSHealthKitManager *)sharedManager {
    static dispatch_once_t pred = 0;
    static GSHealthKitManager *instance = nil;
    dispatch_once(&pred, ^{
        instance = [[GSHealthKitManager alloc] init];
        instance.healthStore = [[HKHealthStore alloc] init];
    });
    return instance;
}
 
— (void)requestAuthorization {
     
    if ([HKHealthStore isHealthDataAvailable] == NO) {
        // If our device doesn’t support HealthKit -> return.
        return;
    }
     
    NSArray *readTypes = @[[HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierDateOfBirth]];
     
    NSArray *writeTypes = @[[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass]];
     
    [self.healthStore requestAuthorizationToShareTypes:[NSSet setWithArray:readTypes]
                                             readTypes:[NSSet setWithArray:writeTypes] completion:nil];
}
 
— (NSDate *)readBirthDate {
    NSError *error;
    NSDate *dateOfBirth = [self.healthStore dateOfBirthWithError:&error];
     
    if (!dateOfBirth) {
        NSLog(@»Either an error occured fetching the user’s age information or none has been stored yet. In your app, try to handle this gracefully.»);
    }
     
    return dateOfBirth;
}
 
— (void)writeWeightSample:(CGFloat)weight {
     
    // Each quantity consists of a value and a unit.
    HKUnit *kilogramUnit = [HKUnit gramUnitWithMetricPrefix:HKMetricPrefixKilo];
    HKQuantity *weightQuantity = [HKQuantity quantityWithUnit:kilogramUnit doubleValue:weight];
     
    HKQuantityType *weightType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
    NSDate *now = [NSDate date];
     
    // For every sample, we need a sample type, quantity and a date.
    HKQuantitySample *weightSample = [HKQuantitySample quantitySampleWithType:weightType quantity:weightQuantity startDate:now endDate:now];
     
    [self.healthStore saveObject:weightSample withCompletion:^(BOOL success, NSError *error) {
        if (!success) {
            NSLog(@»Error while saving weight (%f) to Health Store: %@.», weight, error);
        }
    }];
}
 
@end

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

  • sharedManager — это метод класса, который создает одноэлементный объект при первом его вызове и возвращает этот экземпляр при каждом вызове метода. Функция dispatch_once является функцией GCD (Grand Central Dispatch), которая гарантирует, что переданный ей блок вызывается только один раз, даже если метод sharedManager будет вызываться из нескольких потоков одновременно.
  • requestAuthorization — это метод, который запрашивает у хранилища HealthKit разрешения на чтение и / или запись определенных данных, которые нам нужны. Вы должны вызвать этот метод, прежде чем использовать какой-либо API записи / чтения класса HKHealthStore . В случае, если пользователь отказывает в некоторых (или всех) разрешениях, HealthKit не сообщит вам об этом. Тот факт, что пользователь не хочет делиться некоторыми типами данных, сам по себе является информацией. Вот как Apple заботится о конфиденциальности.
  • Метод readBirthDate возвращает дату рождения пользователя. Возвращает nil если произошла ошибка или если пользователь не указал дату рождения.
  • writeWeightSample: сохраняет измерение веса в HealthKit. Я прокомментировал код, чтобы вы имели общее представление о том, что происходит в методе. HKQuantitySample объект HKQuantitySample , мы сохраняем его в экземпляре HKHealthStore , используя saveObject:withCompletion: Этот метод используется для каждого типа данных о состоянии здоровья, и мы также будем использовать его во второй части этого руководства при сохранении тренировок.

На этом этапе вы встретили несколько классов HealthKit. Вы можете прочитать больше о каждом классе в Справочнике по HealthKit Framework , но я дам вам краткое описание каждого класса.

  • HKHealthStore Это ваше окно для данных HealthKit. Apple рекомендует использовать только один экземпляр этого класса в вашем приложении, и это очень хорошо подходит для шаблона синглтона. Вы используете его для запроса у пользователя разрешений, сохранения образцов и / или тренировок в HealthKit и запроса сохраненных данных. Это лишь некоторые из задач класса HKHealthStore .
  • HKUnit Экземпляры этого класса могут представлять собой либо базовые единицы, такие как метры, секунды и граммы, либо сложные единицы, которые создаются путем объединения базовых единиц, таких как км / ч или или г / м³. Сложные единицы могут быть удобно созданы из строк.
  • Экземпляры HKQuantity этого класса хранят значение (представленное двойным) для данной единицы (представленное HKUnit ). Вы можете использовать doubleValueForUnit: метод для преобразования значения количества в переданную единицу измерения. Примером такого преобразования может быть создание величины расстояния с единицей метров и запрос ее значения в футах.
  • HKQuantityType HealthKit использует количественные типы для создания выборок, в которых хранится числовое значение. Рекомендуется использовать quantityTypeForIdentifier: при создании количественных типов. Несколько примеров количественных типов: велосипедное расстояние, сожженная энергия, количество шагов и количество пройденных полетов.
  • HKQuantitySample Экземпляр этого класса представляет образец, который имеет тип количества (представленный HKQuantityType ), количество (представленное HKQuantity ), а также дату начала и окончания. Если выборка не охватывает период времени, дата окончания может совпадать с датой начала.

Теперь мы можем использовать синглтон GSHealthKitManager из любого места в нашем приложении для работы с HealthKit.

В этом руководстве вы узнали об основах инфраструктуры HealthKit. Я познакомил вас с рамками и указал на некоторые предостережения, на которые стоит обратить внимание. Мы также создали основу примера приложения и GSHealthKitManager класс GSHealthKitManager , который мы будем использовать для взаимодействия с HealthKit.

Во второй части этой серии мы продолжим создание примера приложения и продолжим интеграцию HealthKit. Вы можете найти исходные файлы для этого руководства на GitHub .