How health records can be added to a health app through the Health Kit

I can read Sample data entries in the Health application, such as Body Weight, Height, Weight, and read profile data such as Age, Gender, Blood Type, etc. My piece of code for auth requests and read / write methods is given below.

- (void)requestAuthorization {

    if ([HKHealthStore isHealthDataAvailable] == NO) {
        // If our device doesn't support HealthKit -> return.
        return;
    }

    HKObjectType *dateOfBirth = [HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierDateOfBirth];
    HKObjectType *bloodType = [HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierBloodType];
    HKObjectType *biologicalSex = [HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierBiologicalSex];
    HKObjectType *wheelChairUse = [HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierWheelchairUse];
    HKObjectType *skinType = [HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierFitzpatrickSkinType];

    HKObjectType *bodyMassIndex = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMassIndex];
    HKObjectType *height = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight];
    HKObjectType *bodyMass = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
    HKObjectType *activeEnergy = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierActiveEnergyBurned];

    HKObjectType *heartRate = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate];
    HKObjectType *bloodGlucose = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodGlucose];
    HKObjectType *bodyTemprature = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyTemperature];
    HKObjectType *respiratoryRate = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierRespiratoryRate];
    HKObjectType *oxygenSaturation = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierOxygenSaturation];
    HKObjectType *fatPercentage = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyFatPercentage];
    HKObjectType *waistCircumference = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierWaistCircumference];
    HKObjectType *cholestrol = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryCholesterol];


    NSArray *healthKitTypesToWrite = @[bodyMassIndex,
                                       activeEnergy,
                                       HKObjectType.workoutType];

    NSArray *healthKitTypesToRead = @[dateOfBirth,
                                      bloodType,
                                      biologicalSex,
                                      bodyMassIndex,
                                      height,
                                      bodyMass,
                                      wheelChairUse,
                                      skinType,
                                      heartRate,
                                      bloodGlucose,
                                      bodyTemprature,
                                      respiratoryRate,
                                      oxygenSaturation,
                                      fatPercentage,
                                      waistCircumference,
                                      cholestrol,
                                      HKObjectType.workoutType];

    [self.healthStore requestAuthorizationToShareTypes:[NSSet setWithArray:healthKitTypesToWrite] readTypes:[NSSet setWithArray:healthKitTypesToRead] completion:^(BOOL success, NSError * _Nullable error) {

    }];
}

helper pragma

- (void )getMostRecentSampleForType:(HKSampleType *)sampleType
                  withResultHandler:(HKQueryResultHandler )handler {

    NSPredicate *mostRecentPredicate = [HKQuery predicateForSamplesWithStartDate:NSDate.distantPast endDate:[NSDate date] options:HKQueryOptionStrictEndDate];
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:HKSampleSortIdentifierStartDate ascending:false];
    NSInteger limit = 1;

    HKSampleQuery *sampleQuery = [[HKSampleQuery alloc] initWithSampleType:sampleType predicate:mostRecentPredicate limit:limit sortDescriptors:@[sortDescriptor] resultsHandler:^(HKSampleQuery * _Nonnull query, NSArray<__kindof HKSample *>* _Nullable results, NSError * _Nullable error) {

        dispatch_async(dispatch_get_main_queue(), ^{
            // do work here
            if (handler) {
                if (results && results.count > 0) {
                    HKQuantitySample *sample = (HKQuantitySample *)[results firstObject];
                    handler(sample,nil);
                }else {
                    handler(nil,error);
                }
            }
        });
    }];

    HKHealthStore *store = [[HKHealthStore alloc] init];
    [store executeQuery:sampleQuery];
}

pragma-tag- reading methods

- (NSDate *)readBirthDate {
    NSError *error;

    NSDateComponents *components = [self.healthStore dateOfBirthComponentsWithError:&error];
    // Convenience method of HKHealthStore to get date of birth directly.

    NSCalendar *cal = [NSCalendar currentCalendar];
    [cal setTimeZone:[NSTimeZone localTimeZone]];
    [cal setLocale:[NSLocale currentLocale]];
    NSDate *dateOfBirth = [cal dateFromComponents:components];

    if (!dateOfBirth) {
        NSLog(@"Either an error occured fetching the user age information or none has been stored yet. In your app, try to handle this gracefully.");
    }
    return dateOfBirth;
}

- (NSString *)biologicalSex {
    HKBiologicalSexObject *genderObj = [self.healthStore biologicalSexWithError:nil];
    HKBiologicalSex gender = genderObj.biologicalSex;

    switch (gender) {
        case HKBiologicalSexNotSet:
            return @"";
        case HKBiologicalSexFemale:
            return @"Female";
        case HKBiologicalSexMale:
            return @"Male";
        case HKBiologicalSexOther:
            return @"Other";
        default:
            break;
    }
    return @"";
}

- (NSString *)weight {
    HKSampleType *weightSampleType = [HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
    [self getMostRecentSampleForType:weightSampleType withResultHandler:^(HKQuantitySample *sample, NSError *error) {
        if (!errno) {
            HKQuantity *quantity = sample.quantity;
            HKUnit *kilogramUnit = [HKUnit gramUnitWithMetricPrefix:HKMetricPrefixKilo];
            double weight = [quantity doubleValueForUnit:kilogramUnit];
            NSLog(@"weight = %.0f Kg",weight);
        }
    }];
    return @"";
}

pragma mark-write method

- (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);
        }
    }];
}

But I do not know how to add entries to Health DataHealth Records

Health Record

There is no data

+4
source share
3 answers
// 1. Create a BMI Sample
let bmiType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.bodyMassIndex)
let bmiQuantity = HKQuantity(unit: HKUnit.count(), doubleValue: bmi)
let bmiSample = HKQuantitySample(type: bmiType!, quantity: bmiQuantity, start: date as Date, end: date as Date)

// 2. Save the sample in the store
healthKitStore.save(bmiSample, withCompletion: { (success, error) -> Void in
    if( error != nil ) {
        print("Error saving BMI sample: \(String(describing: error?.localizedDescription))")
    } else {
        print("BMI sample saved successfully!")
    }
})
0

I am not familiar with HL7 and CDA Pro because I am not a member of the healthcare industry. So I can not add codeSystem, code, codeSystemNameetc. With relevant entries. Although I found a way to create my own custom CDA file to display in medical records.

You need to save the CDA placeholder file in the resource bundle. visitSummary.xml

- (void)addToHealth {      

    NSURL *cdaURL = [[NSBundle mainBundle] URLForResource:@"visitSummary" withExtension:@"xml"];
    NSError *parsingError = nil;
    NSString *string = [NSString stringWithContentsOfURL:cdaURL encoding:NSUTF8StringEncoding error:&parsingError];

    string = [string stringByReplacingOccurrencesOfString:@"DOCUMENT_ID" withString:@"DOC449"];
    string = [string stringByReplacingOccurrencesOfString:@"PAT_NAME" withString:@"Alan Joseph"];
    string = [string stringByReplacingOccurrencesOfString:@"MOBILE_NO" withString:@"9643453174"];
    string = [string stringByReplacingOccurrencesOfString:@"EMAIL_ID" withString:@"alan28.joseph@gmail.com"];
    string = [string stringByReplacingOccurrencesOfString:@"PATIENT_ID" withString:@"PID242000012"];
    string = [string stringByReplacingOccurrencesOfString:@"DATE_OF_BIRTH" withString:@"19920515"];

    string = [string stringByReplacingOccurrencesOfString:@"PAT_STREET_LINE" withString:@"Prithviraj Market, Khan Market"];
    string = [string stringByReplacingOccurrencesOfString:@"PAT_CITY" withString:@"New Delhi"];
    string = [string stringByReplacingOccurrencesOfString:@"PAT_STATE" withString:@"Delhi"];
    string = [string stringByReplacingOccurrencesOfString:@"PAT_POSTAL" withString:@"110003"];

    string = [string stringByReplacingOccurrencesOfString:@"GENDER_CODE" withString:@"M"];
    string = [string stringByReplacingOccurrencesOfString:@"GENDER_DISPLAY" withString:@"Male"];

    string = [string stringByReplacingOccurrencesOfString:@"MODEL_NAME" withString:@"iPad Air"];
    string = [string stringByReplacingOccurrencesOfString:@"AUTHOR_NAME" withString:@"Mark"];
    string = [string stringByReplacingOccurrencesOfString:@"CUSTODIAN_NAME" withString:@"Dr. Lauren"];

    string = [string stringByReplacingOccurrencesOfString:@"ALLERGY_COMPONENTS" withString:[self allergyComponents]];
    string = [string stringByReplacingOccurrencesOfString:@"FAMILY_HISTORY_COMPONENTS" withString:[self familyHistoryComponents]];
        string = [string stringByReplacingOccurrencesOfString:@"VITALS_COMPONENTS" withString:[self vitalSignsComponents]];

    NSData *cdaData = [string dataUsingEncoding:NSUTF8StringEncoding];

    NSError *validationError = nil;
    NSDate *date = [NSDate date];
    HKSample *cdaSample = [HKCDADocumentSample CDADocumentSampleWithData:cdaData startDate:date endDate:date metadata:nil validationError:&validationError];

    if (cdaSample != nil) {
        [self.healthStore saveObject:cdaSample withCompletion:^(BOOL success, NSError * _Nullable error) {
            if (!success) {
                NSLog(@"Error while saving CDA to Health Store: %@.", error);
            }
        }];
    }else {
        NSLog(@"No records");
    }
}

Although you need to add another request HKObjectType ie; CDA file.

HKObjectType *cdaObjType = [HKObjectType documentTypeForIdentifier:HKDocumentTypeIdentifierCDA];

NSArray *healthKitTypesToWrite = @[bodyMassIndex,
                                   activeEnergy,
                                   cdaObjType,
                                   HKObjectType.workoutType];

