三、HomeKit之Homes的创建和Accessories的添
HomeKit对象被保存在可以共享的HomeKit数据库中,通过HomeKit框架该数据库可以被多个应用进行访问。HomeKit调用方法都是异步的,这些方法都有完成异步时回调方法。如果方法调用成功,应用在回调中更新本地对象。应用程序启动时,HomeKit对象不能收到代理信息,只能在回调函数中得到信息。
当其他应用程序启动时HomeKit时,想了解HomeKit对象的变化,请参阅Observing HomeKit Database Changes,查阅异步消息完成处理后传过来的错误码的信息,请参阅HomeKit Constants Reference
一、对象命名规则
HomeKit对象的命名要能够Siri识别,如下是给HomeKit 对象命名的几点原则:
- 在命名空间中,HomeKit名字要唯一
- 用户中所有的home名字都在同一个命名空间内。
- home对象和它包含的对象在不同的命名空间中
- 名字只能包含数字、字母、空格以及省略号字符。
- 名字必须以数字或者字母字符开始。
- 在名字中空格或者省略号是忽略的(例如home1和home 1 同一个名字)。
- 名字没有大小写之分。
如果想了解用户可以使用哪些语言与Siri进行交互,请参阅 HomeKit User Interface Guidelines文档中的"Siri Integration"。
二、创建Homes
在HMHomeManager类中增加home对象,是用addHomeWithName:completionHandler: 异步方法。home对象的名字是作为方法参数时,必须要唯一,而且Home对象的名字能被Siri识别。
[self.homeManager addHomeWithName:@"My Home" completionHandler:^(HMHome *home, NSError *error) {
if (error != nil) {
// Failed to add a home
} else {
// Successfully added a home
}
}];
在else语句中,更新应用的视图。如果想要得到 home manager对象,请阅读Getting the Home Manager Object
三、在Home对象中增加Room对象
home对象使用addRoomWithName:completionHandler: 异步方法可以添加room对象。room的名字作为方法的参数,必须是唯一独特的,并且Siri能够识别room的名字。
NSString *roomName = @"Living Room";
[home addRoomWithName:roomName completionHandler:^(HMRoom *room, NSError *error) {
if (error != nil) {
// Failed to add a room to a home
} else {
// Successfully added a room to a home
}
}];
在else语句中,更新应用的视图。
四、得到智能电器
智能电器封装了物理电器的状态,因此它不能被用户创建。为了允许用户给他们home增加智能电器,HMAccessoryBrowser发现没有和home关联的智能电器。HMAccessoryBrower对象在后台搜寻没有和home关联的智能电器,当它找到该智能电器的时,使用代理来通知应用程序。只有在startSearchingForNewAccessories方法调用之后或者stopSearchingForNewAcce-ssories方法调用之前,HMAccessoryBrowserDelegate消息才被发送给代理对象。
发现home中的智能电器
1 增加accessory browser 代理协议和accessory browser 属性
@interface EditHomeViewController () <HMAccessoryBrowserDelegate>
@property HMAccessoryBrowser *accessoryBrowser;
@end
2 创建accessory browser对象,并设置它的代理
self.accessoryBrowser = [[HMAccessoryBrowser alloc] init];
self.accessoryBrowser.delegate = self;
3 开始搜索accessories
[self.accessoryBrowser startSearchingForNewAccessories];
4 将找到的accessories添加到收藏中
- (void)accessoryBrowser:(HMAccessoryBrowser *)browser didFindNewAccessory:(HMAccessory *)accessory {
// Update the UI per the new accessory; for example, reload a picker view.
[self.accessoryPicker reloadAllComponents];
}
写代码在accessoryBrowser:didFindNewAccessory:方法中。 用accessoryBrowser:didRemov-eNewAccessory: 方法来移除accessories,这些accessories对于应用的视图或者收藏来说不再是新accessories。
5 停止搜寻accessories
如果一个视图控制器正在开始搜寻配件,通过重写viewWillDisappear:方法来停止搜寻accessories。代码如下:
- (void)viewWillDisappear:(BOOL)animated {
[self.accessoryBrowser stopSearchingForNewAccessories];
}
注意
在WiFi网络环境下,为了安全地获取新的并且能够被HomeKit发现的无线配件,请参阅External Accessory Framework Reference.
五、Home和room添加Accessory
Accessories属于home,并且它可以被添加到home中的任意room中,使用addAccessory:completionHandler:异步方法为home添加Accessories。Accessories的名字作为方法的参数,所以配件所属的home中必须是唯一的。使用assignAccessory:toRoom:-completionHandler: 异步方法给home中room添加Accessories。roomForEntireHome这个方法返回值room是Accessories默认的room
// Add an accesory to a home and a room
// 1. Get the home and room objects for the completion handlers.
__block HMHome *home = self.home;
__block HMRoom *room = roomInHome;
// 2. Add the accessory to the home
[home addAccessory:accessory completionHandler:^(NSError *error) {
if (error) {
// Failed to add accessory to home
} else {
if (accessory.room != room) {
// 3. If successfully, add the accessory to the room
[home assignAccessory:accessory toRoom:room completionHandler:^(NSError *error) {
if (error) {
// Failed to add accessory to room
}
}];
}
}
}];
Accessory能够提供一项或者多项服务,这些服务的特性是由制造商定义。想了解Accessory的服务和特性,请参阅 Accessing Services and Characteristics。
六、修改Accessories名字
使用updateName:completionHandler: 异步方法可以改变Accessories名称,代码如
下:
[accessory updateName:@"Kid's Night Light" completionHandler:^(NSError *error) {
if (error) {
// Failed to change the name
} else {
// Successfully changed the name
}
}];
七、Homes和Room添加Bridge(桥接口)
桥接口是一个特殊的accessory,允许可以与其他的accessory交流,但是不能直接和HomeKit交流。例如,桥接口可能是控制多个灯的枢纽,它是用是communication protocol协议而不是HomeKit Accessory Protocol协议,为了给home增加桥接口,按照Adding Accessories to Homes and Rooms中所描述的步骤来操作。当home增加桥接口,在桥接口底层的accessories也会被添加到home中。每次修改通知设计模,home的代理不会接收到桥接口的home:did-AddAccessory: 代理消息,而是接收一个有关于accessory 的home:didAddAcces-sory:代理消息。在home中,要把桥接口后的配件和任何类型的配件看成一样的--例如,把它们加入配件列表的配置表中。相反的是,当你给room增添一个桥接口时,这个桥接口底层的配件并不会自动地添加到room中,原因是桥接口和它的的配件可以位于到不同的room中。
八、分区
分区 (HMZone) 是任意可选的房间(rooms)分组;例如楼上、楼下或者卧室。房间可以被添加到一个或者多个区域。
Snip20170322_19.png
用addZoneWithName:completionHandler: 异步方法创建分区。分区的名称作为方法的参数,在home中必须是唯一的,并且应该能被Siri识别。
__block HMHome *home = self.home;
NSString *zoneName = @"Upstairs";
[home addZoneWithName:zoneName completionHandler:^(HMZone *zone, NSError *error) {
if (error) {
// Failed to create zone
} else {
// Successfully created zone, now add the rooms
}
}];
用addRoom:completionHandler:异步方法给分区添加room,代码如下:
__block HMRoom *room = roomInHome;
[zone addRoom:room completionHandler:^(NSError *error) {
if (error) {
// Failed to add room to zone
} else {
// Successfully added room to zone
}
}];