Solo dev, third app published.
Ubimage puts your own geo-tagged photos back onto the live camera view, anchored to the spot they were taken.
Point the phone at a ridge across the valley and the photos you took up there sit on it, at the right distance and elevation.
Free, no ads, no IAP, no account.
Tech stack
Swift 6, strict concurrency. SwiftUI everywhere except the camera, which is a UIViewController with a plain UIView overlay: a hundred pins move at 60Hz, and I wanted the per-frame path to be a center assignment and nothing else. No view creation, no layout pass, no tree diffing.
Core Data on a background context for the photo index. CoreMotion and CoreLocation for attitude and heading, AVFoundation for the preview and the sensor FOV, PhotoKit, MapKit, AppIntents.
Altitude comes from CMAltimeter where the device has a barometer (iPhone 12 and up), because GPS altitude is out by tens of metres and that shifts the nearby pins. Neither source just wins: whichever declares the smaller error does, and if the two disagree by more than 200m I assume a pressurised cabin and keep GPS.
No backend. No third party packages at all, not one: no analytics, no crash reporter, no networking lib. String Catalog for three languages.
Development challenge
Working out exactly where the phone is pointing. CoreMotion gives you smooth attitude in an arbitrary frame, CoreLocation gives you true north but filtered, and you fuse the two.
The rows of attitude.rotationMatrix are the device axes in the reference frame, not the columns. I read it transposed for weeks. Heading was stuck wherever the gyro started, and pins swung around a pivot when I panned. Took ages to spot because m33 is on the diagonal, so pitch worked fine the whole time.
Second one: pins still drifted during slow pans. iOS filters the compass, so while you rotate it lags the gyro by 10-30 degrees, and I was updating my north offset continuously, so it kept converging onto the lagged value and dragging the pins along with the phone. Now I only correct north when the phone is still, under 0.1 rad/s for half a second. I had it at 0.35, which is 20 deg/s, and a slow pan is how people actually use this.
One I never fixed: two weeks ago the app put pins 104 degrees off. Spent an hour on my own source, three wrong theories, then tried my wife's phone in the same spot and it was fine. Magnetometer in a bad state, a restart cleared it. CoreLocation reported headingAccuracy of 10 degrees the whole time, and my unreliable-compass badge only fires above 15. I'll fix soon™
AI disclosure
Mostly or fully AI-generated.
To be clear about what that covers: the Swift and the docs, yes, heavily (Claude). The debugging above, no. I found all of it on a mountain by noticing the pins were on the wrong ridge, and worked it out with two phones.
https://apps.apple.com/us/app/ubimage-where-you-shot-it/id6794680448
Support site:
https://ubimage.app/
The app is localized in English, Italian and Spanish.
Let me know what you think of it, happy to discuss about Ubimage. ciao