Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
@perfood/capacitor-healthkit
Advanced tools
Capacitor plugin to read data from and write data to Apple Health
:heart: Capacitor plugin to retrieve data from HealthKit :heart:
Disclaimer : for now only some of the HK data base, in the future the retrieve base will be bigger !
Do
npm i --save @perfood/capacitor-healthkit
Then
npx cap update
And if you use Ionic or Angular, here a example setup:
in your .ts file add this:
import { Plugins, PluginResultError } from '@capacitor/core';
const { CapacitorHealthkit } = Plugins;
and then you can create async functions for example like this:
async queryHKitSampleType(sampleName: string) {
// sample name, start date (string), end Date (date), limit (0 to infinite)
// let start = "2019/07/01" // YY/MM/DD
this.dataName = sampleName;
const endDate = new Date();
this.data = await CapacitorHealthkit.queryHKitSampleType({
sampleName: sampleName,
startDate: "2019/07/01",
endDate: endDate,
limit: 0
});
}
so you can use the plugin for example with the call CapacitorHealthkit.queryHKitSampleType(...
And you're all set ! :+1:
Tells if HealthKit is available on the device.
isAvailable(successCallback, errorCallback)
{type: function(available)}
, if available a true is passed as argument, false otherwise{type: function(err)
, called if something went wrong, err contains a textual description of the problemTells if HealthKit is authorized for edit data.
isEditionAuthorized(sampleName, successCallback, errorCallback)
{
sampleName : "stepCount"
}
{type: function(available)}
, if available a true is passed as argument, false otherwise{type: function(err)
, called if something went wrong, err contains a textual description of the problemSample name available for this query:
Sample name for query | Request Auth Needed | HealthKit equivalent |
---|---|---|
stepCount | steps | HKQuantityTypeIdentifierStepCount |
flightsClimbed | stairs | HKQuantityTypeIdentifierFlightsClimbed |
distanceWalkingRunning | distance | HKQuantityTypeIdentifierDistanceWalkingRunning |
distanceCycling | distance | HKQuantityTypeIdentifierDistanceCycling |
appleExerciseTime | appleExerciseTime | HKQuantityTypeIdentifierAppleExerciseTime |
activeEnergyBurned | calories | HKQuantityTypeIdentifierActiveEnergyBurned |
basalEnergyBurned | calories | HKQuantityTypeIdentifierBasalEnergyBurned |
sleepAnalysis | activity | HKCategoryTypeIdentifierSleepAnalysis |
workoutType | activity | HKWorkoutTypeIdentifier |
Tells if HealthKit is authorized for edit data (you can ask in this method for multiple sampleName)
isEditionAuthorized(sampleNames, successCallback, errorCallback)
{
sampleNames : ["stepCount", "flightsClimbed"]
}
{type: function(available)}
, if available a true is passed as argument, false otherwise{type: function(err)
, called if something went wrong, err contains a textual description of the problemSame sample names available as isEditionAuthorized()
Requests read and write access to a set of data types. It is recommendable to always explain why the app needs access to the data before asking the user to authorize it.
Important: this method must be called before using the query and store methods, even if the authorization has already been given at some point in the past. Failure to do so may cause your app to crash... :grimacing:
requestAuthorization(datatypes, successCallback, errorCallback)
{
all : [""] // Read & Write permission
read : ["steps"], // Read only permission
write : ["height", "weight"] // Write only permission
}
Example:
let result = await CapacitorHealthkit.requestAuthorization({
all: ["calories", "stairs", "activity"], // ask for Read & Write permission
read: ["steps", "distance", "duration"], // ask for Read Only permission
write: [""] // ask for Write Only permission
});
{type: function}
, called if all OK{type: function(err)}
, called if something went wrong, err contains a textual description of the problemThe datatype activity also includes sleep. If you want to get authorization only for workouts, you can specify workouts as datatype, but be aware that this is only availabe in iOS.
Data type for requestAuthorization:
Data type | Unit | What you actually ask from HealthKit with this data type |
---|---|---|
steps | count | HKQuantityTypeIdentifierStepCount |
stairs | count | HKQuantityTypeIdentifierFlightsClimbed |
distance | m | HKQuantityTypeIdentifierDistanceWalkingRunning + HKQuantityTypeIdentifierDistanceCycling |
duration | min | HKQuantityTypeIdentifierAppleExerciseTime |
calories | kcal | HKQuantityTypeIdentifierActiveEnergyBurned + HKQuantityTypeIdentifierBasalEnergyBurned |
activity | activityType | HKWorkoutTypeIdentifier + HKCategoryTypeIdentifierSleepAnalysis |
"duration"
should be ask for read only property
Please make sure that you called correct requestAuthorization for HealthKit sample you want before use this method :shipit:
Gets all the data points of a certain data type within a certain time window.
Warning: if the time span is big, it can generate long arrays! :cold_sweat:
queryHKitSampleType(queryOptions, successCallback, errorCallback)
queryOptions example:
const endDate = new Date();
queryOptions = {
sampleName: "stepCount", // String
startDate: "2019/07/01", // String
endDate: endDate, // Date
limit: 0 // Int
};
Sample name available for queries:
Sample name for query | Request Auth Needed | HealthKit equivalent |
---|---|---|
stepCount | steps | HKQuantityTypeIdentifierStepCount |
flightsClimbed | stairs | HKQuantityTypeIdentifierFlightsClimbed |
distanceWalkingRunning | distance | HKQuantityTypeIdentifierDistanceWalkingRunning |
distanceCycling | distance | HKQuantityTypeIdentifierDistanceCycling |
appleExerciseTime | appleExerciseTime | HKQuantityTypeIdentifierAppleExerciseTime |
activeEnergyBurned | calories | HKQuantityTypeIdentifierActiveEnergyBurned |
basalEnergyBurned | calories | HKQuantityTypeIdentifierBasalEnergyBurned |
sleepAnalysis | activity | HKCategoryTypeIdentifierSleepAnalysis |
workoutType | activity | HKWorkoutTypeIdentifier |
Example function in Angular:
async queryHKitSampleType(sampleName: string) {
// sample name, start date (string), end Date (date), limit (0 to infinite)
// let start = "2019/07/01" // YY/MM/DD
this.dataName = sampleName;
const endDate = new Date();
this.data = await CapacitorHealthkit.queryHKitSampleType({
sampleName: sampleName,
startDate: "2019/07/01",
endDate: endDate,
limit: 0
});
}
startDate: {type: Date}, start date from which to get data
endDate: {type: Date}, end data to which to get the data
sampleName: {type: String}, the data type to be queried (see above)
limit: {type: integer}, optional, sets a maximum number of returned values
successCallback: {type: function(data) }, called if all OK, data contains the result of the query in the form of an array (detail below)
errorCallback: {type: function(err)}, called if something went wrong, err contains a textual description of the problem
iOS quirks:
Result of query (array):
{
"countReturn": result.count, // number of results
"resultDate": output // output data in result of query
}
countReturn returns the number of results
output contain a set of fixed fields:
output content:
- uuid (string)
- value (double)
- unitName (string)
- startDate (ISO8601 String)
- endDate (ISO8601 String)
- duration (double)
- source (string)
- sourceBundleId (string)
- uuid (string)
- startDate (ISO8601 String)
- endDate (ISO8601 String)
- duration (double)
- source (string)
- sourceBundleId (string)
- workoutActivityId (Int)
- totalEnergyBurned (kilocalorie)
- totalDistance (meter)
- totalFlightsClimbed (count)
- totalSwimmingStrokeCount (count)
If data = -1 => no data collected
- uuid (string)
- startDate (ISO8601 String)
- endDate (ISO8601 String)
- duration (double)
- source (string)
- sourceBundleId (string)
Please make sure that you called correct requestAuthorization for HealthKit sample you want before use this method :shipit:
Gets all the data points of multiple data types within a certain time window.
Exact same query as queryHKitSampleType() but return a large object with all queries in one.
Warning: if the time span is big, it can generate long arrays! :cold_sweat:
multipleQueryHKitSampleType(queryOptions, successCallback, errorCallback)
queryOptions example:
const endDate = new Date();
queryOptions = {
sampleNames: ["stepCount", "workoutType"], // String
startDate: startDate, // Date
endDate: endDate, // Date
limit: 0 // Int
};
result will look like : [String: [String: Any]] First string is sample name, then [String: Any] is exactly like return of queryHKitSampleType() method
This project is licensed under the MIT License
FAQs
Capacitor plugin to read data from and write data to Apple Health
The npm package @perfood/capacitor-healthkit receives a total of 60 weekly downloads. As such, @perfood/capacitor-healthkit popularity was classified as not popular.
We found that @perfood/capacitor-healthkit demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.