During a test run of my HomeKit application in Xcode, after some time the app did run smoothly, I've started for one characteristic to get a pretty weird error in the readValueWithCompletionHandler: callback block:
Error Domain=HMErrorDomain Code=80 "Missing entitlement for API." UserInfo={NSLocalizedFailureReason=Handler does not support background access, NSLocalizedDescription=Missing entitlement for API.}
The application was launched just a couple of hours ago and the profile is still OK (though it will expire very inconveniently soon):
1044 ocs /tmp> security cms -D -i /Users/ocs/Library/Developer/Xcode/DerivedData/HomeObserverNA-hkazqlfbeuucvybpdzdgosyhhxnx/Build/Products/Debug-maccatalyst/HomeObserverNA.app/Contents/embedded.provisionprofile -o /tmp/ppp.plist
1045 ocs /tmp> plutil -extract ExpirationDate raw -o - /tmp/ppp.plist
2026-10-15T14:04:02Z
1046 ocs /tmp>
Note please that immediately after launch (and for some time after that) the value was read in through the same code without any problem.
Strangely enough, when I've switched the device through the Home application,
- I've got the update planned through
enableNotification:completionHandler:all right. - and the error stopped occurring,
readValueWithCompletionHandler:from that moment on again works as presumed.
How can I fix the problem, what's wrong in my app? Thanks!
During a test run of my HomeKit application in Xcode, after some time the app did run smoothly, I've started for one characteristic to get a pretty weird error in the readValueWithCompletionHandler: callback block:
Let me start with the messages here:
"Handler does not support background access"
...
"Missing entitlement for API."
That error and the entitlement it references are a leftover artifact from the Apple Watch's initial release, not a "real" entitlement we actually grant/use. Very early in watchOS 2.0’s development, an entitlement WAS created and integrated into the framework so that watchOS extensions (which run "in the background") running on the iPhone could control HomeKit. However, very early in the pre-release development testing process, it became clear that there were so many other "foreground only" edge cases that it was better to simply "lie" to the extension (so our frameworks considered it "foreground") instead of trying to sort out all of those edge cases.
That made the HomeKit entitlement unnecessary, but there wasn't any reason to remove the existing code, so it was left in place, referencing an entitlement that we've never granted to any developer and probably never will.
That leads back to the error itself. Is our app in the background when it happens? If so, then the answer is "don't do that". HomeKit background access isn't supported [1].
Note please that immediately after launch (and for some time after that) the value was read in through the same code without any problem.
SO, there are three cases here:
-
If you're in the foreground, the API works fine.
-
Immediately after an app enters the background, the system continues to treat it as "foreground" for "awhile.” That might seem strange, but the problem here is that an API like Metal isn't something an app can just "stop" using. Preventing an app from freeing up Metal resources because it's "in the background" is counterproductive, so the system continues treating the app as "foreground" despite the fact it’s in the background.
-
If you're running in the debugger, the system’s behavior can get "weird.” The debugger disables normal app suspensions as well as other things like the main thread watchdog, but that can create unexpected side effects in other places. For example, many daemon's rely on process assertion expiration to trigger behaviors you're normally associated with "entering the background,” but expiration only occurs if/when your app is actually eligible to suspend, so they don't fire. Further complicating things, most of those cases aren't even bugs, as things like the "audio" background category rely on them.
Strangely enough, when I've switched the device through the Home application,
The background restriction is tied to your ability to send commands "into" HomeKit, NOT HomeKit's ability to interact with your app. Things like notifications that you've set up before entering the background may continue to work, particularly if you're dealing with #3.
[1] Why that is the case is a question I'm happy to answer if you're curious, but it's almost dinner time and I should finish up.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware