Menu

 

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.

 

Usage

Add the following code:

See the example app for the full source.

Show code example
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'),
            ),
          ],
        ),
      ),
    );
  }
}

Thank you for reaching out!

We will be in touch with you soon. WeFitter team.

You are subscribed!

You will soon receive our newsletter!
WeFitter team.