Mobile technologies shape the way we work out: no miracle. Tracking tools record each step of your run, map out its route; then the fitness app displays the records in charts and you gladly share all of that on the social media. Little wonder the fitness business keeps up with the trend. Dozens of wearables flooded the market in a couple of last years: virtually each with a mobile app and other digital products to support them. Literally thousands of websites and apps help you to enhance your exercises, track stats, compete, making workouts almost a game-like experience. So the biggest question for the fitness industry is not whether it should integrate more technology in the daily activities of the customers (yes, it should). Surprisingly the question is neither how to come up with a new innovative know-how. The real question for the already existing or establishing businesses is what are the tools to launch a solid, customer-oriented solution in a relatively concise period of time.
One of such tools is Apple’s HealthKit. Quick disclaimer: the goal of the article is not to make a detailed overview of this kit, but to share a few insights on subtleties of fitness app development with it. A few months ago a solution our team developed using HealthKit was finally launched. It is a mobile app for fitness startup rewarding users for their physical activities: roughly, the more distance you cover, the higher your ranking is and the more benefits you receive. So, what are the peculiarities of working with a well-established Apple tech solution? The first and foremost one is not even something particular: one just cannot take anything for granted when working with a third-party service. Even if it is developed by a tech giant like Apple. Regardless of how trivial this is, it is still worth stating, because it is often the self-obvious one disregards or simply forgets to consider.
This issue unraveled when the team was deciding on how to communicate the physical activities with the server. In our case, the client-server communication was decided to be ruled by such requirements: all necessary physical activities of the user should be communicated, the necessary physical activities are those done by a user, who is logged-in in their account, and tracked by the mobile device our application is installed in, each request that sends user’s fitness activities to the server should not be too big and should not possess data already communicated. And so we began. It was necessary to check the HealthKit methods to find out if we can use them and meet the rulings we set upon ourselves. Our assumption on work with HealthKit was the following: a user makes a certain distance, the data about this activity is processed to HealthKit, the user launches our application, the app fetches the physical activity data up to the launch time of our app, the app sends the data to the server and marks the end time of the last activity as an anchor-time, the next time the user launches our app, it will fetch data from Health app starting from the anchor-time it set previously in order not to send the same data twice, thus lightening the load on the server. It was first decided this way based on the premises that it the client-side that has access to raw Health app data, so it the client side, that should be handling the filtration of physical activity data from Health. It turned out to be partially flawed.
First, this logic would potentially exclude data from any wearable trackers (like Apple Watch). In order to get the data from a wearable, one needs to synchronize it with the Health app. But this could happen after the user launched our app, and it communicated the data from the smartphone (not from the wearable) to server, which may result in possible data loss. Imagine (or see the GIF below): you take a walk with your wearable. After the walk, you pick up your smartphone to see the new stats (for the walk) in our app. You may forget to sync your wearable device, launch our app so that it sends the activities data tracked by your smartphone and sets a new anchor-time for the next synchronization. Then you actually sync the wearable and launch our app. But the app is going to fetch activities data from health starting from the newly set anchor-time, thus the activities tracked by the wearable will be lost.
This is grossly bad: quite a lot of people interested in their health wellness do use wearables. It is also quite possible that from time to time they would sync the data from the wearable with HealthKit not instantaneously after, say, walk or run due to any reason imaginable. It is obvious our goal is not to make users learn how they can securely sync their activities data with our app. Almost no one would use the fitness/entertainment app that implicates complications or strict course of actions for the user. That is quite naïve to assume otherwise. Being frank: it is wishful thinking. Our job is to adjust the app’s work to user’s behavior in a real world and to the givens of the tech stack our app utilizes so that user receives the maximum result (seeing their activities stats) with no or little effort (just by launching our app). Second, this logic was partially incompatible with how the HealthKit actually provides the user’s activity data. Three things: activities become available to fetch after not-set time period user stopped e.g. running, some activities become available to fetch earlier than others, activities that become available earlier than other not necessarily occur earlier in real life. From our perspective, it would mean the same potential result as with the wearables: loss of data. The app might communicate the latest activities available in HealthKit, set a new anchor-time. But after a little while, the activities occurred before the new anchor-time become available and will be lost.
Having those two risks mind, the team decided to revise the initial rules that were set. It was decided to include the data from the wearables as the data necessary to communicate with the server. Second, it was decided to set an anchor-time much less frequent. The new anchor-time would be set only if the current one was set the day before the day on which user launches the app or earlier. It gives time both for the user to sync their wearables with HealthKit and for the HealthKit itself to make the data stored in it available for fetching. Third, it was decided that to forgo the rule, that the app does not send to the server the data already communicated. This implicated the server to handle the break-down of activities data for the whole day to separate activities. The precision of the time period of a separate activity depleted, but the user’s activity data was now communicated with the server securely.
Another tricky piece of info. One actually can track flights user has done during this or that activity. Very roughly: a flight here represent a set distance user has made on an inclined plane as opposed to the distance covered on a flat surface. But that can be done only on iPhone 6 and higher. Previous models simply do not have the barometer device to track the flights. A few solutions for the issue were brought up, but all of them were very cumbersome, quite assumptive and implied unnecessary if-checks on the backend. The team came up with the suggestion: since the iOS devices with no barometer would cease to be used, the fitness startup may be wise to prioritize the newer devices over the older ones, with no barometer. The client gave credence to team’s judgment that the additional development for the devices with no barometer would be, formally speaking, cost prohibitive. And the solution was left as it was.
One of the team’s arguments was connected with Android development. There is no way to track flights on most Android devices. Google Fitness API does not provide the data for the flights simply. This brings us to the point worth mentioning: the core requirements for both platforms development will be for the most part identical, but the possibilities tech stack to implement them will vary. Same features will vary in their implementation on different platforms too. For instance, both the Health app and Google Fitness API would ask a user to grant their permissions to track the activities data. Google do that in a robust and very obvious way: the user just needs to login to the Google Account present on the device. But Apple would show the user a permissions screen with multiple toggles and possibility to switch them on/off. To go to the app user would need to tap either “Don’t allow” or “Allow”. The real record shows that this screen is actually the most complicated one of the entire app. It must be said that there users, who tap “Do not allow” and then struggle to understand why our app does not show them anything. That is normal. It is also worth mentioning that some users switch on one toggle and then tap “Allow”, which is not enough for our app working correctly. But that is normal too.
What is odd is the response of HealthKit when our app tries to fetch the activities data from Health. If a user really does not have any activities, the response is figuratively “null”. But when the user does have the real activities record, but the permissions are not granted the response is the same “null”. So our simply cannot tell if the user does not do physical activities with the device on them or it is simply the permissions, which are not granted. The crux of the biscuit is that if “Write” permissions are not granted, our app actually will be notified specifically about that. But it does not work for the “Read” permissions, which are those, our app needs only. So, since the documentation did not bare a trace of how the issue can be resolved, the team decided to utilize an assumptive approach here. If HealthKit returns “null”, when our app tries to fetch activities data for more than a certain amount of time, we make an assumption this is something to do with the permissions and show a user a custom alert, in which ask them to go and check if the permissions are granted. Yes, that is assumptive and speculative, but still better than nothing. With all that said, it is still apparent that development with tools like HealthKit or Google Fitness API the sport or health app development is still much more cost-efficient, quick and quality than the custom development of tools that attempt to communicate with the device’s hardware. Despite the issues and, frankly, bugs of established solution like HealthKit, they have been calibrated and tested and continue to do so. One can still rely on the quite high accuracy of their data. And that is even without mentioning the variety of fitness and health data they provide: from distances, steps, flights to nutrition plans and menstrual cycle, etc. only expands. With that expansion, the possibilities of the business to engage with their customers also broadens. You can create a mobile app, where people will challenge each other for runs, making it in a competitive way. Thus creating a gamified social network, where people actually compete in objective reality but show off in the virtual one. You can develop an app, where the users’ efforts will be converted to a certain gaming point or internal currency and have a shop, where items are sold for that currency. Possibilities are limitless. Well, the only limit is the tech feasibility as always.