UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

@Day 59 and now trying something by myself

Forums > SwiftUI

Hi,

I finnished Day 59. Now I want to consolidate my knowledge a bit. I came up with a project that would also have a practical use for me. I want to create a shift planner. It should be able to create shifts for several employees of a company. The first step in planning is for me to create the model correctly. I do this because I'm not very good at it. This will help me improve my skills. I was planning the "Shift" like this:

struct Shift {
    // the shift e.g. 1st Shift of the Day

    private var name : String
    private var shortName : String
    var modules : [ShiftModule] = []
}

struct ShiftModule { // Start and End of a Shift

    enum ShiftAlteration {
        // Alterations of the same Shift e.g. 1st Shift on Weekends are different then on Weekdays
        case general
        case weekend
        case holiday
    }

    var mode : ShiftAlteration
    var startTime : Date
    var duration : Double
    var endTime : Date?

    init(mode: ShiftAlteration, start: Date, duration: Double) {
        self.mode = mode
        self.startTime = start
        self.duration = duration
        self.endTime = Calendar.current.date(byAdding: .second, value: Int(duration), to: startTime)
    }
}

The rest is not ready to publish. I think my solution is not good. I guess it would be better, when I organize Shift.modules in a dictionary with the ShiftAlteration as a key instead of an array. But let me know your oppinion.

1      

One thing you might do is change duration from a Double to a TimeInterval (which, technically, is just a typealiased Double anyway, but it's more semantic). Then, in ShiftModule.init, calculate endTime using:

self.endTime = .init(timeInterval: duration, since: start)

And then you don't have to worry about endTime being an Optional and can change its type to simply Date.

More comments:

Do you really need both a duration and and endTime? One can always be calculated as needed from the other, after all.

You have name and shortName labeled as private properties in Shift but don't provide an initializer. So it's impossible to create a Shift instance because you can't initialize those properties. Either remove private or provide a custom initializer.

You use var for all the properties in Shift and ShiftModule. Only use var if you plan on being able to change the properties after initialization; otherwise use let.

Depending on how you envision ShiftModules being created and distinguished from one another, a Set<ShiftModule> might be a good idea for Shift.modules. A Dictionary might work too, it all depends on your use case. (Using Set<ShiftModule> would also require making ShiftModule conform to Hashable, but all that needs is to indicate the conformance in the type declaration.)

I'll have to think about it some more, but I'm wondering if your modeling of a shift should perhaps be reworked. I almost think Shift and ShiftModule should be combined into one struct. A day or work week or whatever can have multiple shifts, but could a shift really have multiple start/end times? That seems to me what would be modeled by Shift having multiple ShiftModules. But I could be interpreting your intent incorrectly.

1      

Thank you for your suggestions. I really appreciate that.

TOP: endTime I accepted your suggestion with the self.endTime = .init(timeInterval: duration, since: start) right away. I didn't know this .init existed. I wanted to have this value because I didn't want to constantly calculate it elsewhere.

TOP: private var You are absolutely right. Since I'm really on day 59 now, I still don't have a sense for how to use this properly.

TOP: Set<ShiftModule> In order to evaluate that, I have to explain briefly how I imagined it. The user creates a shift that automatically adjusts its times based on whether it's a weekday, weekend, or holiday. And that is done using the ShiftAlteration. Later in a View we show the correct times for a given shift on a weekday, weekend or holiday. This will be done by looking for the correct ShiftAlteration in modules. Do you think a set would be most appropriate for this usecase?

https://www.dropbox.com/s/dseozemdpf9vuxg/Bildschirmfoto%202022-02-12%20um%2007.43.14.png?dl=0

Sorry i couldn't figure it out, how to attach an image here. The image shows the creation of a shift.

1      

You can embed an image in your post by doing the following:

  1. Change the dl=0 on the end to raw=1
  2. Wrap the link in the appropriate markup:
![image description](image URL)

So:

![shift time adjustment](https://www.dropbox.com/s/dseozemdpf9vuxg/Bildschirmfoto%202022-02-12%20um%2007.43.14.png?raw=1)

results in:

shift time adjustment

2      

As for the actual design and stuff...

I think I get it now. So every Shift will always have at least one module and may or may not have one or two more modules?

If my understanding is correct, here's what I'd do:

struct Shift {
    let name : String
    let shortName : String
    var modules : [ShiftModule.ShiftAlteration: ShiftModule] = [:]  //1

    init(name: String, shortName: String, baseModule: ShiftModule) {  //2
        self.name = name
        self.shortName = name
        self.modules[baseModule.mode] = baseModule  //3
    }
}

struct ShiftModule {

    enum ShiftAlteration: Hashable { //4
        case general
        case weekend
        case holiday
    }

    let mode : ShiftAlteration
    let startTime : Date
    let duration : TimeInterval
    let endTime : Date

    init(mode: ShiftAlteration, start: Date, duration: TimeInterval) {
        self.mode = mode
        self.startTime = start
        self.duration = duration
        self.endTime = .init(timeInterval: duration, since: start)
    }
}
  1. Make modules a Dictionary with a key of ShiftModule.ShiftAlteration. That way, you will only ever have 1 of each alteration type.
  2. This custom init ensures that we will always have one alteration. We may or may not have other alterations, but one is required.
  3. Use the mode property of the baseModule parameter as the key to our Dictionary
  4. Make ShiftModule.ShiftAlteration conform to Hashable so we can use it as a Dictionary key. All we have to do to conform is declare our conformance.

2      

Thanks for both of your answers. I'll post later my results.

1      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

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

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

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.