Skip to content

simonberner/calendar-widget

Repository files navigation

Calendar Widget - Core Data

mastodon.green/@simonberner Gitmoji Conventional Commits

This App shows how one can migrate an existing App which is using a Core Data App container, to an App with a Widget Extension and a shared Core Data container for both parts in place.


Contents


Functionality

App

  • In the calendar view the user can define/select days of study in the current month.
  • The streak view shows the user for how many days they have studied in a row. As streak days count only those days, where the user has studied for at least the current or past day (from the current day) descending.

Widget Extension

  • The Widget updates in real time to the changes made in the App and automatically at the end of each day.
  • As it is a medium sized Widget, there are two touch targets on it. One that deep links into the StreakView and the other into the CalendarView of the App.

Definitions

Tech Stack

  • Xcode 15.2
  • Swift 5.9.2

Frameworks

  • SwiftUI
  • WidgetKit
  • CoreData

Device Compatibility

  • iPhone iOS 17.2+
  • iPad iOS 17.2+

Screenshots

Calendar View Streak View Widget View
Lock Screen Widgets

Learnings

Widget

  • In a Widget we should NOT make async network calls (according to Apple), because of that we can't use the property wrapper '@FetchRequest' in a Widget.

Touch Targets (Deep linking into the App)

  • Deep linking from the Widget into the App can be made by wrapping a view with Link(). This is only available on a medium and a large Widget. We can not have more than one touch targets on a small widget. The only touch target on a small widget is the whole widget.
  • On a small widget, we would use the view modifier .widgetURL()
  • SwiftCalendarApp: here we have to tag the views for deep-linking

Calendar

  • The first day of the week depends on where you are in the world.
  • Calendar.Component.weekday -> The weekday units are the numbers 1 through N (where for the Gregorian calendar N=7 and 1 is Sunday).

Core Data

  • Core Data is a persistence framework.
  • SQLite is the CoreData database engine
  • An AppGroup allows us to share one or more CoreData containers among multiple apps.
  • If you already have an existing App with a CoreData container in place, you have to do a data migration to share that container with another App, Widget Extension or App Clip.

SwiftData

  • SwiftData
  • Same as CoreData, SwifttData uses SQLite as its database engine.

SwiftUI Preview

  • The benefit of having previews is to help you building your UI quickly.
  • Don't invest too much time in maintaining your previews.
  • It probably doesn't make sense to fetch some data in the preview code.

How to make code available or unavailable for different platform versions

  • @available and #available
  • @available: is used when a class or method shall only be made available to specific iOS versions.
  • #available: is used to execute pieces of code in your flow (if #available(...) else {}) only for specific iOS versions.
  • There are also attributes values for: deprecated, obsoleted, renamed, unavailable

Other cool stuff

Testing

I use the Arrange, Act and Assert Pattern for Unit Testing.

Code Comments

I like putting in the effort of adding comments to my code, here is why.

Pull Requests

When I create PRs I stick to this guideline.

Credits

🙏🏽 Sean Allen


Made with a 🙂 Simon Berner