我正在开发一个基于 HomeKit API 的演示 iOS 应用程序。
我已经使用一些服务(S1 S2 ...)为特定主页(H1)创建了场景(操作集)AS1,以便一次性执行多个操作。我可以毫无问题地创建多个场景,但我在更新任何创建的场景时遇到问题
我的申请流程:
问题:一旦我从附件 A1 选项更改了服务的特征,那么添加到场景操作的特征就会更新为相同的值。
我的假设:我认为每个创建的场景(动作集)单独维护自己的特征值,如果用户修改附件A1(从其他地方)的任何服务的特征,那么它不应该影响添加到的动作的值已保存场景(前提条件 - 用户在创建场景的操作中选择了该配件)
我将动作集(场景)更新为,
更新场景(动作集)
1.检查User是否更改了Action-set的名称,
2.如果场景(动作集)名称与旧名称相同,
这是用于填充服务 listView 的代码片段(准备数据源)
func prepareDataSource(){
var actionsArray = NSArray(array:
self.currentScene!.actions.allObjects)
for (var index = 0 ; index<actionsArray.count; index++ ){
var sWritttenAction:HMCharacteristicWriteAction? = actionsArray[index] as? HMCharacteristicWriteAction
if let sActionCharacteristic = sWritttenAction!.characteristic{
var accessoryService = sActionCharacteristic.service as HMService
if(!isServiceAlraedyAdded(accessoryService.name)){
var sceneService = DMIAccessoryService.initWithService(accessoryService)
sceneService.isSelected = true
//Add Services
self.services.append(sceneService)
self.addedServices.append(sceneService)
println("it's a different service")
}
else
{
println("Already has the same service")
}
}
}
}
我浏览了 HomeKit 文档,但没有发现与此问题相关的任何内容。
据我理解动作集的概念,它应该单独维护特征值,以便我们稍后可以更改它的动作值。
我已经在 Stack Overflow 上发布了这个问题。现在我确信这是 Apple Home api 中的一个错误,因为一旦我尝试重新执行相同的操作集(前提条件:用户从 A1 选项更改了服务特征的值)。它已成功执行并更新所有具有与创建的场景(ActionSet)相同特征的附件。
可以使用 HMActionSet 对象创建场景,
它仅公开 3 个 api,即 updateName()、addAction()、removeAction()
添加操作
addAction()用于通过使用Accessory的HMCharacteristic来改变任何Accessory使用场景的行为。该特性必须支持可以检查的
WriteAction。
[characteristic.properties containsObject:HMCharacteristicPropertyWritable]
如何加载特性
特征可以显示在表格视图中,也可以创建自定义视图。并且该特征的值可以设置为显示视图。
- (void) readValueForCharacteristic:(HMCharacteristic *)characteristic completion:(void (^)(id, NSError *))completion {
for (HMCharacteristicWriteAction *action in self.actionSet.actions) {
if ([characteristic isEqual:action.characteristic]) {
completion([self getTargetValueForCharacteristic:characteristic],nil);
return;
}
}
[characteristic readValueWithCompletionHandler:^(NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(characteristic.value, error);
});
}];
}
-(id) getTargetValueForCharacteristic:(HMCharacteristic *)characteristic {
id value;
for (HMCharacteristicWriteAction *action in self.actionSet.actions) {
if ([action.characteristic isEqual:characteristic]) {
value = action.targetValue;
}
}
return value;
}
现在可以在向场景添加特征或更新特征时在两者上设置该值。 当它检查动作是否添加到 Scene 时?然后它会从actionSet中获取值。否则它将读取该特性的当前值。
保存场景 添加场景或更新场景时相同。只需添加一个条件即可。
/** Create property */
@property (nonatomic) dispatch_group_t sceneGroup;
@property (nonatomic) NSError *error;
/** Initialize */
self.sceneGroup = dispatch_group_create();
- (void)saveActionSetWithName:(NSString *)name
completionHandler:(void (^)(NSError *error))completion {
if (self.actionSet) {
[self saveScene:self.actionSet];
[self updateNameIfRequire:name];
} else {
[self createScene:name];
}
dispatch_group_notify(self.sceneGroup, dispatch_get_main_queue(), ^{
completion(self.error);
self.error = nil;
});
}
如果场景已经创建,则将可写动作添加到 saveScene: 方法中的动作集中。还要检查场景名称是否更改,如果需要,只需使用 updateName: 方法更改名称即可。
如果未创建场景,则使用 HMHome 类的方法 addActionSetWithName 创建场景:通过使用 home 对象,在其完成块上调用
saveScene 方法,并向创建的场景添加可写操作。
您可以参考苹果的HMCatalog示例项目
如果您创建模型自定义类来管理 Actionset,那就太好了。
有什么疑问就问我吧