Tech

A Short Guide To Integrating Wearables

Integrating wearables with apps can deliver a range of benefits to users.

Image credits: https://www.citymatters.london/

At Calcey, we believe that great things can happen at the intersection of business and technology. Be it in bio-tech, education, real estate, or finance, the intelligent use of technology can make things better for everyone.

Take for instance Fresh Fitness Food (FFF), a Calcey customer and a London-based startup that specialises in delivering bespoke healthy meals to suit a given caloric requirement of a customer. Every day, thousands of fitness-addicts in and around London, including former England and Wasps rugby player James Haskell, depend on FFF to satisfy their nutritional requirements. 

When you are in the business of delivering healthy meals to fitness junkies, it is really important to ensure that each and every meal suits the needs and dietary preferences of EVERY SINGLE CUSTOMER. To do so, bespoke meal services usually ask customers for information such as height, weight, metabolic rate, allergies and more.

Collecting this data is often a cumbersome process. To make things worse, the human brain is notoriously bad at estimating, as many a scientist has pointed out before.

But, what about the wearables on our wrists? These tiny devices manage to gather a treasure trove of information on us with every passing day, and soon, medical professionals could use the data to even predict illnesses. Why can’t services such as FFF tap into this treasure trove of data instead of relying on inputs from customers?

Integrating wearables with apps can provide a few distinct benefits such as:

Access to real time data

Wearables can provide apps with continuous access to a stream of real time data, thus allowing them to deliver an optimal user experience at all times. For a custom meal service like FFF, access to real time data will allow it to tweak meals to a customer’s shifting health attributes on a daily, weekly or monthly basis.

Better user experiences through precise data collection

For companies and apps operating in the health-tech or fit-tech space, the data collection process is the starting point of the value chain as well as the customer journey. As such, the accuracy of this data is extremely important, and more precise data makes for a better user experience. When paired with a fitness tracker, apps such as Fitbit Coach and Nike Training Club can deliver a vastly superior experience that very closely reflects the needs of the user (based on their physical attributes) compared to when they are used in isolation and depend on user input alone.

Insurance giant AIA’s Vitality programme is a great example. By integrating insurance with fitness trackers, the company can incentivise users to take care of their health and use the data to fine tune their underwriting practices over time.

All major wearable manufacturers such as Apple, Fitbit and Garmin provide developers with access to APIs that make it a breeze to integrate wearables with web and mobile apps. Given below are the basics of what you need to know if you ever intend to integrate a wearable with an app. For the sake of simplicity, we will only be focusing on integrating the Apple Health, Fitbit, and Garmin platforms with an iOS app.

Integrating Apple Health

Of all the wearable platforms, Apple’s HealthKit platform is probably the most feature-rich and easiest to integrate. Due to its laser-like focus on privacy, Apple requires developers to obtain the explicit consent of users before accessing data. In true Apple style, the company provides developers with a set of guidelines for the purpose, and developers are expected to inform users of exactly how and why their information would be used. Typically, this can be accomplished by making amendments to the app’s Info.plist file.

HealthKit relies heavily on subclassing. At its most basic level, this is how a code snippet would look:

class HKQuantitySample : HKSample

HealthKit has several different data types of which ‘Quantity Samples’ is the most common. This data type grants access to data such as a user’s height and weight, pulse rate, etc. which can then be used by services such as FFF to build a user profile.

Here’s a sample of how the code for a query to find out the basal energy burn would look like:

guard let quantityType = HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.basalEnergyBurned) else {
  fatalError("*** Unable to create a step count type ***")
}
// Create the query
let query = HKStatisticsCollectionQuery(quantityType: quantityType,quantitySamplePredicate: nil,options: .cumulativeSum,anchorDate: anchorDate,intervalComponents: interval)

Integrating Fitbit

Fitbit is somewhat different to Apple in that it does not allow developers to access historical data. To get around this problem, developers can use Fitbit’s Health API (now known as the Web API) 

The Fitbit API uses OAuth 2 as its authentication protocol. Since integrating a service through the OAuth 2 protocol can be messy, developers can rely on Swift’s OAuth library to complete the integration. This method should serve well in most instances, and doesn’t take much time to implement as well.

Once a connection is established, the Fitbit APIs Profile and Activity endpoints (or any other endpoint) can be used to obtain the necessary data.

Here’s an example of a GET request that can be entered to obtain information about activities completed by the user:

GET https://api.fitbit.com/1/user/[user-id]/activities/date/[date].json

Once processed, the API would spit out this response:

