Devote Devote

Utilizing Core Data, this app features full database read/write functionality, dynamic light/dark-mode and iOS widget support.

  • iOS 15+

  • SwiftUI 2.0


Devote was designed to be a basic task-manager, allowing users to add, edit, action, and remove text-based tasks from a persistent storage location by introducing the Core Data framework. Additionally, this app also introduces dynamic on-the-fly theme switching, and support for all three sizes of iOS Widgets.


At it's core, the Devote project is an extremely simple app. It is comprised of a single view, allowing the user to scroll through their list of tasks, add tasks using a custom text field component, and switch between Light and Dark Modes by triggering a simple .toggle() button in the apps Navigation bar. A bulk of the development effort is invested in the implementation of the Core Data model which allows the user to add or modify their tasks, and maintain their full task list in a persistent data set.

The task data set is comprised of four primary variables: the task description, stored as a string; the bool task completion status; a timestamp; and a universally unique identifier (UUID()) to differentiate between similar or identical data in the data set. In laymans, this UUID ensures that when data is updated by the user, the correct data is updated in the model.

Using Core Data allows the app to consume and display user-generated data, without the need for manually providing data sets or models as was done in previous projects. Additionally, it provides a vehicle to automate the collection and generation of data for the data model without additional effort being spent building out this functionality. In the Devote app, the only user-provided value is the text description of the task, the UUID and timestamp are generated automatically, and the false completion status is added to new tasks by default.

The final component of the Devote app, is the inclusion of the iOS Widget Extension, which enables widget functionality across all supported devices. For the purposes of this project, a static widget was designed, which would not feature any user-configuration, but would still allow a single responsive design to be used across all widget sizes. By monitoring the selected widget size using the @Environment(\.widgetFamily) property, elements of the design such as the text or logo sizing can be rendered dynamically on a single widget design.



This was an immensely fun project to build. The complexity of the Core Data implementation, paired with the simplicity of the app design, allowed for a greater focus on the Core Data framework principles, and ultimately led to a much deeper level of comprehension. In a similar way, building and implementing a static widget extension laid the necessary framework to construct configurable widgets in subsequent projects.