Starting a new project recently and:
- Wading in to the SwiftData waters and added saving to a context, and I’m impressed. Gave the app an infinite loop at the view layer and we’ll fix that later.
- Doodled a couple candidates for a development and alternate app icon! Someone has to bring a little culture.
- Just that tiny bit of progress today but the momentum is what’s important.
Little clean-ups and place setting / writing plans for the next improvements:
- Fixed that loop lol
- Switched from dataTask completion handlers to Combine's dataTaskPublisher
- TIL don't use @Model var id
because that field name is already taken
- Hm that's weird though, the docs say it's persistentModelId
but Xcode 15.0.1 gives me id
in the definition.
- https://developer.apple.com/documentation/swiftdata/persistentmodel/persistentmodelid
Today:
- Added a preview for the first Form view
- Fixed preview for main view (need to add mock user data)
- Writing notes to connect model work with submitting this form
- Took a detour to build out fetching account info and then returned to pre-populate the form
- Hit a 401 when requesting account info
- Figured out I need to use the accessToken from the token body response
- Pre-filled that info on the form
- Display user's name on main page
- Lots more // TODO
Today
- No luck with my previews yet (likely have to mock out API client)
- add parsing/serializing idempotency test to main model (failing)
- add suggestions list for Manufacturer field with network fetch and SwiftData storage (pretty useful!) (more work to connect selection to main model)
- add KeychainSwift dependency
- add AuthenticatedUser (new) owns User (existing)
- add keychain caching for OAuth token — auto-login if the session is still valid!
Also Thursday (previous post):
- Added environment variables to xcconfig
- Added showing the env in new SettingsView
Today:
- Fixed api host url to include the port
- Added config for local environment!
- Failing to get an access token from the local dev server during OAuth, asked for help
- Added sign-out button to Settings if authenticated
- Added Settings view to sign-in page to show the current env
- Added notes
Today [1/2]:
- Yay just POSTed my first test model through my app!
- Turns out this API supports test=true in production
- Checked with Proxyman
- Added alternate app icons as a treat
- Fixed previews by adding missing models!
- See forTypes
param https://developer.apple.com/documentation/swiftdata/modelcontainer/init(for:migrationplan:configurations:)-8s4ts
- Add super lazy 2 column layout on main page, that'll get changed
- Wrapped the post-auth user model write in a transaction but still getting hangs, hmm…
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.