Blog
Engineering notes from building things.
Write-ups of problems worth writing up — undocumented platform behavior, hardware that talks back, geometry that looks fine and won't print, and bugs whose real cause was three layers away from the symptom. RSS.
-
isPictureInPicturePossible was true and PiP still wouldn't start
startPictureInPicture()returned nothing, no window appeared, and the flag said it should have. The error was real and was arriving in the one delegate method I had never implemented:AVKitErrorDomain -1001. Every search result blames the scene's activation state. Mine was foreground the whole time — AVKit will not start Picture in Picture for a player layer that is not on screen, and a layer in another tab counts. -
Picture in Picture kept freezing, and it was the audio session
Thirteen changes on the video side — the player, the layer, the server, the encode, the teardown — and none of them moved a PiP window that froze within a minute of every source switch. The app held a non-mixable
AVAudioSession, and rebuilding the pipeline re-claimed it out from under whatever else was playing. Adding.mixWithOthersfixed it, and did not cost PiP on tvOS. -
Your teardown is queue.async { [weak self] }, so it might never run
A one-shot
queue.asyncthat captures[weak self]turns guaranteed cleanup into best-effort work: if the object is released before the block runs, the block does nothing and nothing says so. Fine when the cleanup only drops memory. Not fine when it hands back a hardware VideoToolbox session or an open socket. -
Watertight, on the bed, and the wrong shape
A plate printed with 4 mm tongues of material reaching into openings that should have had a 1.4 mm border, and every printability check was green. Offsetting a polygon by moving its vertices spikes at sharp corners and folds through itself at tight curves — and an even-odd fill closes a folded ring as happily as a good one, so the mesh comes out watertight, island-free and slicing clean.
-
VideoToolbox emits keyframes early, and my HLS segments came out twice as long
One segment a minute came out at double length on a real camera, and never once on synthetic test video. The max keyframe interval is a ceiling, not a schedule — encoders spend keyframes early on scene changes — and it counts the timestamps you supply rather than wall clock. Half of that is documented, on a page about a different property.
-
Your tvOS Top Shelf tile is cached, and reinstalling won't clear it
The tile drew a placeholder for hours after the code was correct again. The Home screen caches the rendered tile, dedupes incoming content against it, and on the build this was found on that cache survived uninstalling the app — only a reboot cleared it. Re-checked on the tvOS 27 release build, where a reinstall is now enough. Plus what actually works for getting logs out of a tvOS extension, and what an extension can and can't do with an App Group.
-
Why your HealthKit widget shows zero every morning
The widget was wrong every morning and right the moment I opened the app — but its timestamp was fresh, so it wasn't stale, it was freshly wrong. HealthKit's store is encrypted while the phone is locked, and a query that fails for that reason is indistinguishable from a day with no data unless you read the error.