NSArray *healthKitTypesToRead = @[dateOfBirth,
                                  bloodType,
                                  biologicalSex,
                                  bodyMassIndex,
                                  height,
                                  bodyMass,
                                  wheelChairUse,
                                  skinType,
                                  heartRate,
                                  bloodGlucose,
                                  bodyTemprature,
                                  respiratoryRate,
                                  oxygenSaturation,
                                  fatPercentage,
                                  waistCircumference,
                                  cholestrol,
                                  cdaObjType,
                                  HKObjectType.workoutType];

[self.healthStore requestAuthorizationToShareTypes:[NSSet setWithArray:healthKitTypesToWrite] readTypes:[NSSet setWithArray:healthKitTypesToRead] completion:^(BOOL success, NSError * _Nullable error) {

}];

Helper methods for preparing components.

- (NSString *)allergyComponents {

    NSMutableArray *allergyComponents = [[NSMutableArray alloc] init];

    [allergyComponents addObject:@"<component>"];
    [allergyComponents addObject:@"<section>"];
    [allergyComponents addObject:@"<title>Allergies</title>"];
    [allergyComponents addObject:@"<text>"];
    [allergyComponents addObject:@"<table border=\"1\" width=\"100%\">"];

    [allergyComponents addObject:@"<thead><tr>"];
    [allergyComponents addObject:@"<th>Name</th>"];
    [allergyComponents addObject:@"<th>Type</th>"];
    [allergyComponents addObject:@"<th>Exists From</th>"];
    [allergyComponents addObject:@"</tr></thead>"];
    [allergyComponents addObject:@"<tbody>"];

    for (int i = 0; i<3; i++) {
        [allergyComponents addObject:@"<tr>"];
        [allergyComponents addObject:@"<td>Abalone,perlemoen</td>"];
        [allergyComponents addObject:@"<td>Food Allergy</td>"];
        [allergyComponents addObject:@"<td>29 Feb</td>"];
        [allergyComponents addObject:@"</tr>"];
    }

    [allergyComponents addObject:@"</tbody>"];
    [allergyComponents addObject:@"</table>"];
    [allergyComponents addObject:@"</text>"];
    [allergyComponents addObject:@"</section>"];
    [allergyComponents addObject:@"</component>"];

    return [allergyComponents componentsJoinedByString:@""];
}

- (NSString *)familyHistoryComponents {

    NSMutableArray *familyComponents = [[NSMutableArray alloc] init];

    [familyComponents addObject:@"<component>"];
    [familyComponents addObject:@"<section>"];
    [familyComponents addObject:@"<title>Family History</title>"];
    [familyComponents addObject:@"<text>"];
    [familyComponents addObject:@"<table border=\"1\" width=\"100%\">"];

    [familyComponents addObject:@"<thead><tr>"];
    [familyComponents addObject:@"<th>Relation</th>"];
    [familyComponents addObject:@"<th>Condition</th>"];
    [familyComponents addObject:@"</tr></thead>"];
    [familyComponents addObject:@"<tbody>"];

    for (int i = 0; i<2; i++) {
        [familyComponents addObject:@"<tr>"];
        [familyComponents addObject:@"<td>Father</td>"];
        [familyComponents addObject:@"<td>A, Hemophilia</td>"];
        [familyComponents addObject:@"</tr>"];
    }

    [familyComponents addObject:@"</tbody>"];
    [familyComponents addObject:@"</table>"];
    [familyComponents addObject:@"</text>"];
    [familyComponents addObject:@"</section>"];
    [familyComponents addObject:@"</component>"];

    return [familyComponents componentsJoinedByString:@""];
}

- (NSString *)vitalSignsComponents {

    NSMutableArray *vitalSigns = [[NSMutableArray alloc] init];

    [vitalSigns addObject:@"<component>"];
    [vitalSigns addObject:@"<section>"];
    [vitalSigns addObject:@"<title>Vital Signs</title>"];
    [vitalSigns addObject:@"<text>"];
    [vitalSigns addObject:@"<table border=\"1\" width=\"100%\">"];

    [vitalSigns addObject:@"<thead><tr>"];
    [vitalSigns addObject:@"<th align=\"right\">Date</th>"];
    [vitalSigns addObject:@"<th>Vital</th>"];
    [vitalSigns addObject:@"<th>Reading</th>"];
    [vitalSigns addObject:@"</tr></thead>"];
    [vitalSigns addObject:@"<tbody>"];

    for (int i = 0; i<2; i++) {
        [vitalSigns addObject:@"<tr>"];
        [vitalSigns addObject:@"<th align=\"left\">26-10-2017</th>"];
        [vitalSigns addObject:@"<td>Pulse</td>"];
        [vitalSigns addObject:@"<td>12 bpm</td>"];
        [vitalSigns addObject:@"</tr>"];
    }

    [vitalSigns addObject:@"</tbody>"];
    [vitalSigns addObject:@"</table>"];
    [vitalSigns addObject:@"</text>"];
    [vitalSigns addObject:@"</section>"];
    [vitalSigns addObject:@"</component>"];

    return [vitalSigns componentsJoinedByString:@""];
}

And here is the conclusion of how it will look in the application for health.

enter image description here

The preview will look.

enter image description here

0
source

Source: https://habr.com/ru/post/1693395/


All Articles