Commit 90e73e26 authored by Greg Wilson's avatar Greg Wilson

creation and first commit of repo

parents
# OSX
#
.DS_Store
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
project.xcworkspace
# Android/IJ
#
.idea
.gradle
local.properties
*.iml
local.properties
.idea/workspace.xml
.idea/libraries
build
captures
# node.js
#
node_modules/
npm-debug.log
# BUCK
buck-out/
\.buckd/
android/app/libs
android/keystores/debug.keystore
node_modules
RCTAppleHealthKit.xcodeproj/xcuserdata
RCTAppleHealthKit.xcodeproj/project.xcworkspace
.DS_Store
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
3774C8911D2092F20000B3F3 /* RCTAppleHealthKit.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3774C8901D2092F20000B3F3 /* RCTAppleHealthKit.h */; };
3774C8931D2092F20000B3F3 /* RCTAppleHealthKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 3774C8921D2092F20000B3F3 /* RCTAppleHealthKit.m */; };
3774C89B1D2095450000B3F3 /* RCTAppleHealthKit+Queries.m in Sources */ = {isa = PBXBuildFile; fileRef = 3774C89A1D2095450000B3F3 /* RCTAppleHealthKit+Queries.m */; };
3774C89E1D2095850000B3F3 /* RCTAppleHealthKit+TypesAndPermissions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3774C89D1D2095850000B3F3 /* RCTAppleHealthKit+TypesAndPermissions.m */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
3774C88B1D2092F20000B3F3 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "include/$(PRODUCT_NAME)";
dstSubfolderSpec = 16;
files = (
3774C8911D2092F20000B3F3 /* RCTAppleHealthKit.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
3774C88D1D2092F20000B3F3 /* libRCTAppleHealthKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTAppleHealthKit.a; sourceTree = BUILT_PRODUCTS_DIR; };
3774C8901D2092F20000B3F3 /* RCTAppleHealthKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTAppleHealthKit.h; sourceTree = "<group>"; };
3774C8921D2092F20000B3F3 /* RCTAppleHealthKit.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTAppleHealthKit.m; sourceTree = "<group>"; };
3774C8991D2095450000B3F3 /* RCTAppleHealthKit+Queries.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTAppleHealthKit+Queries.h"; sourceTree = "<group>"; };
3774C89A1D2095450000B3F3 /* RCTAppleHealthKit+Queries.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTAppleHealthKit+Queries.m"; sourceTree = "<group>"; };
3774C89C1D2095850000B3F3 /* RCTAppleHealthKit+TypesAndPermissions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTAppleHealthKit+TypesAndPermissions.h"; sourceTree = "<group>"; };
3774C89D1D2095850000B3F3 /* RCTAppleHealthKit+TypesAndPermissions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTAppleHealthKit+TypesAndPermissions.m"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
3774C88A1D2092F20000B3F3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
3774C8841D2092F20000B3F3 = {
isa = PBXGroup;
children = (
3774C88F1D2092F20000B3F3 /* RCTAppleHealthKit */,
3774C88E1D2092F20000B3F3 /* Products */,
);
sourceTree = "<group>";
};
3774C88E1D2092F20000B3F3 /* Products */ = {
isa = PBXGroup;
children = (
3774C88D1D2092F20000B3F3 /* libRCTAppleHealthKit.a */,
);
name = Products;
sourceTree = "<group>";
};
3774C88F1D2092F20000B3F3 /* RCTAppleHealthKit */ = {
isa = PBXGroup;
children = (
3774C8901D2092F20000B3F3 /* RCTAppleHealthKit.h */,
3774C8921D2092F20000B3F3 /* RCTAppleHealthKit.m */,
3774C8991D2095450000B3F3 /* RCTAppleHealthKit+Queries.h */,
3774C89A1D2095450000B3F3 /* RCTAppleHealthKit+Queries.m */,
3774C89C1D2095850000B3F3 /* RCTAppleHealthKit+TypesAndPermissions.h */,
3774C89D1D2095850000B3F3 /* RCTAppleHealthKit+TypesAndPermissions.m */,
);
path = RCTAppleHealthKit;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
3774C88C1D2092F20000B3F3 /* RCTAppleHealthKit */ = {
isa = PBXNativeTarget;
buildConfigurationList = 3774C8961D2092F20000B3F3 /* Build configuration list for PBXNativeTarget "RCTAppleHealthKit" */;
buildPhases = (
3774C8891D2092F20000B3F3 /* Sources */,
3774C88A1D2092F20000B3F3 /* Frameworks */,
3774C88B1D2092F20000B3F3 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = RCTAppleHealthKit;
productName = RCTAppleHealthKit;
productReference = 3774C88D1D2092F20000B3F3 /* libRCTAppleHealthKit.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
3774C8851D2092F20000B3F3 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0730;
ORGANIZATIONNAME = "Greg Wilson";
TargetAttributes = {
3774C88C1D2092F20000B3F3 = {
CreatedOnToolsVersion = 7.3.1;
};
};
};
buildConfigurationList = 3774C8881D2092F20000B3F3 /* Build configuration list for PBXProject "RCTAppleHealthKit" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 3774C8841D2092F20000B3F3;
productRefGroup = 3774C88E1D2092F20000B3F3 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
3774C88C1D2092F20000B3F3 /* RCTAppleHealthKit */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
3774C8891D2092F20000B3F3 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3774C89B1D2095450000B3F3 /* RCTAppleHealthKit+Queries.m in Sources */,
3774C8931D2092F20000B3F3 /* RCTAppleHealthKit.m in Sources */,
3774C89E1D2095850000B3F3 /* RCTAppleHealthKit+TypesAndPermissions.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
3774C8941D2092F20000B3F3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
3774C8951D2092F20000B3F3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
3774C8971D2092F20000B3F3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/../react-native/React/**",
"$(SRCROOT)/node_modules/react-native/React/**",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Debug;
};
3774C8981D2092F20000B3F3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/../react-native/React/**",
"$(SRCROOT)/node_modules/react-native/React/**",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
3774C8881D2092F20000B3F3 /* Build configuration list for PBXProject "RCTAppleHealthKit" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3774C8941D2092F20000B3F3 /* Debug */,
3774C8951D2092F20000B3F3 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
3774C8961D2092F20000B3F3 /* Build configuration list for PBXNativeTarget "RCTAppleHealthKit" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3774C8971D2092F20000B3F3 /* Debug */,
3774C8981D2092F20000B3F3 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
/* End XCConfigurationList section */
};
rootObject = 3774C8851D2092F20000B3F3 /* Project object */;
}
//
// RCTAppleHealthKit+Queries.h
// RCTAppleHealthKit
//
// Created by Greg Wilson on 2016-06-26.
// Copyright © 2016 Greg Wilson. All rights reserved.
//
#import "RCTAppleHealthKit.h"
@interface RCTAppleHealthKit (Queries)
- (void)fetchMostRecentQuantitySampleOfType:(HKQuantityType *)quantityType predicate:(NSPredicate *)predicate completion:(void (^)(HKQuantity *mostRecentQuantity, NSError *error))completion;
- (void)fetchSumOfSamplesTodayForType:(HKQuantityType *)quantityType unit:(HKUnit *)unit completion:(void (^)(double, NSError *))completionHandler;
- (NSPredicate *)predicateForSamplesToday;
@end
//
// RCTAppleHealthKit+Queries.m
// RCTAppleHealthKit
//
// Created by Greg Wilson on 2016-06-26.
// Copyright © 2016 Greg Wilson. All rights reserved.
//
#import "RCTAppleHealthKit+Queries.h"
@implementation RCTAppleHealthKit (Queries)
- (void)fetchMostRecentQuantitySampleOfType:(HKQuantityType *)quantityType predicate:(NSPredicate *)predicate completion:(void (^)(HKQuantity *, NSError *))completion { NSSortDescriptor *timeSortDescriptor = [[NSSortDescriptor alloc] initWithKey:HKSampleSortIdentifierEndDate ascending:NO];
// Since we are interested in retrieving the user's latest sample, we sort the samples in descending order, and set the limit to 1. We are not filtering the data, and so the predicate is set to nil.
HKSampleQuery *query = [[HKSampleQuery alloc] initWithSampleType:quantityType
predicate:predicate
limit:1
sortDescriptors:@[timeSortDescriptor]
resultsHandler:^(HKSampleQuery *query, NSArray *results, NSError *error) {
if (!results) {
if (completion) {
completion(nil, error);
}
return;
}
if (completion) {
// If quantity isn't in the database, return nil in the completion block.
HKQuantitySample *quantitySample = results.firstObject;
HKQuantity *quantity = quantitySample.quantity;
completion(quantity, error);
}
}];
[self.healthStore executeQuery:query];
}
- (void)fetchSumOfSamplesTodayForType:(HKQuantityType *)quantityType unit:(HKUnit *)unit completion:(void (^)(double, NSError *))completionHandler {
NSPredicate *predicate = [self predicateForSamplesToday];
HKStatisticsQuery *query = [[HKStatisticsQuery alloc] initWithQuantityType:quantityType quantitySamplePredicate:predicate options:HKStatisticsOptionCumulativeSum completionHandler:^(HKStatisticsQuery *query, HKStatistics *result, NSError *error) {
HKQuantity *sum = [result sumQuantity];
if (completionHandler) {
double value = [sum doubleValueForUnit:unit];
completionHandler(value, error);
}
}];
[self.healthStore executeQuery:query];
}
#pragma mark - Convenience
- (NSPredicate *)predicateForSamplesToday {
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *now = [NSDate date];
NSDate *startDate = [calendar startOfDayForDate:now];
NSDate *endDate = [calendar dateByAddingUnit:NSCalendarUnitDay value:1 toDate:startDate options:0];
return [HKQuery predicateForSamplesWithStartDate:startDate endDate:endDate options:HKQueryOptionStrictStartDate];
}
@end
//
// RCTAppleHealthKit+TypesAndPermissions.h
// RCTAppleHealthKit
//
// Created by Greg Wilson on 2016-06-26.
// Copyright © 2016 Greg Wilson. All rights reserved.
//
#import "RCTAppleHealthKit.h"
@interface RCTAppleHealthKit (TypesAndPermissions)
- (NSSet *)dataTypesToWrite;
- (NSSet *)dataTypesToRead;
- (NSDictionary *)readPermsDict;
- (NSDictionary *)writePermsDict;
- (NSSet *)getReadPermsFromOptions:(NSArray *)options;
- (NSSet *)getWritePermsFromOptions:(NSArray *)options;
@end
//
// RCTAppleHealthKit+TypesAndPermissions.m
// RCTAppleHealthKit
//
// Created by Greg Wilson on 2016-06-26.
// Copyright © 2016 Greg Wilson. All rights reserved.
//
#import "RCTAppleHealthKit+TypesAndPermissions.h"
@implementation RCTAppleHealthKit (TypesAndPermissions)
#pragma mark - HealthKit Permissions
// Returns the types of data that Fit wishes to write to HealthKit.
- (NSSet *)dataTypesToWrite {
HKQuantityType *dietaryCalorieEnergyType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryEnergyConsumed];
HKQuantityType *activeEnergyBurnType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierActiveEnergyBurned];
HKQuantityType *heightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight];
HKQuantityType *weightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
return [NSSet setWithObjects:dietaryCalorieEnergyType, activeEnergyBurnType, heightType, weightType, nil];
}
// Returns the types of data that Fit wishes to read from HealthKit.
- (NSSet *)dataTypesToRead {
HKQuantityType *dietaryCalorieEnergyType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryEnergyConsumed];
HKQuantityType *activeEnergyBurnType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierActiveEnergyBurned];
HKQuantityType *heightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight];
HKQuantityType *weightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
HKQuantityType *stepCountType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
HKCharacteristicType *birthdayType = [HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierDateOfBirth];
HKCharacteristicType *biologicalSexType = [HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierBiologicalSex];
return [NSSet setWithObjects:dietaryCalorieEnergyType, activeEnergyBurnType, heightType, weightType, stepCountType, birthdayType, biologicalSexType, nil];
}
- (NSDictionary *)readPermsDict {
NSDictionary *readPerms = @{
@"DietaryEnergy" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryEnergyConsumed],
@"ActiveEnergy" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierActiveEnergyBurned],
@"Height" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight],
@"Weight" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass],
@"Steps" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount],
@"DateOfBirth" : [HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierDateOfBirth],
@"Sex" : [HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierBiologicalSex],
};
return readPerms;
}
- (NSDictionary *)writePermsDict {
NSDictionary *writePerms = @{
@"DietaryEnergy" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryEnergyConsumed],
@"ActiveEnergy" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierActiveEnergyBurned],
@"Height" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight],
@"Weight" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass],
};
return writePerms;
}
// Returns HealthKit read permissions from options array
- (NSSet *)getReadPermsFromOptions:(NSArray *)options {
NSDictionary *readPermDict = [self readPermsDict];
NSMutableSet *readPermSet = [NSMutableSet setWithCapacity:1];
for(int i=0; i<[options count]; i++) {
NSString *optionKey = options[i];
HKObjectType *val = [readPermDict objectForKey:optionKey];
if(val != nil) {
RCTLogInfo(@"Adding read permissions from options: %@", optionKey);
[readPermSet addObject:val];
}
}
return readPermSet;
// return [self dataTypesToRead];
}
// Returns HealthKit write permissions from options array
- (NSSet *)getWritePermsFromOptions:(NSArray *)options {
NSDictionary *writePermDict = [self writePermsDict];
NSMutableSet *writePermSet = [NSMutableSet setWithCapacity:1];
for(int i=0; i<[options count]; i++) {
NSString *optionKey = options[i];
HKObjectType *val = [writePermDict objectForKey:optionKey];
if(val != nil) {
RCTLogInfo(@"Adding write permissions from options: %@", optionKey);
[writePermSet addObject:val];
}
}
return writePermSet;
// return [self dataTypesToWrite];
}
@end
//
// RCTAppleHealthKit.h
// RCTAppleHealthKit
//
// Created by Greg Wilson on 2016-06-26.
// Copyright © 2016 Greg Wilson. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <HealthKit/HealthKit.h>
#import "RCTBridgeModule.h"
#import "RCTUtils.h"
#import "RCTLog.h"
@interface RCTAppleHealthKit : NSObject <RCTBridgeModule>
@property (nonatomic) HKHealthStore *healthStore;
- (void)isHealthKitAvailable:(RCTResponseSenderBlock)callback;
- (void)initializeHealthKit:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
- (void)getHealthKitUserWeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
- (void)saveHealthKitUserWeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
- (void)getHealthKitUserStepCount:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
- (void)getModuleInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
@end
//
// RCTAppleHealthKit.m
// RCTAppleHealthKit
//
// Created by Greg Wilson on 2016-06-26.
// Copyright © 2016 Greg Wilson. All rights reserved.
//
#import "RCTAppleHealthKit.h"
#import "RCTAppleHealthKit+Queries.h"
#import "RCTAppleHealthKit+TypesAndPermissions.h"
@implementation RCTAppleHealthKit
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(isAvailable:(RCTResponseSenderBlock)callback)
{
[self isHealthKitAvailable:callback];
}
RCT_EXPORT_METHOD(initHealthKit:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
[self initializeHealthKit:input callback:callback];
}
RCT_EXPORT_METHOD(getCurrentWeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
[self getHealthKitUserWeight:input callback:callback];
}
RCT_EXPORT_METHOD(saveWeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
[self saveHealthKitUserWeight:input callback:callback];
}
RCT_EXPORT_METHOD(getStepCountForToday:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
[self getHealthKitUserStepCount:input callback:callback];
}
RCT_EXPORT_METHOD(getInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
[self getModuleInfo:input callback:callback];
}
- (void)isHealthKitAvailable:(RCTResponseSenderBlock)callback
{
BOOL isAvailable = NO;
if ([HKHealthStore isHealthDataAvailable]) {
isAvailable = YES;
}
callback(@[[NSNull null], @(isAvailable)]);
}
- (void)initializeHealthKit:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
self.healthStore = [[HKHealthStore alloc] init];
if ([HKHealthStore isHealthDataAvailable]) {
NSSet *writeDataTypes = [self dataTypesToWrite];
NSSet *readDataTypes = [self dataTypesToRead];
// get permissions from input object provided by JS options object argument
NSDictionary* permissions =[input objectForKey:@"permissions"];
if(permissions != nil){
NSArray* readPermsArray = [permissions objectForKey:@"read"];
NSArray* writePermsArray = [permissions objectForKey:@"write"];
NSSet* readPerms = [self getReadPermsFromOptions:readPermsArray];
NSSet* writePerms = [self getWritePermsFromOptions:writePermsArray];
if(readPerms != nil) {
readDataTypes = readPerms;
}
if(writePerms != nil) {
writeDataTypes = writePerms;
}
}
[self.healthStore requestAuthorizationToShareTypes:writeDataTypes readTypes:readDataTypes completion:^(BOOL success, NSError *error) {
if (!success) {
NSLog(@"You didn't allow HealthKit to access these read/write data types. In your app, try to handle this error gracefully when a user decides not to provide access. The error was: %@. If you're using a simulator, try it on a device.", error);
callback(@[RCTMakeError(@"You didn't allow HealthKit to access these read/write data types. In your app, try to handle this error gracefully when a user decides not to provide access. The error was: %@. If you're using a simulator, try it on a device.", nil, nil)]);
return;
} else {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
callback(@[[NSNull null], @true]);
});
}
}];
} else {
callback(@[RCTMakeError(@"HealthKit not available....", nil, nil)]);
}
}
- (void)getHealthKitUserWeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
NSMassFormatter *massFormatter = [[NSMassFormatter alloc] init];
massFormatter.unitStyle = NSFormattingUnitStyleLong;
// NSMassFormatterUnit weightFormatterUnit = NSMassFormatterUnitPound;
// NSString *weightUnitString = [massFormatter unitStringFromValue:10 unit:weightFormatterUnit];
// NSString *localizedWeightUnitDescriptionFormat = NSLocalizedString(@"Weight (%@)", nil);
// Query to get the user's latest weight, if it exists.
HKQuantityType *weightType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
[self fetchMostRecentQuantitySampleOfType:weightType predicate:nil completion:^(HKQuantity *mostRecentQuantity, NSError *error) {
if (!mostRecentQuantity) {
NSLog(@"Either an error occured fetching the user's weight information or none has been stored yet. In your app, try to handle this gracefully.");
callback(@[RCTMakeError(@"Either an error occured fetching the user's weight information or none has been stored yet. In your app, try to handle this gracefully.", nil, nil)]);
}
else {
// Determine the weight in the required unit.
HKUnit *weightUnit = [HKUnit poundUnit];
double usersWeight = [mostRecentQuantity doubleValueForUnit:weightUnit];
callback(@[[NSNull null], @(usersWeight)]);
// dispatch_async(dispatch_get_main_queue(), ^{
// });
}
}];
}
- (void)saveHealthKitUserWeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
double weight= [[input objectForKey:@"weight"] doubleValue];
HKUnit *poundUnit = [HKUnit poundUnit];
HKQuantity *weightQuantity = [HKQuantity quantityWithUnit:poundUnit doubleValue:weight];
HKQuantityType *weightType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
NSDate *now = [NSDate date];
HKQuantitySample *weightSample = [HKQuantitySample quantitySampleWithType:weightType quantity:weightQuantity startDate:now endDate:now];
[self.healthStore saveObject:weightSample withCompletion:^(BOOL success, NSError *error) {
if (!success) {
NSLog(@"An error occured saving the weight sample %@. In your app, try to handle this gracefully. The error was: %@.", weightSample, error);
callback(@[RCTMakeError(@"An error occured saving the weight sample", nil, nil)]);
return;
// abort();
}
callback(@[[NSNull null], @(weight)]);
}];
}
- (void)getHealthKitUserStepCount:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
HKQuantityType *stepCountType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
HKUnit *stepsUnit = [HKUnit countUnit];
[self fetchSumOfSamplesTodayForType:stepCountType unit:stepsUnit completion:^(double totalSteps, NSError *error) {
if (!totalSteps) {
NSLog(@"Either an error occured fetching the user's step count information or none has been stored yet. In your app, try to handle this gracefully.");
callback(@[RCTMakeError(@"Either an error occured fetching the user's step count information or none has been stored yet. In your app, try to handle this gracefully.", nil, nil)]);
return;
}
callback(@[[NSNull null], @(totalSteps)]);
}];
}
- (void)getModuleInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
callback(@[[NSNull null], @"ReactNative Apple HealthKit Native Module. Created By Greg Wilson."]);
}
@end
### RCTAppleHealthKit
'use strict'
let { RCTAppleHealthKit } = require('react-native').NativeModules;
module.exports = RCTAppleHealthKit;
{
"name": "react-native-apple-healthkit",
"version": "0.0.1",
"description": "A React Native bridge module for interacting with Apple HealthKit data",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "github.com:GregWilson/RCTAppleHealthKit.git"
},
"keywords": [
"Apple",
"HealthKit",
"health-kit",
"ReactNative",
"react-native"
],
"author": "Greg Wilson",
"license": "MIT",
"devDependencies": {
"react-native": "^0.28.0"
},
"peerDependencies": {
"react-native": "^0.28.0"
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment