如何用Objective-C为iOS HealthKit添加正念分钟数?含Cordova插件需求
Hey there! I get it—finding Objective-C resources for HealthKit can be tricky when most tutorials lean into Swift. Let's walk through building this plugin step by step, tailored for someone new to both Objective-C and Cordova plugin development.
1. Set Up Your Cordova Plugin Template
First, generate a basic plugin structure with plugman (install it first if you haven't: npm install -g plugman):
plugman create --name MindfulMinutesPlugin --plugin_id com.yourdomain.mindfulminutes --plugin_version 1.0.0
Then add the iOS platform to your plugin:
cd MindfulMinutesPlugin plugman platform add --platform_name ios
2. Configure HealthKit Permissions & Capabilities
In plugin.xml
Add these lines to request necessary permissions and link the HealthKit framework:
<platform name="ios"> <!-- Permission descriptions for HealthKit --> <config-file target="*-Info.plist" parent="NSHealthShareUsageDescription"> <string>We need access to save your mindful minutes to HealthKit</string> </config-file> <config-file target="*-Info.plist" parent="NSHealthUpdateUsageDescription"> <string>We need access to update your mindful minutes in HealthKit</string> </config-file> <!-- Link HealthKit framework --> <framework src="HealthKit.framework" weak="true" /> </platform>
Note: weak="true" ensures your plugin works on devices that don't support HealthKit (like older iPads).
In Xcode (After Adding Plugin to a Cordova App)
Once you add the plugin to a Cordova project, open the Xcode workspace and enable HealthKit:
- Go to your app target > Signing & Capabilities > + Capability > Search for "HealthKit" and add it.
3. Write the Objective-C Plugin Logic
Open src/ios/MindfulMinutesPlugin.m and replace its content with this commented code:
#import <Cordova/CDV.h> #import <HealthKit/HealthKit.h> @interface MindfulMinutesPlugin : CDVPlugin @property (nonatomic, strong) HKHealthStore *healthStore; - (void)saveMindfulMinutes:(CDVInvokedUrlCommand *)command; @end @implementation MindfulMinutesPlugin - (void)pluginInitialize { [super pluginInitialize]; // Initialize HealthStore only if the device supports it if ([HKHealthStore isHealthDataAvailable]) { self.healthStore = [[HKHealthStore alloc] init]; } } - (void)saveMindfulMinutes:(CDVInvokedUrlCommand *)command { CDVPluginResult *pluginResult = nil; // Check if HealthKit is available if (![HKHealthStore isHealthDataAvailable]) { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"HealthKit isn't available on this device"]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; return; } // Validate input: expect a number of minutes NSNumber *minutes = [command.arguments objectAtIndex:0]; if (!minutes) { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Missing 'minutes' parameter"]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; return; } // Define the mindful session HealthKit type HKCategoryType *mindfulSessionType = [HKObjectType categoryTypeForIdentifier:HKCategoryTypeIdentifierMindfulSession]; // Request write access to this type NSSet *writeTypes = [NSSet setWithObjects:mindfulSessionType, nil]; [self.healthStore requestAuthorizationToShareTypes:writeTypes readTypes:nil completion:^(BOOL success, NSError *error) { // Switch back to main thread for Cordova callbacks dispatch_async(dispatch_get_main_queue(), ^{ if (!success) { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:[error localizedDescription]]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; return; } // Calculate start/end time (now minus input minutes to now) NSDate *endDate = [NSDate date]; NSDate *startDate = [endDate dateByAddingTimeInterval:-([minutes doubleValue] * 60)]; // Create the mindful session sample HKCategorySample *mindfulSample = [HKCategorySample categorySampleWithType:mindfulSessionType value:0 startDate:startDate endDate:endDate]; // Save the sample to HealthKit [self.healthStore saveObject:mindfulSample withCompletion:^(BOOL success, NSError *error) { dispatch_async(dispatch_get_main_queue(), ^{ if (success) { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"Mindful minutes saved successfully"]; } else { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:[error localizedDescription]]; } [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }); }]; }); }]; } @end
Key Breakdown:
pluginInitialize: Sets up theHKHealthStore(HealthKit's core manager) when the plugin loads.saveMindfulMinutes: The Cordova-exposed method that:- Checks HealthKit availability.
- Validates input parameters.
- Requests user permission to write mindful session data.
- Creates a HealthKit sample with the provided minutes.
- Saves the sample and sends a callback to your Cordova app.
4. Register the Plugin for JavaScript Access
Add this inside the <platform name="ios"> block in plugin.xml:
<source-file src="src/ios/MindfulMinutesPlugin.m" /> <js-module name="MindfulMinutesPlugin" src="www/MindfulMinutesPlugin.js"> <clobbers target="window.MindfulMinutesPlugin" /> </js-module>
Then update www/MindfulMinutesPlugin.js to expose the method to your app's JavaScript:
var exec = require('cordova/exec'); var MindfulMinutesPlugin = { saveMindfulMinutes: function(minutes, successCallback, errorCallback) { exec(successCallback, errorCallback, 'MindfulMinutesPlugin', 'saveMindfulMinutes', [minutes]); } }; module.exports = MindfulMinutesPlugin;
5. Test the Plugin
- Create a test Cordova project:
cordova create MindfulTest com.yourdomain.mindfultest MindfulTest cd MindfulTest cordova platform add ios
- Add your plugin:
cordova plugin add ../MindfulMinutesPlugin
- Update
www/js/index.jsto call the plugin on app load:
document.addEventListener("deviceready", onDeviceReady, false); function onDeviceReady() { console.log("Device ready!"); // Test saving 10 minutes of mindful time window.MindfulMinutesPlugin.saveMindfulMinutes(10, function(result) { console.log(result); }, function(error) { console.error(error); } ); }
- Run on a physical iOS device (HealthKit doesn't work reliably on simulators):
cordova run ios --device
Swift-to-Objective-C Cheat Sheet (For Your Existing Tutorial)
If you want to cross-reference the Swift tutorial you found, here's how key concepts map:
- Swift's
HKHealthStore()→ Objective-C's[[HKHealthStore alloc] init] - Swift's
HKCategoryTypeIdentifier.mindfulSession→ Objective-C'sHKCategoryTypeIdentifierMindfulSession - Swift completion handlers → Objective-C blocks (always dispatch Cordova callbacks to the main thread!)
内容的提问来源于stack exchange,提问作者James Juanjie

