vcan / Beats

Heart Rate app, testing out Core Bluetooth

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Beats

A heart rate app for iOS for stationary workouts (treadmill, circuit classes, etc.). Built because I couldn't find a nicely designed, simple heart rate tracker for workouts that didn't involved tracking distance rather than time.

screenshot

Currently tested and compatible with:

  • Polar H7 Heart Rate Monitor
  • More to follow ...

Technology

  • Swift 2
  • Xcode 7
  • XCTest
  • UITesting
  • Core Bluetooth

One of the biggest technical challenges so far has been creating a mock version of the Core Bluetooth API, made particularly difficult as key objects have no public initializers.

Designed using Sketch.

To Do

For full development roadmap, head over to the project board Trello.

Future plans and features include:

  • Record workout
  • Save workout
  • Display workout on scrolling graph
  • Pull HeartRateKit out into a framework
  • Personalised heart rate zones

Resources

Code Snippet

A helper method to run asynchronous tests on methods that don't have a closure in the argument. The only example code for XCTestExpectation was for networking code, like this from Big Nerd Ranch, but I need to test CoreBluetooth methods which did not include a completionHandler in the method signature. In order to avoid altering the CoreBluetooth code purely for testing purposes I wrote this asyncTest function which is used throughout my tests.

extension XCTestCase {

    func asyncTest(completion: () -> Void, wait: Int64){
        let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), wait * Int64(NSEC_PER_SEC))

        dispatch_after(time, dispatch_get_main_queue()) {
            completion()
        }
    }

}

Example usage:

func testReceivesUpdatesOnHeartRate() {
    weak var expectation = expectationWithDescription("Should see a pulse")

    let completion = { () -> Void in
        XCTAssertTrue(self.mockBluetoothController.hrNotificationReceived)
        expectation?.fulfill()
    }

    mockPeripheral.setHeartRateMode(.SteadyResting)
    asyncTest(completion, wait: 5)

    waitForExpectationsWithTimeout(5.5, handler: nil)
}

About

Heart Rate app, testing out Core Bluetooth


Languages

Language:Swift 100.0%