-
-
Notifications
You must be signed in to change notification settings - Fork 144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement AddOdometerReading AppIntent #302
base: dev
Are you sure you want to change the base?
Implement AddOdometerReading AppIntent #302
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So there are a couple of things going on here:
- Since
Vehicle
conforms now toAppEntity
protocol, it must beidentifiable
, meaning it must have a non-optionalid
- The property
documentID
was previously namedid
and since it's defined using@DocumentID
property wrapper, it must be an optional value, so by keeping it asid
will give a compilation error indicating that TypeVehicle
does not conform to protocolAppEntity
, which must be non-optional as motioned in the aforementioned point - The
documentID
will correspond to the key "_id" when sending/retrieving vehicle from firebase as theCodingKeys
enum indicates - The reason why
documentID
is set to private property is not to confuse the caller for havingdocumentID
andid
so 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 thedocumentID
and 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3595e43
to
b79dcc0
Compare
b79dcc0
to
3838276
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's add OdometerViewModel
as a dependency too
What it Does
Implement shortcut for adding new odometer reading
What is implemented?
Vehicle
now conforms toAppEntity
protocol, hence, it should have an explicitid
, which representsdocumentId
under the hoodVehicleQuery
is simply fetching vehicles from the serverDistanceUnit
enum 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
Settings
tab >Add Vehicle
+
on the top right corner⨁ Add Action
Apps
tabBasic Car
Add Odometer Reading
Unhappy Scenario
Senario1
Settings
tab >Add Vehicle
+
on the top right corner⨁ Add Action
Apps
tabBasic Car
Add Odometer Reading
Senario2
+
on the top right corner⨁ Add Action
Apps
tabBasic Car
Add Odometer Reading