The Documentation

I document my frameworks, failures, and daily builds so you can use them.

Sep 7
2026

Dots N Bars (post-1.2.1 build) — I changed the plank to start at 2 segments and grow to 3 then 4 as score crosses fixed thresholds, instead of always being 4. I also added the project’s first test target — 31 unit tests covering the new scoring and matching rules, written as plain functions so they run without SpriteKit or a simulator.

Sep 7
2026

Canopy build 9 (unreleased, pending merge) — Fixed a data-loss bug where an involuntarily interrupted recording (permission revoked mid-flight) could be silently wiped by the next tap of “Record,” and a trim-tool bug that let both handles land on the same point and save, collapsing the flight to a single point with no recovery path in the UI.

Sep 6
2026

Dots N Bars (post-1.2.1 build) — Added a drop type that matches no color currently on the plank — touching it now ends the run, and letting it fall through is the correct play. While building this I found the existing plank-drag clamp was mathematically too narrow to ever dodge a drop (its radius was smaller than the plank’s own width), so I widened it.

Sep 5
2026

Pixel Edit Lite v1.4.0 (build 12) — Sharing a sprite saved it as .com.apple.Foundation.NSItemProvider.P48iCO.png — the generic fallback name iOS assigns when a shared item has no filename of its own. I fixed it by switching from DataRepresentation to FileRepresentation, writing a real temp file first, so shares now save as PixelEdit-Sprite-8x8-2026-09-05-091600.png.

Sep 4
2026

Pixel Edit Lite v1.4.0 (build 12) — New Sprite Sheet used to wipe the sprite sheet outright behind a confirm dialog. I changed it to silently save the outgoing sheet to disk via a security-scoped bookmark before clearing, so the action needs no confirmation now and nothing is lost — the same check runs before Import and before reopening a past file too.

Sep 4
2026

Dots N Bars 1.2.1 (build 11) — A plank’s 4 segments are always distinct colors, so a drop landing exactly on a segment boundary always touches one matching and one non-matching segment in the same physics step, and SpriteKit doesn’t guarantee delivery order between them. If the matching contact happened to be processed first, the mismatch was silently dropped and the drop scored instead of ending the run. Fixed by deferring the outcome to didSimulatePhysics(), which runs once per step after every contact has been delivered, so a same-step mismatch always wins regardless of order.

Sep 4
2026

Pixel Edit Lite v1.3.2 (build 11) — Added VoiceOver labels across the toolbar and menu chrome. The one non-trivial part was the Shape tool’s long-press (toggles filled/outlined) — VoiceOver’s standard double-tap activation can’t trigger a long-press, so I exposed it separately as a named accessibility action via .accessibilityAction(named:) rather than leaving that functionality unreachable for VoiceOver users.

Sep 4
2026

Dots N Bars 1.2.1 (build 10) — Found on a physical device: the red failure flash could freeze mid-fade and linger on the restart screen, tinting it red. Root cause was one node that was never tagged for the game-over cleanup sweep that removes transient effects — the cleanup logic itself was correct, this one node was just missed.

Sep 4
2026

Canopy (build 9) — Ran a full release-hardening pass ahead of App Store submission: fixed import-correctness edge cases, tightened privacy handling, and closed out the remaining App Store readiness items.

Sep 3
2026

Dots N Bars 1.2.1 (build 9) — Catch matching compared rendered fillColor between the drop and plank segment, which was only coincidentally reliable. Gave both an explicit matchColor set once at init, and backed score with a private store so a score reset can never accidentally trigger the best-score/celebration logic — true by construction instead of by 0 never exceeding the best score.

Sep 3
2026

Dots N Bars 1.2.1 (build 8) — The color palette was defined in two separate lists that could silently drift apart — adding a color to one without the other would show a “?” glyph instead of a real symbol. Centralized it into one source of truth, and replaced the start-menu title’s hardcoded character-offset coloring with self-describing (text, color) pairs so a future text edit can’t silently miscolor the wrong letters.

