A SwiftUI app that allows users to record their thoughts on a quote daily. Each day a new quote is displayed via the Zen Quotes API.
- The app displays a new quote every day via the API in the 'Home' tab. The user can then choose to share this quote with other apps or reflect on the quote and save their thoughts/feelings.
- Quotes which have been reflected upon will appear in the 'Saved' tab. The user can scroll through the list of their saved quotes or search by author or quote content. Each quote's reflection can be viewed or edited from here. Each quote can be deleted from the menu button or by swipe action.
- In the 'Settings' tab the user can change their notifications and appearance settings. The notification reminds them to open the app each day to see a new quote (assuming the user has granted permission to receive notifications). The user can switch between light, dark and system appearance.
Overview:
- This app is almost entirely SwiftUI. UIKit was used for the
UIActivityViewControlleron iPad. - The minimum deployment target is iOS 27.0 and iPadOS 27.0.
- Swift language version is Swift 6.
- MVVM, Core Data and Swift concurrency.
- iPhone and iPad are both supported.
- The app supports different size classes, portrait and landscape orientation, and light, dark or system appearance.
- XCTest and Swift Testing are used for testing.
Networking:
- The network code uses async/await with
URLSession, and there is dependency injection for loose coupling and testability. - The network response is cached using
URLCache. - The caching strategy avoids exceeding the rate limit of 5 requests per 30 second period, and the cached data is overwritten when new data is available (daily).
- I looked at various caching solutions such as
NSCache,URLCache, and in-memory caching and persistent caching.NSCacheis emptied when the app is terminated / the current session ends, so this doesn't stop the rate limit being exceeded. The caching strategy now usesURLCachewhich may persist data across app launches, and the data's date is used to determine if a new network request is needed.
Persistence:
- Persistence of saved quotes is achieved via
CoreData. - I was looking for an approach which separated
CoreDatafrom the rest of the app as much as possible, which ruled out using@FetchRequestin my app's views. For this purpose I wanted to try out Donny Wals' approach of usingObservableObject, the@Publishedproperty wrapper andNSFetchedResultsController. You can read his article on it here. - The user's appearance setting is persisted by
UserDefaults, and the user can change the appearance in the app's settings. - If the user sets a new time for notifications that time will be saved to
UserDefaults.
Accessibility:
- There is support for VoiceOver and Dynamic Type.
- Migrate to Swift 6.
- Migrate from
CoreDatatoSwiftData. - Migrate from
ObservableObjectto@Observable. - Improve testability and test coverage, and add UI tests.
- Other enhancements and quality of life improvements.
- Clone the repo.
- Open
Quotes.xcodeproj. - Build and run.



