Today [2/2]:
- Added URLEncodedForm dependency for creating models https://github.com/interactord/URLEncodedForm
- Now that creating a model works I need to update the app after you get a result back. Lots to do in this regard starting with networking, data, relationships, and navigation.
- Need to overhaul networking and probably rip out Combine
- Need to fix navigation bugs
- Need to write documentation and do clean-up
- Lots to do after a busy Monday/Tuesday
Today 1/2
- Continuing API work. Moving to Result and using Result.catching which is very nice.
- thx Andres! See https://iosdev.space/@andresraigoza/111467810356746742
- Switched UIKit ASWebAuthentication to Environment(\.webAuthenticationSession)
- thx Andy! See https://iosdev.space/@andy/111474237966941569
- Wading back into the project to get building again.
Today 2/2
- Fighting SwiftData lifecycles from: A) fetching and parsing JSON, B) writing to disk, C) with relationships. My key problem is that I'm expecting to "upsert" models when a new instance has the same value for an @Attribute(.unique) field, but that's not happening. The tell is that a relationship’s persistentModelID.storeIdentifier is nil after the parent's init(decoder:).
- Gotta revisit the videos and examples around SwiftData to see how this should be done.
Today 1/2:
- Was hitting fatal SwiftData errors on ~4 of 5 builds.
- Background: server returns nested models in the first endpoint I need to request. Have to solve up that front.
- Synthesizing the resources below I think I switched over to a working approach…
• Started adding the modelContext into JSONDecoder.userInfo and inserting child/related models as decoding progresses
• Changed child/related models to optional vars or provided default values for empty arrays
Today 2/2:
- Helpful links for figuring out how to decode SwiftData relationships from JSON:
* https://stackoverflow.com/questions/77073504/swiftdata-illegal-attempt-to-establish-a-relationship-between-objects-in-differ
* https://www.hackingwithswift.com/quick-start/swiftdata/common-swiftdata-errors-and-their-solutions
* https://stackoverflow.com/questions/77485748/json-to-swiftdata-decode-of-json-ends-in-error-at-observationregistrar
Okay performing the “upsert” manually for the 1:1 relationship is the right path to work toward and not yet complete. This scenario is all about inserting multiple models at once. I'm thinking the easiest way will be to delete any stale primary data, use a cascade to change the relationships' data (or do the manual inserts), and then save everything.
Alright I know I’ve said this a lot but back to making progress:
- Split my Decodables and PersistentModels so that the networking code can perform decoding and later on I can safely transform a Decodable into a PersistentModel, establish relationships, save it, and use it.
- stopped accessing ModelContext on different threads!
- found a working relationship set up (cascade on the parent, inverse on the child), can’t explain it, gonna try adding more
Today: brought all those networking updates into the registration view and [redacted] data model, fixing some errors with POST behavior, correcting some enums to match the API.
Finally getting back to the point with UI changes on the registration view… … adding an alert after the POST succeeds or fails. Next I think I’ll get back to displaying the user’s list of [redacted] data models.
Today: fix missing serial number scenario, replace frameColors array with three fields (one required, two optional) because the array manipulation doesn't matter, bump deployment target iOS 17.2 / Xcode 15.1 because I can, add long-press to reach the same Add Bike view with more fields for stolen bikes, begin adding fields for stolen bikes to populate phone, address info.
Yesterday/today: conflicted on how to effectively use NavigationSplitView and NavigationStack. After I got everything working well on iPad I noticed that the approach is incompatible with iPhone.
(That approach was changing the NavigationSplitView detail: { }
contents based on a switch-enum in order to fill the detail view as the root view).
To get the UI that I want I think I need to just switch to modals/sheets and explore that paradigm.
This project seems like a better starting point if I go back to NavigationSplitView for this project https://github.com/gahntpo/DoubleColumnNavigationSplitProject
No wait I don't want any of that lol. I think settling on NavigationStack containing a root of a grid of buttons with NavigationPath to control the stack is what I want. That ought to navigate well on iPhone + iPad, still let me display a decent grid across both, look good, and be nice to use for editing.
A task for tomorrow.
hmmm that BetterSafariView integration is gonna need work later, on just because of the nature of SFSafariViewController…
Today: added Acknowledgement section for open source packages, moved Debug menu into nested hierarchy, and most-importantly started on fetching your registered bikes now that the network API is set up how I want for fetching and writing to SwiftData!
Installed the app to my phone for the first time too
Today: Add basic bike list and detail view, fixup the title, parse thumbnail and hero image, switch missing serial number to “unknown”, add option for bikes in model year 2025, begin adding other modes to RegisterBikeView, add a FAQ link, lots of clean-up and fixups.
Feels like we're getting close to an MVP!
omg forgot to mention, switched from BetterSafariView to WebViewKit (hi Daniel ) to access shared session state across all webviews. ASWebAuthenticationSession and SFSafariViewController are nice but I didn't have A) any way to ensure the user is logged in to present pages for advanced editing and B) no way to actually clear session state and log out!
(I might've just needed a network request to /logout but the active session in ASWebAuthenticationSession was too aggressively cached IMHO).
Today 1/2: phew! Lots of busy-work.
- Fixed log-out for “real final final copy_(2)” with a network request to /logout, and keeping a global WKWebViewConfiguration to burn the auth cookie.
- Added scheme validation for auth callbacks
- Added inspectability to web view
- Added javascript+css injection to style the page and remove the main nav header
- Added @Observable NavigableWebView wrapping WebView with a Navigator WKNavigationDelegate…
Today 2/?:
- I want a lil responder-chain of WKNavigationDelegate objects so that I can have a general one useful for back/forward navigation and then a specialized one that does authentication. (This would've been easier if they didn't all conform to WKNavigationDelegate). Made a NavigatorChild
that implements _all_ WKNavDel and has a property child: NavigatorChild
. Then those specialized uses (back/forward, authentication) are separate subclasses.
Today: shared first TestFlight internal beta, hoping for a long list of strong-opinion/loosely-held priorities, finally settled on a Pride icon.
I gotta get back to figuring out everything that was broken and in-progress I think the first was session renewal so I'm gonna have to start adding tests and making a to-do list for tomorrow.
Today: Added a "Scan Text" button for serial numbers. I just wish it had flashlight control for low-light conditions. Maybe that's not necessary.
https://developer.apple.com/videos/play/wwdc2021/10276/
This weekend:
- Fixed session refresh when the session has expired (do not need to tap "Sign in" — refreshed automatically)
- Fixed keyboard when searching/entering a Manufacturer name
- Fixed electric motor toggle behavior for "Has throttle" and "Has pedal"
- Fixed layout for Serial Number "Scan Text" button
I’m proud to introduce you to Bike Index: an open-source iOS app for the world’s leading bike registration and recovery service of the same name! Bikes mean everything to their riders: freedom of movement, ability to transport cargo, exercise and empowerment, connecting with nature and the great outdoors. Bike Index helps you recover your bike if it’s ever lost or stolen. Built with and
Direct link here https://apps.apple.com/us/app/bike-index/id6477746994
Pro-tip: remember the “Authorize this OAuth application" step for your UITests
Agh!!!!
Turmoil to get there:
3. This broke the debug-only modal AuthPage > NavigationStack > Settings > Buttons append to $path
a. Settings { @.Environment(\.openURL) var openURL } was causing continuous changes to the view itself and blocking the whole UI
b. Solved by replacing OpenURL with Link(destination:label:)
.
I definitely should’ve been using a Link before but this seems like a
4. Now I need to get those disclosure indicators back in a nice way.
Alright NavigationStack + Button + navigationDestination wasn't necessary. Revisited https://developer.apple.com/documentation/swiftui/migrating-to-new-navigation-types and realized that the problem was NavigationLink(destination: () -> View, label:) and the fix is simply NavigationLink(value: Hashable?, label:) + navigationDestination. Glad I didn't spend too much time on it. Still got those speed improvements, more to test too.
+67 -504
https://github.com/bikeindex/bike_index_ios/pull/14
Why haven't you taken the Xcode "Convert to Folder" pill yet?
GitHub
Fix: Convert Xcode project groups to folders by aokj4ck · Pull Request #14 · bikeindex/bike_index_iosDescription There are several benefits to using folders instead of groups when organizing your Xcode project files. Folders have a much smaller representation in the project file, which can result...
> There are several benefits to using folders instead of groups when organizing your Xcode project files. Folders have a much smaller representation in the project file, which can result in fewer merge conflicts because when you add or remove files to the project you don’t modify the project file. Additionally, your Xcode project file automatically updates as you make changes to the file system.
— https://developer.apple.com/documentation/xcode/managing-files-and-folders-in-your-xcode-project#Convert-groups-to-folders