vankuik.nl

Latest weblog entries

2023-09-18 SwiftUI Separate toolbar

In SwiftUI, it's easy to just keep coding and dump everything in one view. Toolbars especially are "bulky", they take up a lot of lines, and are not regular views so syntax-wise, they're a bit of a bother to separate away. Here's an example of a bottom toolbar, to help you split up those big views.

    struct MainView: View {
        var body: some View {
            Color.blue
                .ignoresSafeArea(edges: [.top, .leading, .trailing])
                .toolbar {
                    ActionToolbar()
                }
        }
    }
    struct ActionToolbar: ToolbarContent {
        var body: some ToolbarContent {
            ToolbarItem(placement: .bottomBar) {
                 Spacer()
             }
            ToolbarItem(placement: .bottomBar) {
                Button(action: { print("Plus") }) {
                    Image(systemName: "plus.app.fill")
                        .resizable()
                        .scaledToFit()
                }
            }
        }
    }

2023-08-30 Coordinator in preview

When you're using the Coordinator pattern in a SwiftUI project, you'll find yourself sometimes wanting to preview the initial start of a "flow" of screens. But that's quite a bit of work because inside the coordinator, some boilerplate code needs to be present, to wrap the SwiftUI view in a UIHostingController.

This bit of code is useful to plunk in the utilities folder of your project, and use in the preview section of your SwiftUI view.

    private class PreviewViewController: UIViewController {
        private let coordinator: NavigationControllerCoordinator
        init(coordinator: NavigationControllerCoordinator) {
            self.coordinator = coordinator
            super.init(nibName: nil, bundle: nil)
        }
        required init?(coder: NSCoder) {
            fatalError()
        }
        override func viewDidLoad() {
            guard let navigationController = self.navigationController as? NavigationController else {
                return
            }
            title = "Preview"
            var configuration = UIButton.Configuration.filled()
            configuration.title = "Start"
            self.view = UIButton(configuration: configuration, primaryAction: UIAction(handler: {_ in
                navigationController.present(self.coordinator.navigationController, animated: true)
                self.coordinator.start()
            }))
        }
    }
    struct PreviewCoordinator: UIViewControllerRepresentable {
        let coordinator: NavigationControllerCoordinator
        typealias UIViewControllerType = NavigationController
        func makeUIViewController(context: Context) -> NavigationController {
            let viewController = PreviewViewController(coordinator: coordinator)
            return NavigationController(rootViewController: viewController)
        }
        func updateUIViewController(_ uiViewController: NavigationController, context: Context) {}
    }

Use as follows;

    struct NetworkScanQRView_Previews: PreviewProvider {
        static var previews: some View {
            PreviewCoordinator(coordinator: NetworkScanQRCoordinator.mocked)
        }
    }

2023-06-14 SwiftUI pet peeves

This is my list of SwiftUI pet peeves. It's a work in progress.

  • Using .onTapGesture when you should actually use a button. Although it's nicely concise, a button will show visual feedback, and can easily be adjusted for accessibility.
  • Using a class when a struct suffices.
  • When naming a function that instantiates something, it should be prefixed with "make", not with "get" or something else. See also: https://www.swift.org/documentation/api-design-guidelines/
  • Hardcoded button sizes, when they actually should be a ScaledMetric.

2023-04-12 Natural breaks in Time Out application for macOS

I'm using a break reminder on macOS, it's called Time Out. https://dejal.com/timeout/

It's a very full-featured app, one of them is that it can skip breaks if it detects a natural break. Meaning, if you go and get a cup of coffee, it counts as a break.

The problem was, that this wasn't working. I found out how to fix this, and I'm documenting it here. Firstly, to see if the app is unable to detect the computer idle, open Time Out, and in the left navigation, select "Advanced". Then turn on "Output scheduler logging" and click the "Open Console" button. This will open Console, the macOS log viewer.

In Console, click the blue Start Streaming button, then in the top right, type: "process: Time Out" and press enter. You should now only see output from Time Out. If you don't move the keyboard or mouse, Time Out should detect that you leave the computer idle. In my case that wasn't happening, it just repeatedly logged the following lines, edited for brevity:

    idle (for 0 secs); Normal due 12/04/2023, 11:19 (in 11 min, 46 secs); .......
    idle (for 0 secs); Normal due 12/04/2023, 11:19 (in 11 min, 45 secs); .......
    idle (for 0 secs); Normal due 12/04/2023, 11:19 (in 11 min, 44 secs); .......

When I went back to Time Out, and in the Advanced screen, changed "Natural break detection method" from "Event Monitor" to "Event Source", then back to "Event Monitor", this fixed the problem! It should now detect idling correctly:

    idle (for 0 secs); Normal due ... not yet idle for at least 30 seconds
    idle (for 1 secs); Normal due ... not yet idle for at least 30 seconds
    idle (for 2 secs); Normal due ... not yet idle for at least 30 seconds

Note that perhaps on the same screen (Advanced), you'll have to adjust the "Natural break active threshold" as well, mine is set to 30 seconds. After the problem is fixed, be sure to disable "Output scheduler logging" as well.

2023-04-04 Kafka introduction tip

If you need an introduction to Kafka, here's a very nice YouTube video on the subject: https://www.youtube.com/watch?v=Ch5VhJzaoaI

Note that it's 4 years old, and I'm not sure how fast Kafka moves.

More...

Weblog Archive

Weblog entries 2023

Weblog entries 2022

Weblog entries 2021

Weblog entries 2020

Weblog entries 2019

Weblog entries 2018

Weblog entries 2017

Weblog entries 2016

Weblog entries 2015

Weblog entries 2014

Weblog entries 2013

Weblog entries 2012

Weblog entries 2011

Weblog entries 2010

Weblog entries 2009

Weblog entries 2008

Weblog entries 2007

Weblog entries 2006

Weblog entries 2005

Weblog entries 2004

All weblog entries

Articles

Articles, chronologically (latest first). This is pretty old stuff.

Scribblings

Not yet finished. Maybe will never be finished. Maybe they'll get deleted. Who knows?

Programming:

System administration:

Others:

Files: