From 8c5a287c54fa999abc75f24abf6709c4e429e052 Mon Sep 17 00:00:00 2001 From: Omar Hegazy Date: Tue, 10 Sep 2024 13:53:49 +0300 Subject: [PATCH] Add documentations to AppIntent and add comments to localizable strings --- .../AddOdometerReadingAppIntent.swift | 57 +++++++++++++++++-- .../Shared/Localizable.xcstrings | 13 ++--- .../Shared/Models/Vehicle.swift | 13 +++-- 3 files changed, 65 insertions(+), 18 deletions(-) diff --git a/Basic-Car-Maintenance/Shared/AppIntents/AddOdometerReadingAppIntent.swift b/Basic-Car-Maintenance/Shared/AppIntents/AddOdometerReadingAppIntent.swift index 961fa96f..4867e1f2 100644 --- a/Basic-Car-Maintenance/Shared/AppIntents/AddOdometerReadingAppIntent.swift +++ b/Basic-Car-Maintenance/Shared/AppIntents/AddOdometerReadingAppIntent.swift @@ -8,6 +8,7 @@ import Foundation import AppIntents +/// The query used to retrieve vehicles for adding odometer. struct VehicleQuery: EntityQuery { func entities(for identifiers: [Vehicle.ID]) async throws -> [Vehicle] { @@ -29,6 +30,13 @@ struct VehicleQuery: EntityQuery { } } +/// An enumeration representing the units of distance used for odometer readings. +/// +/// This enum conforms to `AppEnum` and `CaseIterable` to provide display representations +/// for the available distance units: miles and kilometers. +/// +/// - `mile`: Represents distance in miles. +/// - `kilometer`: Represents distance in kilometers. enum DistanceUnit: String, AppEnum, CaseIterable { static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Distance Type") static var caseDisplayRepresentations: [DistanceUnit: DisplayRepresentation] { @@ -42,11 +50,24 @@ enum DistanceUnit: String, AppEnum, CaseIterable { case kilometer } +/// An `AppIntent` that allows the user to add an odometer reading for a specified vehicle. +/// +/// This intent accepts the distance traveled, the unit of distance (miles or kilometers), +/// the vehicle for which the odometer reading is being recorded, and the date of the reading. +/// +/// The intent validates the input, ensuring that the distance is a positive integer. +/// If the input is valid, the intent creates an `OdometerReading` and saves it using the `OdometerViewModel`. +/// Upon successful completion, a confirmation dialog is presented to the user. struct AddOdometerReadingIntent: AppIntent { @Parameter(title: "Distance") var distance: Int - @Parameter(title: "Distance Unit") + @Parameter( + title: LocalizedStringResource( + "Distance Unit", + comment: "The distance unit in miles or kilometers" + ) + ) var distanceType: DistanceUnit @Parameter(title: "Vehicle") @@ -55,7 +76,10 @@ struct AddOdometerReadingIntent: AppIntent { @Parameter(title: "Date") var date: Date - static var title: LocalizedStringResource = "Add Odometer Reading" + static var title = LocalizedStringResource( + "Add Odometer Reading", + comment: "Title for the app intent when adding an odometer reading" + ) func perform() async throws -> some IntentResult & ProvidesDialog { if distance < 1 { @@ -71,10 +95,26 @@ struct AddOdometerReadingIntent: AppIntent { let authViewModel = await AuthenticationViewModel() let odometerVM = OdometerViewModel(userUID: authViewModel.user?.uid) try odometerVM.addReading(reading) - return .result(dialog: "Added reading successfully") + return .result( + dialog: IntentDialog( + LocalizedStringResource( + "Added reading successfully", + comment: "The message shown when successfully adding an odometer reading using the app intent" + ) + ) + ) } } +/// An enumeration representing errors that can occur when adding an odometer reading. +/// +/// This enum conforms to `Error` and `CustomLocalizedStringResourceConvertible` to provide +/// localized error messages for specific conditions: +/// +/// - `invalidDistance`: Triggered when a distance value less than 1 (either in kilometers or miles) is entered. +/// - `emptyVehicles`: Triggered when there are no vehicles available to select for the odometer reading. +/// +/// Each case provides a user-friendly localized string resource that describes the error. enum OdometerReadingError: Error, CustomLocalizedStringResourceConvertible { case invalidDistance case emptyVehicles @@ -82,9 +122,16 @@ enum OdometerReadingError: Error, CustomLocalizedStringResourceConvertible { var localizedStringResource: LocalizedStringResource { switch self { case .invalidDistance: - "You can not select distance number less than 1 km or mi" + LocalizedStringResource( + "You can not select distance number less than 1 km or mi", + comment: "an error shown when entering a zero or negative value for distance" + ) case .emptyVehicles: - "No vehicles available, please add a vehicle using the app and try again" + LocalizedStringResource( + "No vehicles available, please add a vehicle using the app and try again", + comment: "an error shown when attempting to add an odometer while there are no vehicles added" + ) + } } } diff --git a/Basic-Car-Maintenance/Shared/Localizable.xcstrings b/Basic-Car-Maintenance/Shared/Localizable.xcstrings index d472f354..39a5eca6 100644 --- a/Basic-Car-Maintenance/Shared/Localizable.xcstrings +++ b/Basic-Car-Maintenance/Shared/Localizable.xcstrings @@ -370,7 +370,7 @@ } }, "Add Odometer Reading" : { - + "comment" : "Title for the app intent when adding an odometer reading" }, "Add Reading" : { "comment" : "Title for form when adding an odometer reading", @@ -636,7 +636,7 @@ } }, "Added reading successfully" : { - + "comment" : "The message shown when successfully adding an odometer reading using the app intent" }, "AddEvent" : { "comment" : "Label for adding maintenance event on Dashboard view", @@ -1723,7 +1723,7 @@ }, "Distance Unit" : { - + "comment" : "The distance unit in miles or kilometers" }, "Edit" : { "comment" : "Button label to edit this maintenance", @@ -3276,7 +3276,7 @@ } }, "No vehicles available, please add a vehicle using the app and try again" : { - + "comment" : "an error shown when attempting to add an odometer while there are no vehicles added" }, "Notes" : { "comment" : "Maintenance event notes text field label", @@ -5872,12 +5872,9 @@ }, "You can edit more data about the vehicle in the 'Settings' tab." : { - }, - "You can not select a past date" : { - }, "You can not select distance number less than 1 km or mi" : { - + "comment" : "an error shown when entering a zero or negative value for distance" }, "your vehicle" : { diff --git a/Basic-Car-Maintenance/Shared/Models/Vehicle.swift b/Basic-Car-Maintenance/Shared/Models/Vehicle.swift index 006121f6..0c51c5b5 100644 --- a/Basic-Car-Maintenance/Shared/Models/Vehicle.swift +++ b/Basic-Car-Maintenance/Shared/Models/Vehicle.swift @@ -9,10 +9,7 @@ import FirebaseFirestoreSwift import Foundation import AppIntents -struct Vehicle: Codable, Identifiable, Hashable, AppEntity { - var id: String { - documentID ?? "" - } +struct Vehicle: Codable, Identifiable, Hashable { @DocumentID private var documentID: String? var userID: String? let name: String @@ -28,7 +25,7 @@ struct Vehicle: Codable, Identifiable, Hashable, AppEntity { static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Vehicle") init( - id: String = "", + id: String? = nil, userID: String? = nil, name: String, make: String, @@ -61,3 +58,9 @@ struct Vehicle: Codable, Identifiable, Hashable, AppEntity { case licensePlateNumber } } + +extension Vehicle: AppEntity { + var id: String { + documentID ?? UUID().uuidString + } +}