Implement AddOdometerReading AppIntent#302
Implement AddOdometerReading AppIntent#302OmarHegazy93 wants to merge 2 commits intomikaelacaron:devfrom
Conversation
mikaelacaron
left a comment
There was a problem hiding this comment.
Thank you for submitting this!
I have several comments about the implementation, and a few questions
Basic-Car-Maintenance/Shared/AppIntents/AddOdometerReadingAppIntent.swift
Outdated
Show resolved
Hide resolved
| let authViewModel = await AuthenticationViewModel() | ||
| let odometerVM = OdometerViewModel(userUID: authViewModel.user?.uid) | ||
| try odometerVM.addReading(reading) | ||
| return .result(dialog: "Added reading successfully") |
There was a problem hiding this comment.
I see why you need this, but I don't like having this here in this struct because it makes it impossible to test this, but also because now AddOdometerReadingIntent depends on AuthenticationViewModel and OdometerViewModel
I'm not sure what the alternative is, which kinda goes back to my question about when is this struct called?
There was a problem hiding this comment.
let me know if the previous answer addresses your question, but here the only way we can access the user id to retrieve the Vehicles is through AuthenticationViewModel, however, one alternative solution would be persisting the vehicles locally on disk so that we can access vehicles from inside OdometerViewModel, hence, no need for the AuthenticationViewModel dependency anymore nor calling an api to fetch the vehicles from the server.
Or maybe storing the UserID somewhere and make it accessible inside `OdometerViewModel, but this one wouldn't make sense to me
Basic-Car-Maintenance/Shared/AppIntents/AddOdometerReadingAppIntent.swift
Outdated
Show resolved
Hide resolved
Basic-Car-Maintenance/Shared/AppIntents/AddOdometerReadingAppIntent.swift
Outdated
Show resolved
Hide resolved
| vin: String? = nil, | ||
| licensePlateNumber: String? = nil | ||
| ) { | ||
| self.documentID = id |
There was a problem hiding this comment.
The documentID shouldn't be set from the id, because it would always be empty
this gets set properly when fetching from Firebase
There was a problem hiding this comment.
So there are a couple of things going on here:
- Since
Vehicleconforms now toAppEntityprotocol, it must beidentifiable, meaning it must have a non-optionalid - The property
documentIDwas previously namedidand since it's defined using@DocumentIDproperty wrapper, it must be an optional value, so by keeping it asidwill give a compilation error indicating that TypeVehicledoes not conform to protocolAppEntity, which must be non-optional as motioned in the aforementioned point - The
documentIDwill correspond to the key "_id" when sending/retrieving vehicle from firebase as theCodingKeysenum indicates - The reason why
documentIDis set to private property is not to confuse the caller for havingdocumentIDandidso I wanted the caller to deal with only one value that refers to the id of the vehicle and under the hood, we pass this id to thedocumentIDand when callingvehicle.id, this implicitly get thedocumentID
Hopefully that made it clear
Basic-Car-Maintenance/Shared/Settings/ViewModels/SettingsViewModel.swift
Show resolved
Hide resolved
|
@OmarHegazy93 please click "resolve" on all the issues that you've addressed |
|
Sorry @mikaelacaron , I re-requested the review and forgot to submit the comments 😄, you should be able to see them now |
mikaelacaron
left a comment
There was a problem hiding this comment.
Just another comment, thanks for all the work on this! Can you also update this branch from change on dev
| let authViewModel = await AuthenticationViewModel() | ||
| let odometerVM = OdometerViewModel(userUID: authViewModel.user?.uid) |
There was a problem hiding this comment.
So from what I've seen in examples we'd use @Dependency for these dependencies in the EntityQuery and AppIntent
Like:
@Dependency private var authViewModel: AuthenticationViewModel as a struct level variable, then we use it in perform and fetchVehicles, rather than initializing it
Can you add that here and in the other places too
3595e43 to
b79dcc0
Compare
b79dcc0 to
3838276
Compare
mikaelacaron
left a comment
There was a problem hiding this comment.
we reviewed this live during my livestream!
https://youtube.com/live/xhlq3p9gxDM?feature=share
we didn't finish it, but there's a few comments of things we are going to change!
Basic-Car-Maintenance/Shared/Settings/ViewModels/AuthenticationViewModel.swift
Show resolved
Hide resolved
| ) | ||
|
|
||
| private func fetchVehicles() async throws -> [Vehicle] { | ||
| let odometerVM = OdometerViewModel(userUID: authViewModel.user?.uid) |
There was a problem hiding this comment.
let's add OdometerViewModel as a dependency too
What it Does
Implement shortcut for adding new odometer reading
What is implemented?
Vehiclenow conforms toAppEntityprotocol, hence, it should have an explicitid, which representsdocumentIdunder the hoodVehicleQueryis simply fetching vehicles from the serverDistanceUnitenum is used to make it more readable for selecting Distance unitAddOdometerReadingIntent, validation is applied toDistance, and if the vehicles are empty, then the user will not be able to finish the shortcutHow I Tested
Happy Scenario
Settingstab >Add Vehicle+on the top right corner⨁ Add ActionAppstabBasic CarAdd Odometer ReadingUnhappy Scenario
Senario1
Settingstab >Add Vehicle+on the top right corner⨁ Add ActionAppstabBasic CarAdd Odometer ReadingSenario2
+on the top right corner⨁ Add ActionAppstabBasic CarAdd Odometer Reading