Sep 3
2026

Dots N Bars 1.2.1 (build 8) — applicationWillResignActive was an empty stub, so a phone call or notification pull left the game running unpaused for the full transition window. Added a NotificationCenter observer that reuses the existing pause-button logic instead of a second state machine.

Sep 3
2026

Space Jam v1.1.2 (unreleased) — Three properties (starfield, backgroundMusic, an explosion sprite) were implicitly-unwrapped optionals fed by SpriteKit’s failable initializers, so a missing or renamed asset file would force-unwrap nil and crash. I replaced them with local guard let/if let bindings that log and skip the effect instead of crashing, then added the project’s first test target — 4 XCTests locking in the enemy spawner’s dodge-lane and speed-sync guarantees.

Sep 3
2026

Dots N Bars 1.2.1 (build 8) — Neither the drop nor the plank segments set collisionBitMask, so SpriteKit was resolving a real physical collision between them on every catch in addition to the contact-test callback — when a drop’s circle overlapped two flush segments at once, the catch callback fired twice, and the second call force-unwrapped an already-nil drop and crashed. Fixed by resolving the drop from the actual contact node and setting collisionBitMask = 0 on both, since the relationship was only ever meant to be a contact test.

Sep 3
2026

Space Jam v1.1.2 (unreleased) — High scores were only written to UserDefaults at game-over, so a crash or force-quit mid-run could lose a new best score that never touched disk. I moved the write into score’s didSet, right where bestScore updates, so it persists the instant the record is broken.

Sep 3
2026

Pixel Edit Lite v1.3.1 (build 10) — Shift previously clipped: pixels pushed off one edge of a sprite were just deleted and replaced with the erase color. Checked how real PICO-8 handles this first, confirmed it wraps instead of clipping, then replaced the bounds-check-and-erase branch with modular index arithmetic so shifted pixels now reappear on the opposite edge with zero loss.

Sep 3
2026

Dots N Bars 1.2.0 (build 7) — Archived build 6 under the version string 1.2, but the App Store Connect version shell had been typed as 1.1.1 then corrected to 1.2.0 — a string mismatch that blocks attaching the build. Build numbers turned out to be permanent per bundle ID too, so build 6 couldn’t be reused once corrected; had to burn it and re-archive as build 7.

Sep 3
2026

Canopy (build 8) — Fixed an IGC midnight-UTC rollover bug where baseMidnight + timeOfDay timestamps ran backwards for any flight crossing midnight, corrupting sort order and duration. Also fixed a flight save that could fail silently with no error shown to the pilot.

Sep 2
2026

Space Jam v1.1.1 (Build 5-6) — A difficulty bump only applied its new fall speed to rows spawned after it — anything already on screen kept its old, slower velocity, so a freshly-spawned fast row could catch up to an older slow one and wall off a lane right at the transition. I extracted baseFallSpeed into a single named constant and added syncActiveEnemiesToCurrentSpeed(), called the instant the multiplier changes, so nothing on screen is ever moving at a stale speed.

Sep 2
2026

Space Jam v1.1.1 (Build 5-6) — SKPhysicsBody(texture:size:) bakes its collision shape at creation time and never re-reads .setScale() afterward, so enemy hitboxes stayed full-size even after I shrunk the sprites 0.8x to widen dodge gaps — collisions didn’t match what the player saw on screen. Fixed it by explicitly computing the scaled CGSize and passing it into the physics body constructor instead of relying on the node’s transform.

Sep 2
2026

Dots N Bars 1.2.0 — Added a live celebration — haptic, gold screen flash, particle burst, and a gold-tinted score label — that fires the instant a run’s score passes the previous best, instead of only showing it after the fact on the restart screen. First version relied on the gold flash alone, which didn’t read as distinct from a normal perfect catch on-device; added an explicit “NEW BEST!” text banner to fix that.

Aug 26
2026

