CareKit Tutorial for iOS: Part 1

In the first part of our CareKit Tutorial for iOS, you’ll learn the basics of using CareKit by building a Zombie Training and Symptom Tracker. By Jeff Rames.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 4 of this article. Click here to view the first page.

Preparing Care Plan Data

Now you need to generate some care plan data, which will require a bit of setup. Select the Care Plan Store group in the Project Navigator and select File\New\File…, then choose the iOS\Source\Swift File template and click Next. Name the file CarePlanData.swift and click Create. In the new file, replace the template code with the following:

import CareKit

enum ActivityIdentifier: String {
  case cardio
  case limberUp = "Limber Up"
  case targetPractice = "Target Practice"
  case pulse
  case temperature
}

class CarePlanData: NSObject {
  let carePlanStore: OCKCarePlanStore
  
  init(carePlanStore: OCKCarePlanStore) {
    self.carePlanStore = carePlanStore
    
    //TODO: Define intervention activities
    
    //TODO: Define assessment activities
    
    super.init()
    
    //TODO: Add activities to store
  }
}

This code creates an enum, ActivityIdentifier, that will provide unique identifiers for intervention and assessment activities. It then defines a stubbed-out CarePlanData class which will be tasked with defining activities and adding them to the data store. Its initializer currently grabs a reference to OCKCarePlanStore for this purpose.

To initialize an OCKCarePlanActivity to define an activity, you need to provide a schedule minimally defining a start date and frequency. Add the following to CarePlanData just below the properties:

class func dailyScheduleRepeating(occurencesPerDay: UInt) -> OCKCareSchedule {
  return OCKCareSchedule.dailySchedule(withStartDate: DateComponents.firstDateOfCurrentWeek,
                                       occurrencesPerDay: occurencesPerDay)
}

This method calls the convenience initializer dailySchedule(withStartDate:occurrencesPerDay:), which creates an OCKCareSchedule with the given start date and number of daily occurrences. For the start date, you’re using NSDateComponents.firstDateOfCurrentWeek which is a computed property included with the starter project. This will generate results to cover the current week.

Intervention Activities

Now you’re ready to create some intervention activities. Replace //TODO: Define intervention activities with:

let cardioActivity = OCKCarePlanActivity(
  identifier: ActivityIdentifier.cardio.rawValue,
  groupIdentifier: nil,
  type: .intervention,
  title: "Cardio",
  text: "60 Minutes",
  tintColor: UIColor.darkOrange(),
  instructions: "Jog at a moderate pace for an hour. If there isn't an actual one, imagine a horde of zombies behind you.",
  imageURL: nil,
  schedule:CarePlanData.dailyScheduleRepeating(occurencesPerDay: 2),
  resultResettable: true,
  userInfo: nil)

let limberUpActivity = OCKCarePlanActivity(
  identifier: ActivityIdentifier.limberUp.rawValue,
  groupIdentifier: nil,
  type: .intervention,
  title: "Limber Up",
  text: "Stretch Regularly",
  tintColor: UIColor.darkOrange(),
  instructions: "Stretch and warm up muscles in your arms, legs and back before any expected burst of activity. This is especially important if, for example, you're heading down a hill to inspect a Hostess truck.",
  imageURL: nil,
  schedule: CarePlanData.dailyScheduleRepeating(occurencesPerDay: 6),
  resultResettable: true,
  userInfo: nil)

let targetPracticeActivity = OCKCarePlanActivity(
  identifier: ActivityIdentifier.targetPractice.rawValue,
  groupIdentifier: nil,
  type: .intervention,
  title: "Target Practice",
  text: nil,
  tintColor: UIColor.darkOrange(),
  instructions: "Gather some objects that frustrated you before the apocalypse, like printers and construction barriers. Keep your eyes sharp and your arm steady, and blow as many holes as you can in them for at least five minutes.",
  imageURL: nil,
  schedule: CarePlanData.dailyScheduleRepeating(occurencesPerDay: 2),
  resultResettable: true,
  userInfo: nil)

This code allocates three OCKCarePlanActivity objects of type intervention, which correlate to your Care Card. Each has a unique identifier based on your enum along with the title, instructions, tint color and schedule created with the helper. Soon you’ll be able to view where each of these fields map.

To get the activities to appear in your Care Card View Controller, add them to the store by adding the following method to the bottom of CarePlanData:

func add(activity: OCKCarePlanActivity) {
  // 1
  carePlanStore.activity(forIdentifier: activity.identifier) {
    [weak self] (success, fetchedActivity, error) in
    guard success else { return }
    guard let strongSelf = self else { return }
    // 2
    if let _ = fetchedActivity { return }
    
    // 3
    strongSelf.carePlanStore.add(activity, completion: { _ in })
  }
}

What this code does:

  1. You call activity(forIdentifier:completion:) to search the store for an activity with the given identifier. This is required to avoid inserting items with duplicate identifiers.
  2. If the fetch is successful, fetchedActivity unwraps; since there’s nothing to add, you return.
  3. If the identifier didn’t exist, you call add(_:completion:) on the store to add the activity to the carePlanStore.

Now you can use that code to add each of the activities you defined. Back in init(carePlanStore:), replace //TODO: Add activities to store with:

for activity in [cardioActivity, limberUpActivity, targetPracticeActivity] {
                  add(activity: activity)
}

This iterates through the activities you defined and adds each one to the store.

You need to initialize this data class so the process to add data to the store will begin, so head over to TabBarViewController.swift and add the following property at the top of TabBarViewController:

fileprivate let carePlanData: CarePlanData

Now add the following to init(coder:), before the call to super:

carePlanData = CarePlanData(carePlanStore: carePlanStoreManager.store)

This kicks off the initialization you wrote for CarePlanData that adds activities to the store.

Note: Hard-coding activities will likely be used in some cases, but many CareKit apps will take other routes. Plans might be generated dynamically based on responses to a guided tour or derived from curated health plans maintained on a web service.

Build and run—you’ve got yourself a zombie apocalypse training plan! Tap any bubble to fill it in, indicating you’ve completed one instance (or event) of the activity, and Care Completion updates accordingly. Tap elsewhere on the cell to see the instructions you provided for that activity.

CareKit tutorial

After a modest amount of code, mostly to seed the data source, you now have a UI that displays and updates persisted Care Card data. That’s great news for your zombie-apocalypse users!

Symptom and Measurement Tracker

Now that your users have a plan to avoid infection, it’s time to tackle symptom tracking to monitor their zombie status.

While the Care Card tracks actions taken to improve or maintain a condition, the Symptom and Measurement Tracker monitors progress. For ZombieKit, that means checking for signs of infection—or (un)death.

In TabBarViewController.swift, add the following property to the others at the top of TabBarViewController:

fileprivate var symptomTrackerViewController: OCKSymptomTrackerViewController? = nil

You’ll need a reference to the OCKSymptomTrackerViewController, as it will be used throughout this class.

In createSymptomTrackerStack(), replace:

let viewController = UIViewController()

with the following:

let viewController = OCKSymptomTrackerViewController(carePlanStore: carePlanStoreManager.store)
viewController.progressRingTintColor = UIColor.darkGreen()
symptomTrackerViewController = viewController

This initializes your OCKSymptomTrackerViewController while providing its datasource, the Care Plan Store. You also set the progressRingTintColor, which optionally colors the progress indicator. Finally, you store the reference in symptomTrackerViewController for use elsewhere.

Build and run, and check out the Symptom Tracker tab. Similarly to the Care Card, you’ll see a weekly and detail progress indicator, currently set to 100% due to your lack of activities.

CareKit tutorial