Show Full thread

Today:
- got the dev server working!
- This is not a reproducible build
- This is not a place of honor 🫣
- That GettingStarted.md is calling me and it'll be starting from zero. Might come back to it later
- Need a breather after this but glad I have a checkpoint

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:
- wrote that Getting Started guide for installing on Ubuntu

I am _reminded_ that Foundation's URLRequest and Swift's Codable don't have support for HTTP multipart forms

"Hey get out of here! No programming in the house! Take that outside on the weekends. We _just_ got the PR queue cleaned up.”

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 developer.apple.com/documentat
- 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 github.com/interactord/URLEnco
- 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:
- started to rewrite networking out of Combine (dataTaskPublisher) into an actor.
- aiming for groups of generic endpoints mapped to models

Today:
- continuing actor based networking
- mostly defining generic endpoints

Today:
- git push origin -u main
- 🫣 still more to clean and rearrange

Well! Thanksgiving threw off my development streak. Got to get back into it.

Today 1/2
- Continuing API work. Moving to Result and using Result.catching which is very nice.
- thx Andres! See iosdev.space/@andresraigoza/11
- Switched UIKit ASWebAuthentication to Environment(\.webAuthenticationSession)
- thx Andy! See iosdev.space/@andy/11147423796
- 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

Ahhhh still figuring this out 🥴

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.

- experimenting and trying to figure out this decoding in unit tests. Inching forward.
- Found the ‘-com.apple.CoreData.SQLDebug 3‘ launch argument to help
- I think I’m going to separate the data models from the decoding and that way I can figure out autosave and inserts on an appropriate timeline

I think to get started with SwiftData you need to first understand CoreData. The sample code is cute but any slightly advanced scenario is obtuse.

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 I did some clean up, deleted comments and unused code, and feel pretty good about this little home grown networking layer.

Today: 🆕 switching over to pushing changes to the public repo. I might've left more things broken but now I'm content with the path forward.

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 github.com/gahntpo/DoubleColum

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.

Today: yeah I flattened this hierarchy into a ContentView containing NavigationStack containing the root level of buttons and menu options that link to .navigationDestination.
Next I need to revisit that test data and add your own bikes to the ContentView’s root level.

Turns out the way to get a custom navbar background is with

.toolbarColorScheme(.dark, for: .navigationBar)
.toolbarBackground(.blue, for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar)

Today: fixed up a usage of the old networking pattern, cleaned up the WelcomeView and assets, figured out how to add that navigation bar I wanted.

Today: fixed up the BetterSafariView navigation

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: working on the bike app for so long that my token expired and I haven't built any automatic refresh behavior yet trololol

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).

This new approach with WebViewKit might run into trouble with app review or macOS potentially but that's a problem for another day

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: still setting up the dev account, still on my mind

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.

jack

@j4ck@iosdev.space

Today: separated main module sources from tests, fixed grid sizing, fixed app icon display, updated

DEBUG exclusions for production. In-progress: session renewal, starting with local unit tests.

February 18, 2024 at 6:16:33 AM

🤦‍♂️
@objc func refresh(timer: Timer)
!=
@objc func refresh(timer: Timer) async

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.
developer.apple.com/videos/pla

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

This weekend in

:
- minor project configuration clean up
- swing and miss at integrating Fastlane Snapshot, not essential so deferring
- trying out swift 6 concurrency

Tomorrow: app launch??

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 apps.apple.com/us/app/bike-ind

Pro-tip: remember the “Authorize this OAuth application" step for your UITests 🧠💡

Elk Logo

Welcome to Elk!

Elk is a nimble Mastodon web client. You can login to your Mastodon account and use it to interact with the fediverse.

Expect some bugs and missing features here and there. Elk is Open Source and we're actively improving it as a community project. Join us and let's build it together!

If you'd like to report a bug, help us testing, give feedback, or contribute, reach out to us on GitHub and get involved.

To boost development, you can sponsor the Team through GitHub Sponsors. We hope you enjoy Elk!

三咲智子 Kevin DengAnthony FuPatakJoaquín SánchezDaniel RoeTAKAHASHI Shuuji

The Elk Team