Space Jam v1.1.0 (Build 3-4) — The spawner could roll all 3 lanes in a single row, which is an unwinnable state — there’s no lane left to dodge into. I rewrote it to pick 1-2 lanes per row from a shuffled array, guaranteeing at least one always stays open.

Aug 26
2026

Space Jam v1.1.0 (Build 3-4) — Pulled enemy-spawning logic out of the 250-line GameScene god object into its own EnemySpawner class and added a progressive difficulty curve (spawn interval and fall speed both ramp with score). Switched controls again, this time to split-screen tap zones, after swipe gestures proved less reliable for rapid lane changes.

Aug 26
2026

Dots N Bars 1.2.0 — The entire game mechanic is color matching with zero accommodation for colorblind players. Added a shared color-to-glyph mapping (star, triangle, square, diamond, dot, down-triangle, plus) wired into both the drop and plank-segment rendering, so the game is playable by shape alone.

Aug 25
2026

Space Jam v1.1 (pre-release) — Ripped out AdMob entirely, which meant deleting 200MB+ of vendored GoogleMobileAds/GoogleAppMeasurement/nanopb binary frameworks that had been committed directly into the repo instead of pulled via a dependency manager. Replaced tap-to-move lane switching with UISwipeGestureRecognizer-based swipe controls, and fixed the score label sitting under the status bar by anchoring it to view.safeAreaInsets.top instead of a fixed offset.

Aug 25
2026

Space Jam v1.1 (pre-release) — willMove(from:) never invalidated the spawn Timer, so leaving the scene left a zombie spawner retaining self and firing into a dead scene. I added the missing invalidate() call and swapped three hardcoded pixel coordinates (80, 190, 300) for frame.width percentages so lane positions stop breaking on non-iPhone-8 screen sizes.

Aug 23
2026

Pixel Edit Lite v1.3.0 (build 9) — Migrated flood fill, rotate, and shift off whole-buffer operations onto a bounded (origin, regionSize) window as part of moving to an always-on 128×128 sprite sheet, so editing one sprite can no longer flood-fill or rotate across the other 255 slots on the same sheet. Also replaced wiping the entire undo history on every transform with proper single-step undo, since a bounded region write can go through the same per-pixel history path as normal drawing.

Aug 21
2026

Dots N Bars 1.1 (build 5) — Tried setting the marketing version to 1.0 for a fresh release line, since the original 2020 listing had been delisted. App Store Connect rejected it outright — version 1.0 had already been approved once and Apple’s version-history lock on a bundle ID is permanent regardless of whether the listing was later removed — so reverted to 1.1.

Aug 19
2026

Pixel Edit Lite v1.2.2 (build 8) — The palette-change confirmation alert had stopped appearing. Traced it to PalettePickerView calling both the environment dismiss() action and setting its own popUp binding to false in the same tap handler — two overlapping dismissal triggers on one sheet, which was swallowing the alert that was supposed to follow. Removed the redundant dismiss() call and let the alert fire from .onDisappear once the sheet had actually finished closing.

Aug 19
2026

Dots N Bars 1.1 (build 5) — bestScore was updated in memory on a new high but never written to UserDefaults, so the displayed best score silently reverted to whatever was last saved on every relaunch. Also fixed a memory leak where the score popup’s animation sequence never called removeFromParent(), permanently leaving an invisible node in the scene graph on every single catch.

Aug 19
2026

Canopy (build 7) — Fixed the app’s accent color, which had drifted from the brand teal in Settings and icon badges.

Aug 17
2026

Pixel Edit Lite v1.2.1 (build 5) — A user reported Undo reverting strokes from several pixels back instead of the most recent one. Root cause was an unstructured Task { @MainActor in ... } wrapping every pixel write with no actual async work inside it — if the drag’s .onEnded fired before a queued write executed, that pixel landed in the next stroke’s undo entry instead of its own. Made the write path synchronous and verified with a three-tap sequence (red, blue, yellow) that each Undo now removes exactly one stroke in the right order.

Aug 13
2026

