I am working on an app for a Home automation device built on Matter. There are both standard and custom features/services/clusters on this device. HomeKit seems to pick up the standard ones except for one (leak detector) that is part of the Matter 1.3 spec. Of course HomeKit doesn't know what to do with the custom ones so they aren't shown in the Home app. I am trying to access those directly via calls to the Matter APIs so I can present them in a custom app. To access Matter APIs I am using a process suggested by DTS in a forum post that can be found here.
The MTRBaseDevice I obtain in the suggested way responds appropriately to read and write commands, but subscribe doesn't work as expected. It returns an error code 48 which is described as "The operation couldn’t be completed." and the source that contains the error calls it "operationNotSupported". This is the subscribe call referenced in the DTS response to earlier post, however there are three more "subscribe" methods and I have tried them all. Two also return an error 48, and the last one never calls any of the callback handlers providing no data or errors.
Since a subscription is supposed to return data periodically even when there have been no changes it doesn't seem that different than polling so I have written code for that and it works. However I don't expect iOS will let me poll in the background for alarm conditions and I am hoping subscription updates will be sent to a background app so it can notify users of these conditions. Is that a reasonable assumption?
Here is the code I am using to test subscribe, perhaps I am doing something wrong? Originally I had shorter intervals but changing them made no difference. Do they need to be longer?
let subscribeParams = MTRSubscribeParams(minInterval: 15, maxInterval: 900)
if #available(iOS 17.6, *) {
subscribeParams.shouldAssumeUnknownAttributesReportable = true
}
subscribeParams.shouldFilterByFabric = false
subscribeParams.shouldReplaceExistingSubscriptions = true
subscribeParams.shouldReportEventsUrgently = true
subscribeParams.shouldResubscribeAutomatically = false
print("Attempting subscribe:with")
let localClusterStateCache = MTRClusterStateCacheContainer()
matterBaseDevice.subscribe(with: OS_dispatch_queue_global.global(), params: subscribeParams, clusterStateCacheContainer: localClusterStateCache) { (attributes: [Any]) in
print("subscribe:with attributeHandler: \(attributes)")
} eventReportHandler: { (events: [Any]) in
print("subscribe:with eventHandler: \(events)")
} errorHandler: { (error: any Error) in
let reportingError = error as NSError
if reportingError.domain == "HMErrorDomain" {
let hkError = HMError(HMError.Code(rawValue: reportingError.code)!)
print("subscribe:with errorHandler: \(hkError.localizedDescription); UserInfo: \(hkError.userInfo); ErrorUserInfo: \(hkError.errorUserInfo)")
} else {
print("subscribe:with errorHandler: \(reportingError)")
}
} subscriptionEstablished: {
print("subscribe:with Subscription established!!!")
} resubscriptionScheduled: { (error: any Error, numericParam: NSNumber) in
print("subscribe:with Resubscription scheduled; error: \(error); numericParam: \(numericParam)")
}