Code Your Smart Home with Apple HomeKit

The smart home is no longer the stuff of science fiction, and Apple is hoping its HomeKit will be the brains behind it. HomeKit is an iOS 8  framework for communicating with and controlling connected accessories in a user’s home. ProgrammableWeb has been putting HomeKit through its paces, including working with the HomeKit Simulator. In this article, we will show you how to create a project using the XCode IDE, as well as recommend some methods you can take advantage of right away.

First of all, you need to download the HomeKit.framework.

During the initial run-through, the user will receive a prompt asking for permission for HomeKit to access accessory data. Here, using the settingst we created using the HomeKit Simulator, we allowed for the possibility that the user may not grant permissions.

CatFeeder Permission

We next created a TableViewController to list all the homes (locations) that are already registered to work with in the iCloud account.The UIViewController subclass must conform to HMHomeManagerDelegate, which we will associate with an instance of HMHomeManager. To get a list of homes, we accessed the instance object HMHomeManager’s property, a listing of homes that can be used to set up the tableview delegate and datasource, starting with the count for number of rows.

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->UITableViewCell {
...

let home = homeManager.homes[indexPath.row] as HMHome

cell.textLabel.text = home.name
return cell
}

We updated our listing object through one of the HMHomeManager delegates. This method gets called in response to a state change in the user’s list of registered homes, changing the state from uknown to known. Update your view list of houses within this method.We could just as easily add a new home and associate it with the user with the addHomeWithName method.

homeManager.addHomeWithName(name, completionHandler: {[weak self] (home: HMHome!, error: NSError!) in
  let strongSelf = self!
  if error != nil{
    println("We got an error \(error)\")
  } else {
    //we succesfully added a new home by name
  }

})

Within each home there are rooms, and, just as we iterated through the list of homes, we can iterate through all the rooms in a home.

let room = home.rooms[indexPath.row] as HMRoom
...
cell.textLabel.text = room.name

The process for adding rooms to a home is similar to adding a new home. Using the addRoomWithName:completionHandler: method of homeManager, while listening via the HMHomeDelegate delegate method for changes to the number of rooms in a specific home. For that, we would use the delegate method home:didAddRoom:.

...
home.addRoomWithName(textField.text, completionHandler: {[weak self]
(room: HMRoom!, error: NSError!) in
let strongSelf = self!   
if error != nil{
  println("We got an error: \(error)")
} else {
  //we sucessfully added a new room
}
})

Finding, Interacting with HomeKit Accessories

During tests, when an iOS-based device was in the same network as the accessories for a particular home, we could interact with the accessories using the HMAccessoryBrowser class, along with the associative delegate in the view controller.

To prompt the accessory browser object to discover new accessories that are reachable via the network, use the startSearchingForNewAccessories: method of HMAccessoryBrowser class. The discovery results are then presented in the HMAccessoryBrowserDelegate methods accessoryBrowser:didFindNewAccessory: (for devices that are successfully reachable) and accessoryBrowser:didRemoveNewAccessory: (for any device that is not reachable or that has already been added to the home list).

func accessoryBrowser(browser: HMAccessoryBrowser!, didFindNewAccessory accessory: HMAccessory!) {
println("Accessory found")
home.addAccessory(accessory, completionHandler: {[weak self]
  (error: NSError!) in
  let strongSelf = self!
  if error != nil{
    println("Error adding accessory, with reason being \(error)")
  } else {
    println("Added the accessory to home as part of user account")
    strongSelf.home.assignAccessory(accessory,toRoom: strongSelf.room,
      completionHandler: {(error: NSError!) in
        if error != nil{
    println("Error assigning accessory to room, with reason being \(error)")
        } else {
          println("Successfully assigned accessory to room")
          strongSelf.findServicesByAccessory(accessory)
        }
      })
  }

Once we added the accessory, we could look up the services it exposes, as well as characteristics.

Go Forth and Make Homes Smarter

func findServicesByAccessory(accessory: HMAccessory){
for service in accessory.services as [HMService]{
  println(" Service found \(service.name) \(service.serviceType)"  )
  getServiceCharacteristics(service)
}
}

func getServiceCharacteristics(service: HMService){
 for serviceCharacteristic in service.characteristics as [HMCharacteristic]{
   println("Characteristic Type is \(serviceCharacteristic.characteristicType)")
  }
}

Hopefully, we have whetted your smart home appetite by giving you a glimpse of what Apple's HomeKit is capable of. Now you can explore and innovate, especially as Apple releases new hardware and accessories (including the Apple Watch and new Apple TV). Of course, we're also likely to see a slew of third-party appliance manufacturers start to create HomeKit-compliant gadgets during the course of the next few years. Please let us know in the comments section and on ProgrammableWeb's Facebook and Twitter sites what you think Apple needs to do to take its smart home enabler to the next level.

Doron Katz A keen passion for emerging technologies, practices and methodologies, Doron embraces the vision of lean development with continuous customer development. Consultant for various startups, as a Project and Product Manager, with a mobile engineering background in iOS, and over 10 years of professional web development experience.

Comments

Comments(3)

realalien

It looks hard for new comers like me to fully grasp the code without fully runnable demo, would you please to give a download link?

doronkatz

 

Thanks for your valuable input @realalien.  We will update the post with appropriate references and sample code to download in the next day or so.  Thanks 

 

Yep

Can we get the project and source code?