Pixel Edit Lite v1.2.0 (build 4) — Added local autosave: the app now serializes the sprite buffer to a CanvasSnapshot in Application Support when it backgrounds, and restores it on next launch. Undo/redo history is deliberately excluded from what’s saved — it was already scoped to a single session, so autosave doesn’t change that.

Aug 12
2026

Dots N Bars 1.1 (build 4) — Gravity increased by a fixed amount on every catch with no ceiling, so fall time kept shrinking indefinitely — past roughly catch 35–40 it dropped under the ~0.5s floor needed to see a drop, judge its color, and react, meaning every long run was ending from the game outrunning human reaction time rather than an actual mistake. Capped gravity at a fixed maximum so difficulty plateaus into a sustained challenge instead of a hidden wall.

Aug 12
2026

Dots N Bars 1.1 (build 4) — Fixed a plank-reachability bug I’d introduced in an earlier width change that day — clamping the plank to stay fully on-screen over-constrained its range and made the two edge segments mathematically unable to ever reach a drop spawned at certain x positions. Recentered the clamp on the drop’s actual spawn x instead, and made drop spawn position randomized rather than fixed, since a fixed spawn point made “perfect” catches trivial to memorize.

Aug 12
2026

Dots N Bars 1.1 (build 4) — Added a perfect-catch bonus: a catch within 15pt of a segment’s center now scores +2 instead of +1, with distinct visual feedback so the bonus is readable at a glance.

Aug 12
2026

Dots N Bars 1.1 (build 4) — Found that triggerGameOverFeedback()’s sound/shake/flash were being scheduled during the physics-simulation phase of a frame, one frame after update() had already paused the scene — so the feedback sat queued and paused until the player resumed, and effectively only played on resume, not on the actual failure. Fixed by splitting “detect game over” from “freeze and tear down” into two states so the scene stays unpaused for a ~0.35s feedback window first.

Aug 12
2026

Dots N Bars 1.1 (build 4) — Split the plank and drop into their own SKShapeNode subclasses (previously inlined directly in the scene) and added a real Start Menu/Pause overlay flow plus haptic feedback, replacing an old scene-transition-based game-over screen.

Aug 12
2026

Dots N Bars 1.1 (build 4) — Removed the vendored GoogleMobileAds/GoogleAppMeasurement SDK entirely, along with the arm64-simulator-exclusion workaround that existed only because of it. While auditing the code I found two real bugs: nothing stopped a new drop from spawning before the previous one was resolved (could silently orphan a drop), and the scene rendered at a fixed 375x667 with .aspectFit, letterboxing on every other screen size — switched to .resizeFill with layout-time safe-area insets so the score label also clears the notch.

Aug 12
2026

Canopy (build 7) — Reworked Replay around a real cursor/clock instead of a hacked animation loop, unified GPX/IGC/TCX import into one shared pipeline, and fixed a bug where reimporting a file created a duplicate glider instead of reusing the existing one by name.

Aug 9
2026

Canopy (build 5) — Fixed a set of unit-conversion bugs where altitude was being converted twice across several charts, then rewrote the flight-metrics engine with rolling-window algorithms and added a dedicated test suite to stop it from regressing again.

Aug 8
2026

Canopy (build 3–4) — Added a universal aviation equipment schema, hold-to-stop recording with background-tracking permissions, and a flight-trimming tool. Fixed a crash in IGCParser caused by unsafe string extraction on malformed records.

Aug 6
2026

Pixel Edit Lite v1.1.0 (build 2) — Revived the project after roughly three and a half years dormant and modernized the whole data model off ObservableObject/@Published onto Swift’s @Observable macro, plus moved the canvas from a custom rendering approach to SwiftUI’s Canvas API. Touched every core file in the app (CanvasDataModel, CanvasView, ColorPaletteView, ToolBoxView) in one pass to get it building clean on Swift 6.

Aug 6
2026