{
    "activities":[
        {
            "activityId":51007,
            "activityParentId":90019,
            "calories":230,
            "description":"7mph",
            "distance":2.04,
            "duration":1097053,
            "hasStartTime":true,
            "isFavorite":true,
            "logId":1154701,
            "name":"Treadmill, 0% Incline",
            "startTime":"00:25",
            "steps":3783
        }
    ],
    "goals":{
        "caloriesOut":2826,
        "distance":8.05,
        "floors":150,
        "steps":10000
     },
    "summary":{
        "activityCalories":230,
        "caloriesBMR":1913,
        "caloriesOut":2143,
        "distances":[
            {"activity":"tracker", "distance":1.32},
            {"activity":"loggedActivities", "distance":0},
            {"activity":"total","distance":1.32},
            {"activity":"veryActive", "distance":0.51},
            {"activity":"moderatelyActive", "distance":0.51},
            {"activity":"lightlyActive", "distance":0.51},
            {"activity":"sedentaryActive", "distance":0.51},
            {"activity":"Treadmill, 0% Incline", "distance":3.28}
        ],
        "elevation":48.77,
        "fairlyActiveMinutes":0,
        "floors":16,
        "lightlyActiveMinutes":0,
        "marginalCalories":200,
        "sedentaryMinutes":1166,
        "steps":0,
        "veryActiveMinutes":0
    }
}

Here’s another example of a GET request through which developers can obtain details about the user’s profile:

GET https://api.fitbit.com/1/user/[user-id]/profile.json

And the response:

{
    "user": {
        "aboutMe":<value>,
        "avatar":<value>,
        "avatar150":<value>,
        "avatar640":<value>,
        "city":<value>,
        "clockTimeDisplayFormat":<12hour|24hour>,
        "country":<value>,
        "dateOfBirth":<value>,
        "displayName":<value>,
        "distanceUnit":<value>,
        "encodedId":<value>,
        "foodsLocale":<value>,
        "fullName":<value>,
        "gender":<FEMALE|MALE|NA>,
        "glucoseUnit":<value>,
        "height":<value>,
        "heightUnit":<value>,
        "locale":<value>,
        "memberSince":<value>,
        "offsetFromUTCMillis":<value>,
        "startDayOfWeek":<value>,
        "state":<value>,
        "strideLengthRunning":<value>,
        "strideLengthWalking":<value>,
        "timezone":<value>,
        "waterUnit":<value>,
        "weight":<value>,
        "weightUnit":<value>
    }
}

Integrating Garmin

Unlike Fitbit, Garmin’s Health API uses OAuth 1 as its authentication protocol. Don’t worry though, because Swift’s OAuth library supports both OAuth 1 and OAuth 2 protocols.

To fetch data, developers can use the Garmin API’s Activities and Dailies classes. Here’s a sample code snippet that can be used to obtain a daily summary of the user’s activity.

Here’s the GET request:

GET https://healthapi.garmin.com/wellness- api/rest/dailies?uploadStartTimeInSeconds=1452470400&uploadEndTimeInSeconds=1452556800

And here’s the response:

{ "summaryId": " EXAMPLE_67891", "calendarDate": "2016-01-11", "activityType": "WALKING", "activeKilocalories": 321, "bmrKilocalories": 1731, "consumedCalories": 1121,
"steps": 4210,
"distanceInMeters": 3146.5, "durationInSeconds": 86400, "activeTimeInSeconds": 12240, "startTimeInSeconds": 1452470400, "startTimeOffsetInSeconds": 3600, "moderateIntensityDurationInSeconds": 81870, "vigorousIntensityDurationInSeconds": 4530, "floorsClimbed": 8, "minHeartRateInBeatsPerMinute": 59, "averageHeartRateInBeatsPerMinute": 64, "maxHeartRateInBeatsPerMinute": 112, "timeOffsetHeartRateSamples": {
    "15": 75"30": 75,
     "3180": 76,
     "3195": 65,
     "3210": 65,
     "3225": 73,
     "3240": 74,
     "3255": 74
},
"averageStressLevel": 43, "maxStressLevel": 87, "stressDurationInSeconds": 13620, "restStressDurationInSeconds": 7600, "activityStressDurationInSeconds": 3450, "lowStressDurationInSeconds": 6700, "mediumStressDurationInSeconds": 4350, "highStressDurationInSeconds": 108000, "stressQualifier": "stressful_awake", "stepsGoal": 4500, "netKilocaloriesGoal": 2010, "intensityDurationGoalInSeconds": 1500, "floorsClimbedGoal": 18
}

And that’s all there is to it, really (at least from a developer’s point of view). Happy coding! 

If you are interested in finding out how we can help unleash a new wave of growth for your company with the smart use of technology, contact us via our website.

Tech

Get Hooked on React Hooks

A handy primer on React Hooks / React Hooks is what happens when you bring a cannon to a knife fight

