ContactTrickStateModel.swift 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import ConnectIQ
  2. import CoreData
  3. import SwiftUI
  4. extension ContactTrick {
  5. @Observable final class StateModel: BaseStateModel<Provider> {
  6. @ObservationIgnored @Injected() var contactTrickStorage: ContactTrickStorage!
  7. var contactTrickEntries = [ContactTrickEntry]()
  8. private let contactManager = ContactManager()
  9. var units: GlucoseUnits = .mmolL
  10. /// Subscribes to updates and initializes data fetching.
  11. override func subscribe() {
  12. units = settingsManager.settings.units
  13. Task {
  14. /// Initial fetch to fill the ContactTrickEntry array
  15. await fetchContactTrickEntriesAndUpdateUI()
  16. }
  17. }
  18. /// Fetches all ContactTrickEntries from Core Data.
  19. func fetchContactTrickEntriesAndUpdateUI() async {
  20. let entries = await contactTrickStorage.fetchContactTrickEntries()
  21. await MainActor.run {
  22. self.contactTrickEntries = entries
  23. }
  24. }
  25. /// Creates a new contact in Apple Contacts and saves it to Core Data.
  26. /// - Parameters:
  27. /// - entry: The ContactTrickEntry to be saved.
  28. /// - name: The name of the contact.
  29. func createAndSaveContactTrick(entry: ContactTrickEntry, name: String) async {
  30. // 1. Check for contact access permissions.
  31. let hasAccess = await contactManager.requestAccess()
  32. guard hasAccess else {
  33. print("No access to contacts.")
  34. return
  35. }
  36. // 2. Create the contact and retrieve its `identifier`.
  37. guard let contactId = await contactManager.createContact(name: name) else {
  38. print("Failed to create contact.")
  39. return
  40. }
  41. // 3. Update the entry with the `contactId`.
  42. var updatedEntry = entry
  43. updatedEntry.contactId = contactId
  44. // 4. Save the contact to Core Data.
  45. await addContactTrickEntry(updatedEntry)
  46. }
  47. /// Adds a ContactTrickEntry to Core Data.
  48. /// - Parameter entry: The ContactTrickEntry to be saved.
  49. func addContactTrickEntry(_ entry: ContactTrickEntry) async {
  50. await contactTrickStorage.storeContactTrickEntry(entry)
  51. await fetchContactTrickEntriesAndUpdateUI()
  52. }
  53. /// Deletes a contact from Apple Contacts and Core Data.
  54. /// - Parameter entry: The ContactTrickEntry representing the contact to be deleted.
  55. func deleteContact(entry: ContactTrickEntry) async {
  56. guard let contactId = entry.contactId else {
  57. print("Contact does not have a valid ID.")
  58. return
  59. }
  60. // 1. Attempt to delete the contact from Apple Contacts.
  61. let contactDeleted = await contactManager.deleteContact(withIdentifier: contactId)
  62. if contactDeleted {
  63. print("Contact successfully deleted from Apple Contacts: \(contactId)")
  64. } else {
  65. print("Failed to delete contact from Apple Contacts. Check if it exists.")
  66. }
  67. // 2. Delete the entry from Core Data.
  68. if let objectID = entry.managedObjectID {
  69. await deleteContactTrick(objectID: objectID)
  70. }
  71. }
  72. /// Deletes a Core Data entry.
  73. /// - Parameter objectID: The Managed Object ID of the entry to be deleted.
  74. func deleteContactTrick(objectID: NSManagedObjectID) async {
  75. await contactTrickStorage.deleteContactTrickEntry(objectID)
  76. await fetchContactTrickEntriesAndUpdateUI()
  77. }
  78. /// Updates a contact in Apple Contacts and Core Data.
  79. /// - Parameters:
  80. /// - entry: The ContactTrickEntry to be updated.
  81. /// - newName: The new name to assign to the contact.
  82. func updateContact(entry: ContactTrickEntry, newName: String) async {
  83. guard let contactId = entry.contactId else {
  84. print("Contact does not have a valid ID.")
  85. return
  86. }
  87. // 1. Update the contact in Apple Contacts.
  88. let contactUpdated = await contactManager.updateContact(withIdentifier: contactId, newName: newName)
  89. guard contactUpdated else {
  90. print("Failed to update contact in Apple Contacts.")
  91. return
  92. }
  93. // 2. Update the entry in Core Data.
  94. var updatedEntry = entry
  95. updatedEntry.name = newName // Update additional fields if needed.
  96. await updateContactTrick(updatedEntry)
  97. }
  98. /// Updates a Core Data entry.
  99. /// - Parameter entry: The updated ContactTrickEntry.
  100. func updateContactTrick(_ entry: ContactTrickEntry) async {
  101. await contactTrickStorage.updateContactTrickEntry(entry)
  102. await fetchContactTrickEntriesAndUpdateUI()
  103. }
  104. }
  105. }