Canopy (build 3) — Rebranded the app from Zephyr to Canopy and completed the V1 launch checklist, then fixed flight-stats and site-picker bugs found right after.

Aug 3
2026

Dots N Bars 1.1 (build 2) — Fixed a GoogleMobileAds SDK linking error on simulator builds by excluding the arm64 simulator architecture. Also modernized the layout constraints, added haptic feedback, and removed several force-unwraps that could crash.

Jul 29
2026

Zephyr (pre-release) — Added CSV export, social-sharing flight snapshots, and climb-rate-colored flight paths with takeoff/landing markers on the map. Fixed a MapKit DRM bug that produced a yellow screen and an auto-record bug.

Jul 28
2026

Zephyr (pre-release) — Added IGC file import, a first onboarding flow, and a pitched 3D map camera. Also fixed a Site model initializer bug where a parameter shadowed itself and a main-thread block during TCX/IGC imports.

Jul 18
2026

Zephyr (pre-release) — Built FlightRecorderService to record a flight live via GPS instead of only importing files, and made the SwiftData models CloudKit-compliant by giving every non-optional property a default value.

Jul 14
2026

Zephyr (pre-release) — Rebuilt the flight list into a Strava-style dashboard with month grouping and search, and moved all file import/processing onto a background ModelActor so large files no longer block the UI thread.

Sep 18
2025

Zephyr (pre-release) — Added the app’s first icon. Development paused here for about ten months.

Sep 10
2025

Zephyr (pre-release) — Added a user-configurable unit system (metric/imperial) and cleaned up duplicated duration-parsing logic between the manual entry and edit forms.

Sep 1
2025

Zephyr (pre-release) — Moved file parsing off the main thread and added a progress indicator so importing a file no longer freezes the UI while it processes.

Aug 31
2025

Zephyr (pre-release) — Added 3D terrain to the map view with the flight path colored by speed, then built a full flight Replay feature on top of the same track data.

Aug 17
2025

Zephyr (pre-release) — Started the project: SwiftData models for flights, manual flight entry, and TCX file import with a map view. Added flight stats, a settings screen, and the ability to edit or delete a saved flight.

Feb 5
2023
Interval picker in SwiftUI tips

Last run on Xcode 14.2, iOS 16.2, and Swift 5.7.2 Picker View for Time Durations In my Timer app, I needed a Picker View for taking the timer interval …

Read full →
Jan 31
2023
Change Back Button Icon in Navigation Bar tips

Last Run on XCODE 14.2 / iOS 16.2 / Swift 5.7.2 Change the Back Button’s Icon If you have used the default Settings App that comes with iOS, you …

Read full →
Jan 25
2023
Flood Fill: Recursion versus Iterative Solution posts

Last Run on Python 3.11.1 Intro I have been working on a SwiftUI app to develop a Pixel Editor inspired by the simplicty of the pico8 fantasy game …

Read full →
Jan 21
2023
Dynamic Buttons to handle different app behvaior in SwiftUI tips

Last Run on XCODE 14.2 / iOS 16.2 / Swift 5.7.2 Making a Dynamic Button If you have noticed, the play button on most media players changes to pause …

Read full →
Jan 17
2023
Hello 2023 posts

Is 2023 the year I blog more frequently? I have been blogging on/off for the past decade. This is another attempt at rekindling the fire. The …

Read full →
Jan 17
2023

Space Jam v1.0 (2020 baseline) — Brought the original 2020 build under git for the first time. I had no version control history for this project before this point — everything prior lived only as local file copies.

Jan 17
2023
Making a Progress View Ring tips

Last Run on XCODE 14.2 / iOS 16.2 / Swift 5.7.2 Progress View Ring I was building a Timer app and needed a visual indicator to display the the amount …

Read full →
Aug 4
2020
Getting Component Information From Date tips

Last Run on XCODE 11.6 / Swift 5.2 Last Run on XCODE 12.0 beta 4 / Swift 5.3 Definition Calendar - A definition of the relationships between calendar …

