NEW: Learn to build the incredible iOS 15 Weather app today! >>

SOLVED: Day 56: Bookworm Wrapup: Challenge #3

Forums > 100 Days of SwiftUI

To wrapup the Bookworm project @twostraws challenges us to add a new date attribute to the Book entity. Then he says to format that nicely somewhere in DetailView.

Adding a reviewDate to the CoreData model was as simple as adding a new entity, and rebuilding. Then when you create a new book, just assign to the reviewDate var.

To add business logic to the CoreDate Book class, I created an extension. There I added a few business rules as computed properties. I also created a convenience view to show the review date for Challenge #3.

What I toyed with (examples below) are iOS 15 features for formatting date objects. (Check out Logan's 5 min vid: iOS 15 Date Formatter )

For example:

  • reviewDate.formatted(.dateTime.year().day(.twoDigits).month(.abbreviated)) -> Nov 27, 2021 or Jan 03, 2022
  • reviewDate.formatted(.dateTime.month(.abbreviated).year())) -> Nov 2021
  • reviewDate.formatted(.dateTime.year(.twoDigits).month(.twoDigits)) ) -> 11/21

It's more Swift like to use .abbreviated or .twoDigits rather than the C-like "MMmmmHH-YY" rules.

// Books_Extension.swift
// This extension adds logic to the CoreData class. It's in an extension because CoreData will
// overwrite the Class definition, if you modify the CoreData model.
//  Created by Obelix on 11/25/21.

import SwiftUI

extension Book {
    // isWorstRating is a business rule. This logic should NOT be in the view!
    func isWorstRating() -> Bool {
        if self.rating == 1 { return true }
        return false
    // Turn the review date into a string for display.
    var displayDate : String {
        return (reviewDate ?? // Core data may not have a value for this
                        .year()                // New formatter! 2 or 4 year
                        .day(.twoDigits)       // day has options! 07 or 7
                        .month(.abbreviated))  // month has more options
        // format descriptors are more Swifty. Less C-like.

// Create a convenience view to use on other forms and views.
struct ReviewDateView: View  {
    let reviewDate: String
    var body: some View {
        HStack {
            Label ("\(reviewDate)", systemImage: "text.badge.checkmark")
                .padding([.trailing, .leading])
                .clipShape(RoundedRectangle(cornerRadius: 5))

Bookworm: Challenge #3


Hi @Obelix

You might want to consider putting this in the DetailView

if let date = {
    Label(date.formatted(date: .abbreviated, time: .omitted), systemImage: "calendar.badge.clock")
        .clipShape(RoundedRectangle(cornerRadius: 5))


This has the advantage that will always show in correct format for a user's settings


Thanks for the hint! I suppose I should honor a user's preferred settings, if I must. <insert winky emoji here>

Actually for my own projects I prefer the 15 NOV 2021 format. I like to see dates WITHOUT commas in them. I was trying for this format, but found out that the new Swifty formatters do not honor the order in which they are placed.

     .year()                // New formatter! 2 or 4 year
     .day(.twoDigits)       // day has options! 07 or 7

produces the same output as


For me that's Nov 28, 2021

I don't like commas in my dates! Maybe this is already formatted for my 'locale' ?

Still need more hours in the driver's seat to figure these out.


HINT: The simulator is set by default to US. You can change it to your region by selecting Product then hold the option key until you see … after Run then click on it then change the App Region to your region.


Hacking with Swift is sponsored by Sentry

SPONSORED With Sentry’s error and performance monitoring for iOS, you see mobile vitals that actually matter, can solve any latency issues quickly, and learn how each release is performing over time.

Learn More

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.