"Three times in one day the obvious guess about Foundation was backwards. Each time, measuring cost a ten-line script."
Swift Strings Compare Meaning, Files Compare Bytes
Swift's String == uses Unicode canonical equivalence. The Korean word 한글 written precomposed (NFC, 6 UTF-8 bytes) and decomposed into jamo (NFD, 18 bytes) are equal Strings. That is lovely for comparing text a person typed, and dangerous the moment a string is on its way to becoming a filename, a hash input or a dictionary key the file system will see. macOS can hand you a decomposed name from a directory listing while the text field hands you a composed one; hash both and a note grows two sidecar folders with half its history in each. Nothing errors. A family editor porting a filename-key function from Rust learned this when its own "these must differ" test failed — in Swift they compare equal. Normalize explicitly (precomposedStringWithCanonicalMapping is NFC) and compare utf8 bytes when bytes are what matter.
Two Valid Spellings of One Moment
A web client stamped captures as 2026-09-10T12:17:29+09:00. A native client stamped 2026-09-10T10:45:13.146Z. Both are correct ISO 8601. The list sorted the raw strings, so a capture from 19:45 local time sank below one from 12:17, and the newest entry — the entire point of a capture app — looked like it never arrived. Parse to Date before comparing, and know that one ISO8601DateFormatter configured with fractional seconds refuses the plain form and vice versa, so try both. Sort anything unparseable to the bottom on purpose, so a bad timestamp cannot pose as the newest row.
A related trap: a location fix's timestamp is an instant in UTC, while a capture's own time carries the wall-clock offset a person lives in. A label built from the fix read "13:25" for something the screen elsewhere called "22:25". Two fields, two jobs — render the one a human means.
Invisible Characters and Empty-but-Present Data
- Dictation can leave U+FFFC behind. Dictating into a SwiftUI
TextField(axis: .vertical)on iOS left an OBJECT REPLACEMENT CHARACTER at the front of the bound string. A language model on the other end read it as an image placeholder and went hunting for an attachment. Strip U+FFF9 through U+FFFC from text that leaves the device. - "Available" is not "present". A pasteboard item that promises a PNG answers
data(forType:)with 0 bytes, not nil. A guard written as "nil means incomplete" never trips on a promise. Check emptiness when emptiness is the failure.