A little over a year ago, React 16.8 shipped with an additional API that lets developers use state and other features in React without writing a class. Known as ‘Hooks’, this additional API has grown in popularity amongst developers, and is now a common feature in everything from open-sourced applications to enterprise apps.

Crucially though, React hooks are completely opt-in, which means there is no need to rewrite existing code. Hooks are also 100% backward compatible and don’t contain any breaking changes.

Why Use React Hooks?

Hooks were developed with the intention of solving a range of seemingly unconnected problems, which were hampering the evolution of React—a language that is not yet a decade old.

Hooks make it possible to:

  • Reuse stateful logic between components
    Hooks allow you to reuse logic between components without changing their architecture or structure.
  • Understand components easily
    When components become larger and carry out many operations, they become increasingly difficult to understand. Hooks solve this problem by allowing developers to separate a given component into various smaller functions which are related to each other.
  • Navigate classes (without tearing your hair out)
    To the novice, Classes in React can become quite confusing. To complicate matters further, computers also tend to get confused by Functions and Classes. For instance, minifiers/unglifiers don’t play well with Classes and can cause problems. With Hooks, developers can use more of React’s features without opting for Classes. This makes sense because when you really think about it, React components have always been conceptually similar to functions. In essence, Hooks embrace functions without discarding everything that is great about React.

Before going any further, there are two main ‘rules’ that need to be kept in mind.

  • Make sure to not use Hooks inside loops, conditions, or nested functions;
  • Only use Hooks from inside React Functions.

The Different Types of Hooks

React 16.8 ships with 10 in-built hooks, but the most basic and commonly used ones are:

useState()

The useState() hook allows developers to update, handle and manipulate state inside functional components without needing to convert it to a class component.

useEffect()

The useEffect() hook accepts a function that would contain effectual code. In functional components, effects like mutations, subscriptions, timers, logging, and other effects are not allowed to be placed inside a functional component. Doing so would lead to a lot of bugs and inconsistencies when the UI is rendered.

When useEffect() hook is deployed, the effectual function passed into it will execute right after the render has been displayed on the screen. By default, effects are executed after the render has been completed, but you can also execute them when certain values change. 

useContext()

The useContext() hook accepts a context object, i.e. a value that is returned from React.createContext, and then returns the current context value as appropriate.

Prior to the introduction of the useContext hook, developers would need to set up a contextType or a to access the global state passed down from a provider in a class component.

useRef()

The useRef hook is a function that returns a mutable ref object whose .current property is initialized with the passed argument (initialValue). The returned object will persist for the full lifetime of the component.

Experienced developers will recognise the useRef hook as something that is used to access DOM nodes or React elements. However, it can also be used to keep any mutable value around similar to how you would use instance fields in classes.

Before vs. After: A Code Example

In order to demonstrate how effective Hooks can be, let’s try to build a simple counter. If we were to use Classes, this is how the code would look:

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }
  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}

But, if we were to rewrite this using Hooks, this is how it would look:

 import React, { useState } from 'react';
 
  function Example() {
     const [count, setCount] = useState(0);
 
     return (
      <div>
        <p>You clicked {count} times</p>
        <button onClick={() => setCount(count + 1)}>
         Click me
       </button>
      </div>
    );
  }

Note the following:

  • Line 1: The useState Hook from React is imported. It lets us keep the local state in a function component.
  • Line 4: Inside the Example component, a new state variable is declared by calling the useState Hook. It returns a pair of values, to which names can be given. We’ve called our variable count because it holds the number of button clicks. We initialize it to zero by passing 0 as the only useState argument. The second returned item is itself a function. It lets us update the count so we’ve named it setCount.
  • Line 9: When the user clicks, we call setCount with a new value. React will then render the Example component again, passing the new count value to it.

Bringing It All Together

Here is a little tutorial on how to implement a few basic hooks. In order to illustrate how each hook can be used, we will be attempting to build a small app within React.

import React, { useState, useRef, useEffect } from "react";
export default function Alarm(props) {
 let snooze = 600;
  const intervalRef = useRef();
  const [alarm, setAlarm] = useState(props.alarmInSec);
  useEffect(() => {
    const id = setInterval(function () {
      setAlarm(alarm => alarm - 1);
    }, 1000);
    intervalRef.current = id;
    return () => {
      clearInterval(intervalRef.current);
    }
  }, []);
  return (
    <div>
      <p>{new Date(alarm * 1000).toISOString().substr(11, 8)}</p>
      <button onClick={() => setAlarm(alarm + snooze)}>
        SNOOZE ALARM
         </button>
    </div>
  );
}

Done! You, young padawan, are now on your way to becoming a great React ninja. Congratulations!