Do Good Daily Day 3
Tags: swift, swiftui, ios
Published: 2019-09-15 04:15:52

📅 09/14/2019
🔥 3 day streak
📱 Do Good Daily
💰 $0.99 price
🤑 0 sales
⌚️ 3 hours spent
💻 8 files changed, 53 additions(+), 9 deletions(-)
✅ Today's goal: Recap yesterday

## I have a life

It might surprise you but I actually have a life outside of making apps. I don’t want to bore you with the details but I didn’t get much done today.

Let’s dive right in. How do you set the initial state of a swiftUI view? Here’s how I did it

## Setting SwiftUI initial state

```swift
import SwiftUI

struct MorningReminderView: View {
    @State var hour = 5
    @State var minute = 0

    var body: some View {
        VStack {
        }.onAppear {
            let app = Database().load()
            self.hour = app.morningHour
            self.minute = app.morningMinute
        }
    }
}
```

## Custom fonts in swiftUI

There are three steps
1. Add the font to the project and make sure it’s added to the target
![xcode font added to project](https://thepracticaldev.s3.amazonaws.com/i/78vijrsakws6ecwj6a7j.png)
2. Add it to info.plist
![info plist](https://thepracticaldev.s3.amazonaws.com/i/jxgzweyjrm99pvr9ayeu.png)
3. Call it in your code
```swift
let font = "IM_FELL_English_Roman"
Text("Set Your Morning Reminder Time")
            .font(.custom(font, size: 16))
```

## Serialize app state to a json file

Last thing about swiftUI today, serialize app state to a json file the ghetto way. Two parts, the first part is a class that handles loading and saving to the file along with json serialization, hey it does it all!

```swift
import Foundation

public struct App : Codable {
    public var morningHour:Int
    public var morningMinute:Int
    public var eveningHour:Int
    public var eveningMinute:Int
    public var entries:[Entry]
}

public struct Entry : Codable {
    public var goal:String
    public var accomplished:String
    public var timestamp:Int
}

public class Database {
    let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
    let db = "db.json"

    func getDocumentsDirectory() -> URL {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        return paths[0]
    }

    public func save(app: App) {
        let filename: URL = getDocumentsDirectory().appendingPathComponent(db)
        let data: Data = try! JSONEncoder().encode(app)

        try! data.write(to: filename)
    }

    public func load() -> App {
        let filename: URL = getDocumentsDirectory().appendingPathComponent(db)
        do {
            let data = try Data(contentsOf: filename, options: .mappedIfSafe)
            let app = try JSONDecoder().decode(App.self, from: data)

            return app
        } catch {
            return App(morningHour: 7, morningMinute: 30, eveningHour: 21, eveningMinute: 0, entries: [])
        }
    }
}
```

The second part is the SwiftUI view

```swift
import SwiftUI

struct MorningReminderView: View {
    @State var hour = 5
    @State var minute = 0

    var body: some View {
        VStack {
            Button(action: {
                self.saveTime()
            }) {
                Text("Save")
                .frame(width: 200)
                .font(.custom(self.font, size: 24))
                .padding()
                .foregroundColor(Color.black)
                .overlay(
                    RoundedRectangle(cornerRadius: 40)
                        .stroke(Color.black, lineWidth: 2)
                )
            }
        }
    }

    func saveTime() {
        var app = Database().load()
        app.morningHour = self.hour
        app.morningMinute = self.minute
        Database().save(app: app)
    }
}
```

And that's that for today, I learned quite a bit and I hope it helps you handle the basics of any swiftUI app. Let me know if you want to learn swift, I'm on twitter (probably too much) or just leave a comment and if I can answer any of your questions, I will!