Read full →
Jul 21
2020
Usage of CaseIterable in Swift Enum tips

Last Run on XCODE 11.6 / Swift 5.2 Definition CaseIterable is a protocol in Swift, that typically lets an enumeration to provide all of its cases as a …

Read full →
Jul 17
2020
Injecting custom behavior during editmode on a TextField in SwiftUI tips

Last Run on XCODE 11.6 / Swift 5.2 Definitions ‘TextField’ is a View provided in SwiftUI for handling user entered input into an app. As …

Read full →
Jul 15
2020
Custom View Modifiers in SwiftUI tips

Last Run on XCODE 11.6 / Swift 5.2 In SwiftUI View(s) are the building blocks of the UI. All changes to the Views are done by calling special …

Read full →
May 3
2020
User Input in Swift commandline tips

Last Run on XCODE 11.4 / Swift 5.2 If you are writing a command line tool and need user input, the readLine() function can be used for it. It returns …

Read full →
May 1
2020
Checking if a Swift String contains a certain text tips

Last Run on XCODE 11.4 / Swift 5.2 A simple way to check if a string contains a certain text is to use the method contains available to Strings. In …

Read full →
Apr 28
2020
Matching Swift Strings by Prefix or Suffix tips

Last Run on XCODE 11.4 / Swift 5.2 A simple way to check if a string starts or ends with a certain pattern is to use the method hasSuffix and …

Read full →
Apr 21
2020
Access Swift String by Index tips

Last Run on XCODE 11.4 / Swift 5.2 The swift string class does not provide the ability to get a character at a specific index because of its native …

Read full →
Apr 10
2020
How to enumerate nodes in Spritekit? tips

Last Run on XCODE 11.4 / Swift 5.2 Spritekit has a method enumerateChildNodes that searches the children of the receiving node to perform processing …

Read full →
Sep 25
2019
Select Sections From Images of Newspaper clippings, receipts etc Using Opencv and Python posts

We often take pictures of menus, receipts, and message boards etc. They are often not aligned properly. In this post, I will show you how to select …

Read full →
Sep 16
2019
Create and apply simple filters to an image using OpenCV and Python posts

In this blog post, I will show you how we can enhance our images using colored filters and add border backgrounds. Original Original w/ color filter …

Read full →
Aug 22
2019
Adding text to an image using OpenCV and Python posts

In a series of upcoming blog posts, I will be using OpenCV to manipulate images. In this post, I will be adding text to an image (below), I took of a …

Read full →
Mar 11
2019
WC implementation in Go Lang posts

Continuing the theme of exploring Go Lang, today I will be writing a simple version of the Unix utility wc that displays the number of lines, words, …

Read full →
Mar 6
2019
Exploring filesystem in golang posts

I am currently dabbling in [GoLang] go-lang and trying to get familiar with it’s syntax and style of programming. I also want to get familiar …

Read full →
Feb 28
2019
ls implementation in python3 posts

“ls” is unix utility that lists the files and directories in the current path or a user passed path. In this post we will explore how to …

Read full →
Jan 29
2012
Using Python's map() AND reduce() posts

Sum of the Squares of the first 5 numbers In this post I will try to use the map() and reduce() functions to compute the sum of the squares of the …

Read full →
Jan 7
2012
What is memoization? posts

Memoization is a computer science concept to optimize programs by avoiding computations that have already been done and to reuse it. This is achieved …

Read full →
Sep 28
2011
Traceroute implementation using scapy posts

Traceroute Traceroute is a network diagnostic utility used for displaying the path taken by a packet to it’s destination. It uses the ICMP …

Read full →
Sep 10
2011
How does DHCP work? posts

What is DHCP ? DHCP is a protocol used to provide an IP address to a device. It is also used to configure additional networking related parameters on …

Read full →
Sep 10
2011
Dropbox: LAN Sync Protocol posts

A year ago, I fired up wire shark on my home network to check out the packet flow of the DHCP process. I closed all my browser windows and other …

Read full →