Tutorial for Apple

Contents

Overview

The GemSDK for iOS and OS X provides an easy way to scan and connect to Gem/s with a very short amount of code. This tutorial will focus on using the SDK with the Swift programming language, it is also possible to use the same API with Objective-C like you’d use any Objective-C written library.
The SDK is supported and tested on iOS 9.2+ and OS X 10.11+, but it might work on older versions. If you need an older version, it might be worth to try and ask about it in the forums.

Getting Started

Downloads

The GemSDK is available to download from here: GemSDK-iOS-OSX-0.1.0

Preparation

Prerequisites:

If using iOS:
* iPhone or newer models, running iOS 9.2+ (all iPhones models since S4 have Bluetooth Low-Energy support)

If using OS X:
* A Mac computer with OS X 10.11+

Setting up a project for iOS

  1. Extract the downloaded zip archive
  2. Open up XCode and create a new Single View Application by clicking on: iOS > Application > Single View Application and then click Next.

  1. Choose a name for the project, and because in this tutorial we are going to use Swift, in the language dropdown menu, select Swift.

  1. Choose a folder to save your project and click Create.

  2. Now we need to a reference to the SDK, in the project tree, select your project, choose the General and search for Embedded Binaries, drag in the extracted “GemSDK.framework” from the iOS folder and click Finish.


  1. Open up ViewController.swift and get ready to code!

Setting up a project for OS X

For OS X you can follow the same steps as noted above, with the exceptions of creating an OS X project instead of iOS in Step 2 and add the GemSDK.framework from the OSX folder instead of the iOS folder.

Scanning for Gems

The first things we have to do in order to connect to a Gem is to scan for nearby Gems, select the one we want and connect to it.

First, replace your ViewController.swift contents with this:

import UIKit
import GemSDK

class ViewController: UIViewController, GemScanDelegate, GemDelegate {

var gemManager: GemManager!
var myGem: Gem!

override func viewDidLoad() {
super.viewDidLoad()

gemManager = GemManager(delegate: self)
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

}

Let’s look at the following line in viewDidLoad:

gemManager = GemManager(delegate: self)

Here, we’re creating a new GemManager, this class that manages all the interactions with the Gems for us. (Note: each app should create only one instance of this class!)

Now we are assigning the current instance of ViewController as the delegate of GemManager, so we could handle events invoked by it. Notice how we are adopting the GemScanDelegate protocol in ViewController’s class definition, this protocol contains all the events that GemManager can generate. Now we’ll have to implement the required methods defined in GemScanDelegate, add the following functions to your code:

// Called when GemManager is ready, when we receive this callback we may start working with the GemManager class.
func onReady() {
gemManager.startScan()
NSLog("Scan has started!")
}

// Called when GemManager initialization failed, if this function gets called and not the onReady() function, do not attempt to call GemManager's functions. Try to inspect the error parameter and solve the problem first, then wait for a call to onReady().
func onInitializationError(error: InitializationError) {
switch(error)
{
case .BluetoothOff:
NSLog("BluetoothOff")
break
case .BluetoothResetting:
NSLog("BluetoothResetting")
break
case .BluetoothUnauthorized:
NSLog("BluetoothUnauthorized")
break
case .BluetoothUnknown:
NSLog("BluetoothUnknown")
break
case .BluetoothUnsupported:
NSLog("BluetoothUnsupported")
break
}
}

// Called everytime a new Gem is discovered.
func onDeviceDiscovered(gem: Gem!, rssi: NSNumber!) {
gemManager.stopScan()
gem.delegate = self
gemManager.connectGem(gem)
myGem = gem
NSLog("Gem is found! Scan stopped.")
}

Receiving data

Immediatly after a Gem is discovered we, we stop the scan, and again assinging the current instace of ViewController to be the Gem’s delegate. Notice that we are adopting the GemDelegate protocol, this protocol is has all the events a Gem can generate. We now have to add the following functions in order to conform to the GemDelegate protocol:

// Called when an error related to the Gem has fired, all the details are in NSError.
func onErrorOccurred(error: NSError!) {
NSLog("An error has occured! Details: " + error.localizedDescription)
}

//Called everytime the Gem's state changed.
func onStateChanged(state: GemState) {
switch(state)
{
case .Connected:
NSLog("The is connected!")
break
case .Connecting:
NSLog("Connecting in progress")
break
case .Disconnected:
NSLog("The gem is disconnected!")
break;
case .Disconnecting:
NSLog("Disconnecting in progress")
}
}

func onCombinedData(data: GemCombinedData!) {
NSLog("Quaternion X:%f, Y:%f, Z:%f, W:%f", data.quaternion[0].floatValue, data.quaternion[1].floatValue, data.quaternion[2].floatValue, data.quaternion[3].floatValue)
// TODO something usefull with the data!
}

That’s it! When a Gem is connected it starts to send CombinedData immediatly.

For further information about the API, you can check out the API Reference documentation.

Tap events

TODO

Pedometer

TODO

Getting raw data

TODO

Samples

Currently there are no samples available for iOS’s GemSDK.