Flutter
Flutter library for integrating WeFitter and HealthKit into your app
Installation
yarn add https://github.com/wefitter/flutter-wefitter-ios.git#v0.0.1
After installing run pod install in ios directory.
Hide code example
Example
class _MyHomePageState extends State<MyHomePage> {
static const platform = MethodChannel('wefitter');
static const platform2 = MethodChannel('wefitter_sdk');
bool supported = true;
bool configured = false;
bool connected = false;
String profile = '';
String error = '';
static final types = [
"ACTIVE_ENERGY_BURNED",
"APPLE_EXERCISE_TIME",
"APPLE_MOVE_TIME",
"BASAL_ENERGY_BURNED",
"BLOOD_GLUCOSE",
"BLOOD_PRESSURE_DIASTOLIC",
"BLOOD_PRESSURE_SYSTOLIC",
"BODY_FAT_PERCENTAGE",
"BODY_MASS",
"BODY_MASS_INDEX",
"BODY_TEMPERATURE",
"CYCLING_CADENCE",
"CYCLING_POWER",
"CYCLING_SPEED",
"DISTANCE_CYCLING",
"DISTANCE_DOWNHILL_SNOW_SPORTS",
"DISTANCE_SWIMMING",
"DISTANCE_WALKING_RUNNING",
// "DISTANCE_WHEELCHAIR",
"ELECTROCARDIOGRAM",
"HEART_RATE",
"HEART_RATE_VARIABILITY_SDNN",
"HEIGHT",
// "MINDFULNESS",
"OXYGEN_SATURATION",
"RESTING_HEART_RATE",
"RUNNING_POWER",
"RUNNING_SPEED",
"SLEEP_ANALYSIS",
// "STAIR_ASCENT_SPEED",
// "STAIR_DESCENT_SPEED",
"STEP_COUNT",
"VO2MAX",
"WALKING_SPEED",
"WORKOUT"
];
// create config
static var config = {
'token': 'YOUR_TOKEN', // required, WeFitter API profile bearer token
// 'apiUrl': 'https://api.wefitter.com/api/', // optional, only use if you want to use your backend as a proxy and forward all API calls to the WeFitter API. Default: `https://api.wefitter.com/api/`
// 'startDate': '2024-09-10', // optional with format `yyyy-MM-dd`, by default data of the past 20 days will be uploaded
// 'enabledDataTypes': types.join(','), // optional array of datatypes to customize requested permissions. Default: all
// 'enableDailyDetail': false, // optional boolean that enables uploading of daily detail. This wil result in a lot of extra processing and can slow down syncing of data when there is a lot of historic data. Default: false
// 'enableHeartRateSamples': false, // optional boolean that enables uploading of heart rate samples. This wil result in a lot of extra processing and can slow down syncing of data when there is a lot of historic data. Default: false
};
@override
void initState() {
super.initState();
platform2.setMethodCallHandler(nativeMethodCallHandler);
platform.invokeMethod("configure", {'config': config});
}
Future<dynamic> nativeMethodCallHandler(MethodCall methodCall) async {
switch (methodCall.method) {
case "onConfiguredWeFitterHealthConnect" :
setState(() {
configured = methodCall.arguments["configured"];
});
break;
case "onConnectedWeFitterHealthConnect" :
setState(() {
connected = methodCall.arguments["connected"];
if (connected) {profile = methodCall.arguments["profile"];} else {profile = '';}
});
break;
case "onSupported" :
setState(() {
supported = methodCall.arguments["supported"];
});
break;
case "onErrorWeFitterHealthConnect" :
setState(() {
error = methodCall.arguments["error"];
});
break;
default:
return "Nothing";
break;
}
}
void _onPressConnectOrDisconnect() {
setState(() {
if (Platform.isIOS) {
// platform.invokeMethod("isSupported");
supported = true;
if (supported) {
if (connected) {
platform.invokeMethod("disconnect");
} else {
platform.invokeMethod("connect");
}
}
} else {
// Alert
};
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Configured: $configured',
style: Theme.of(context).textTheme.bodyMedium,
),Text(
'Connected: $connected',
style: Theme.of(context).textTheme.bodyMedium,
),Text(
connected ? 'Profile: $profile' : '',
style: Theme.of(context).textTheme.bodyMedium,
),Text(
error != '' ? 'Error: $error' : '',
style: TextStyle(color: Colors.red.withOpacity(0.9)),
),
TextButton(
style: ButtonStyle(
foregroundColor: WidgetStateProperty.all<Color>(Colors.white),
backgroundColor: WidgetStateProperty.all<Color>(Colors.blue),
),
onPressed: _onPressConnectOrDisconnect,
child: Text(connected ? 'DISCONNECT' : 'CONNECT'),
),
],
),
),
);
}
}