为什么添加到 Home e(HMHome) 的场景(动作集)总是更新特性(HMCharacteristic)值

问题描述 投票:0回答:1

我正在开发一个基于 HomeKit API 的演示 iOS 应用程序。

我已经使用一些服务(S1 S2 ...)为特定主页(H1)创建了场景(操作集)AS1,以便一次性执行多个操作。我可以毫无问题地创建多个场景,但我在更新任何创建的场景时遇到问题

我的申请流程:

  • 显示添加的主页(ListView)
  • 单击任何主页,会出现详细信息屏幕,其中有几个选项(附件A1,房间A2,场景A3....)
  • 点击A1添加配件(可以从这里更改已添加配件的服务特征)
  • A3 有一个已添加场景(动作集)的列表以及一个用于将新场景(动作集)添加到当前主页的按钮
  • 用户可以单击任何添加的场景(动作集)来更新其动作并命名两者

问题:一旦我从附件 A1 选项更改了服务的特征,那么添加到场景操作的特征就会更新为相同的值。

我的假设:我认为每个创建的场景(动作集)单独维护自己的特征值,如果用户修改附件A1(从其他地方)的任何服务的特征,那么它不应该影响添加到的动作的值已保存场景(前提条件 - 用户在创建场景的操作中选择了该配件)

我将动作集(场景)更新为,

  • 一旦用户单击任何添加的操作集服务列表,用户可以单击任何服务来更新其特征
  • 访问当前操作集的操作
  • 访问每个动作的特征(HMCharacteristicWriteAction) 特色接入服务
  • 创建 CustomServices 实例(以跟踪其他一些信息,例如用户将该服务包含到当前操作集中等)并将其添加到数据源并避免重复
  • 用户完成值更改后,单击更新操作按钮
  • 开始更新过程

更新场景(动作集)

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)相同特征的附件。

ios swift xcode6.1 homekit
1个回答
1
投票

可以使用 HMActionSet 对象创建场景,
它仅公开 3 个 api,即 updateName()、addAction()、removeAction()

如果用户想要更改场景名称,可以使用updateName。它不应该调用任何其他 api(removeAction 或 addAction)

添加操作 addAction()用于通过使用Accessory的HMCharacteristic来改变任何Accessory使用场景的行为。该特性必须支持可以检查的
WriteAction

[characteristic.properties containsObject:HMCharacteristicPropertyWritable]

如何加载特性 特征可以显示在表格视图中,也可以创建自定义视图。并且该特征的值可以设置为显示视图。

如果当前特征已经添加到actionset中,我们需要从actionset对象的actions属性中获取值。

- (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,那就太好了。
有什么疑问就问我吧

© www.soinside.com 2019 - 2024. All rights reserved.