Latest Posts

WebcamSnap Open Source Library Released

The picture cropping sheet in action

Another month goes by, another little macOS component was released.

This time, I wanted to have a very simple drop-in view component that takes pictures with the iSight camera of MacBooks or any other connected USB camera device. And if the user wants to crop the picture, I wanted to add that as post-processing.

Thought this would be a common need, but Google wasn’t helping much. So I coded this thing myself.

Have a look: https://github.com/CleanCocoa/WebcamSnap

How Taking Pictures with AVFoundation Works

Before I got it working, all the AVFoundation code looked pretty scary. But it’s simple, really, when you think about the possibilities of audio and video capturing and processing.

These are the requirements to take a photo with a USB camera using AVFoundation:

  1. you need a AVCaptureSession that controls the lifetime of the audio and/or video input and/or output;
  2. you specify output ports of type AVCaptureOutput, like the AVCaptureStillImageOutput I use here to grab a single image (instead of video or audio);
  3. you specify input ports of type AVCaptureInput, like the AVCaptureDeviceInput that takes a AVCaptureDevice, which in this case is of type AVMediaTypeVideo;
  4. you add a Core Animation layer (CALayer) to a preview view using AVCaptureVideoPreviewLayer(session:) so users see what the camera is showing before they hit the “Take Picture” button.

If things work out well, you have a session that can read video data from your camera device and streams the video signal to the preview. You can shoot photos, also known as “request still images” from the video stream, using captureStillImageAsynchronously on your AVCaptureStillImageOutput.

All of this setup is encapsulated in the Webcam object of my library. (links to the version of v1.0.0, no the latest, to prevent dead links in the future).

Hope it helps!

Do You Need to Use Action Creators in ReSwift to Conditional Action Dispatching? (No)

This is an answer to a StackOverflow question titled “When, why and how to use Action Creators in redux?” that is really targeted at ReSwift. The real question is phrased a bit differently, though:

For example, I have a button, after user pressed it I want to start some process if I’m in state A. So, I have to write an action creator, which will check current state and then return correct action, or not action at all. Then dispatch this action from the same place.

Redux.js and ReSwift behave quite differently. Redux recommendations may not apply in all cases.

Clearing up Redux.js/ReSwift confusions

Action Creators in ReSwift

“Action creators” is a rather specialized term in Redux.js, but the type is defined like this in ReSwift as of v4:

public typealias ActionCreator = (_ state: State, _ store: Store) -> Action?

So contrary to general advice, you do have access to the state at the point of dispatching the action. You don’t need a Thunk implementation, although Thunks or Epics can help in more complex cases.

“Action Creators help encapsulate action creation details”

A common benefit of Action Creators in Redux is their function as a factory.

Redux.js actions are object literals. Redux actions, if you were to write them in Swift, would be more like Dictionarys. If you come from an Objective-C background, you know both the good and bad of dictionaries: they are flexible, but you can cause trouble with typos, and the compiler won’t catch changes to values or keys if they are stringified. That’s how Action Creators in Redux.js provide the convenience of factories (as in “Factory”, the Gang of Four design pattern).

Here’s one as an example:

function addTodo(text) {
    return {
        type : "ADD_TODO",
        text
    }
}

// Somewhere else
dispatch(addTodo(text))

The ReSwift.Action type is usually implemented in custom value types (structs), though. ReSwift does not suffer from that problems of Redux.js actions. That means by creating a custom action type in ReSwift, the benefit of centralizing action creation in one function goes away. The initializer of your type does provide this already.

That paints a totally different picture.

And that’s probably why ReSwift.Store.ActionCreator passes in the state: to provide any benefit at all. At the cost of a different kind of API than Redux.

Application to the Question

Recall the question:

For example, I have a button, after user pressed it I want to start some process if I’m in state A. So, I have to write an action creator, which will check current state and then return correct action, or not action at all. Then dispatch this action from the same place.

There are a couple of ways to achieve that.

If you have access to the store variable to call dispatch, you also have access to its current state property. You can ask the store for the state the app is in and act accordingly. Usually, you’d write store subscribers to get “push notifications” of store changes, but in cases like this you can also ask the store.

That means the following would be a totally valid implementation:

let currentState = store.state
let action: Action = {
    if currentState.someSubstate == "A" {
        return ActionWhenInStateA()
    } else {
        return ActionWhenNotInStateA()
    }
}
store.dispatch(action)

Since ReSwift Stores are not supposed to receive dispatch commands from different threads, you can rely on the state from line 1 to be the same in the last line, where you dispatch.

TL;DR: you do not need ActionCreator to achieve this. But you can if you like to write “east-oriented” code, leaning on callbacks instead of property queries:

store.dispatch { state, _ in
    if state.someSubstate == "A" {
        return ActionWhenInStateA()
    } else {
        return ActionWhenNotInStateA()
    }
}

Adding RxSwift Ports to Resolve UI Inconsistencies

I am currently struggling to write my user interface layer (Mac) in a way that works well with RxSwift (the reactive library). Meanwhile, the whole app’s state is maintained by ReSwift (the unidirectional data flow library). Both work well together, but I made some weird choices initially.

For example, I’d write Presenters to subscribe to store changes, assemble a static View Model, then pass that on to the View. That’s all nice and imperatively object-oriented.

But then I wrote the actual view controller (which implements the View protocol) to simply update the UI components like I always did. That worked well, it seemed, up until it suddenly began to cause trouble. At the same time, I’d use RxSwift to publish user-initiated changes as events.

Input and output qdhered to different paradigms. In the case of a NSTextField, you can rely on the .rx.text property to produce a change signal when the user types. But when you set the stringValue manually, it won’t. That was a very nice “feature,” by accident!, because now programmatically changing the text field didn’t fire a change event again. Hooray!

Weeks later, I run into problems with edge cases where sometimes the text field should not be updated for some reason, and sometimes where events should not be fired. The mixture of imperative and reactive input VS output got in the way. The solution, in this case, was to use a naive implementation of a reactive view model. I’d keep both the imperative display(string:) input port and the reactive searchTermChange output port around. But instead of relying on the text field as mediator, I’d add the view model as the local source of truth.

  • When the presenter wants to display(...) something, the view controller receives the value and either changes a RxSwift.Variable or call .on(next(...)) for a RxSwift.PublishSubject. Both types are great to pipe changes through, each with a different set of strengths.
  • Either way the value change will be observed and trigger an update to the text field’s contents in all cases that apply.
  • Typing into the text field triggers a searchTermChange, as already mentioned.
  • Text field changes that are identical to the view model, though, will be ignored! This way the binding of view model to text field will not emit a change event.

Ignoring identical values from two sources typically looks like this (in my view controllers):

// Typing is the source stream of itnerest
textField.rx.text
    
    // Combine typed and programmatically changed 
    // values into a single stream
    .withLatestFrom(viewModel) { ($0, $1) }
    
    // Select typed-in values if they are different
    .filter { new, old in
        new != old }
    .map { new, _ in new }
    .distinctUntilChanged()
    
    // Emit change event
    .bindTo(searchTermChange)
    .addDisposableTo(disposeBag)

It’s awkward that I had to add another RxSwift-based property at first, but in the end it made sense to unify input and output so I can combine both kinds of streams and work with them more easily.

Figuring out when an observable emits events and why or how combinations of streams produce results still is very hard. I think I am developing a fist kind of intuition, though, and when the refactoring has proven to be useful, I’ll distill the lessons into blog posts, of course.

ReSwift v4 Released

I totally forgot to bring this up: ReSwift version 4 was released 13 days ago!

The coolest part (in my opinion) is to skip duplicate states in subscriptions if you want to. The state has to be equatable somehow to do this with the default subscription measurements. But then again you’re using this anyway right now with ReSwift 3.x, only for every subscriber.

store.subscribe(subscriber) {
  $0.select {
    ($0.testValue, $0.otherState?.name)
  }.skipRepeats {
    return $0 == $1
  }
}

The skipRepeats in the subscription builder/configuration block will be used automatically if the selected state conforms to Equatable. But you can use your own skipRepeats implementation if needed.

In theory, you could add map and filter and whatnot to the underlying Subscription type that’s being configured in the block you pass to subscribe(), though I don’t see much value in this at the moment.

Drawing Custom Alternating Row Backgrounds in NSTableViews with Swift

This is an old hat in Cocoa: when you change the appearance of NSTableRowViews, they will indeed look different – but the enclosing table view itself will still draw the system default background to fill the space below the last row.

Similarly, when you have scrolling elasticity enabled and scroll above the topmost row, whatever is being drawn there won’t match your custom styled rows, either.

NSTableViews themselves draw the row backgrounds that visually match the NSTableRowView backgrounds, but only in default settings. When you change row backgrounds, you end up with colorful content rows – and regular white & light gray rows above and below the content, filling the gap to the edges of the table’s clip view.

As I said, this is an old hat. But now we work with Swift and all, so I figured I’d share the Swift code I use to draw custom alternating row backgrounds above and below the visible content:

public class CustomTableView: NSTableView {
    
    var alternateBackgroundColor: NSColor = // ...
    
    public override func drawBackground(inClipRect clipRect: NSRect) {

        super.drawBackground(inClipRect: clipRect)

        guard usesAlternatingRowBackgroundColors else { return }

        drawTopAlternatingBackground(inClipRect: clipRect)
        drawBottomAlternatingBackground(inClipRect: clipRect)
    }

    fileprivate func drawTopAlternatingBackground(inClipRect clipRect: NSRect) {

        guard clipRect.origin.y < 0 else { return }

        let backgroundColor = self.backgroundColor
        let alternateColor = self.alternateBackgroundColor

        let rectHeight = rowHeight + intercellSpacing.height
        let minY = NSMinY(clipRect)
        var row = 0

        while true {

            if row % 2 == 0 {
                backgroundColor.setFill()
            } else {
                alternateColor.setFill()
            }

            let rowRect = NSRect(
                x: 0,
                y: (rectHeight * CGFloat(row) - rectHeight),
                width: NSMaxX(clipRect),
                height: rectHeight)
            NSRectFill(rowRect)

            if rowRect.origin.y < minY { break }
            
            row -= 1
        }
    }

    fileprivate func drawBottomAlternatingBackground(inClipRect clipRect: NSRect) {

        let backgroundColor = self.backgroundColor
        let alternateColor = self.alternateBackgroundColor

        let rectHeight = rowHeight + intercellSpacing.height
        let maxY = NSMaxY(clipRect)
        var row = rows(in: clipRect).location

        while true {

            if row % 2 == 1 {
                backgroundColor.setFill()
            } else {
                alternateColor.setFill()
            }

            let rowRect = NSRect(
                x: 0,
                y: (rectHeight * CGFloat(row)),
                width: NSMaxX(clipRect),
                height: rectHeight)
            NSRectFill(rowRect)

            if rowRect.origin.y > maxY { break }
            
            row += 1
        }
    }
}

I don’t attempt to draw row backgrounds in my NSTableView here. I leave that to the NSTableRowView itself. And its color is set using the NSTableViewDelegate.

func tableView(_ tableView: NSTableView, didAdd rowView: NSTableRowView, forRow row: Int) {
    
    guard let tableView = tableView as? CustomTableView else { return }
    
    rowView.backgroundColor = row % 2 == 1
        ? tableView.backgroundColor
        : tableView.alternateBackgroundColor
}

If you don’t just want a solid background but draw custom bezeled borders or something even fancier instead, putting everything into the table view drawing code may pay off because you can leave the drawing code in that single place. Your row views will then have to be transparent.

One Way to Solve Inexplicable Race Conditions in Tests

Today I wrote my first asynchronous test in my latest project and suddenly, during the waitForExpectations run loop, a totally unrelated test’s stuff crashed. To make things worse, it was part of an RxSwift subscription. No idea who kept that alive and where the EXC_BAD_ACCESS really originated.

It helped to make sure that no object references are kept around longer than necessary. In unit tests, this can mean to make your test doubles and collaborating objects optionals:

class BananaTests: XCTestCase {

    var banana: Banana!
    var tree: Tree!
    var monkey: Monkey!
    
    override func setUp() {
        super.setUp()
        tree = Tree()
        monkey = Monkey()
        banana = Banana(on: tree, eatenBy: monkey)
    }
    
    override func tearDown() {
        tree = nil
        monkey = nil
        banana = nil
        super.tearDown()
    }
}

If you just go the lazy route and make the objects properties of the BananaTests class, the objects will be kept around until all tests have finished and the BananaTests instance is being disposed of. With the setup–tear down dance here, we manage to get rid of references right after each test execution.

In case you wonder what the lazy version looks like where the latest references are kept alive:

class BananaTests: XCTestCase {

    var banana: Banana!
    let tree = Tree()      // <- uh oh
    let monkey = Monkey()  // <- guess who stays around ...
    
    override func setUp() {
        super.setUp()
        banana = Banana(on: tree, eatenBy: monkey)
    }
}

I’d love to tell you now that this solved my problem. (It didn’t.) Instead, I want you to keep this in mind as a potential source of problems. Tests for NotificationCenter subscribers will are a great example of problematic tests: the subscribers will continue to receive notifications when other test suites run.

SwiftyBeaver: Record to Array

I am using SwiftyBeaver in TableFlip and my latest project. Doing some robust console and file logging is important, and this library seems to work just fine for my needs.

Except for error reporting. I do not want to attach the whole debug log when folks may report a simple problem. So I figured: maybe it’ll help to have the last 5 or 10 log messages attached upon a first error encounter.

So I wrote a SwiftyBeaver “in memory” destination that is set up next to a file and a console destination:

class InMemoryDestination: BaseDestination {

    var maxHistory = 5
    fileprivate(set) var messages: [String] = []

    override func send(_ level: SwiftyBeaver.Level, msg: String, thread: String, file: String, function: String, line: Int) -> String? {

        let formattedString = super.send(level, msg: msg, thread: thread, file: file, function: function, line: line) ?? "\(msg) (formatting error!)"

        messages = Array(messages
            .appending(formattedString)
            .suffix(maxHistory))

        return formattedString
    }
}

As a means to access these messages, I use a free function-like global closure:

let error = ...
let logMessages = lastLogMessages().joined(separator: "\n")
reportError(error: error, additionalInfo: logMessages)

Here, lastLogMessages is a closure so it can be swapped during runtime:

fileprivate(set) var lastLogMessages: () -> [String] = { return [] }

This then comes in handy when I set up my SwiftyBeaver logger:

let console = ...
let file = ...
let inMemory: InMemoryDestination = {
    let inMemory = InMemoryDestination()
    inMemory.maxHistory = 10
    inMemory.format = "$DHH:mm:ss: $M"
    inMemory.asynchronously = false

    // Here create a closure that points inside the InMemoryDestination:
    lastLogMessages = { return inMemory.messages }

    return inMemory
}()

SwiftyBeaver.addDestination(console)
SwiftyBeaver.addDestination(file)
SwiftyBeaver.addDestination(inMemory)

And that’s it! I get a buffer of 10 log messages and read access to said buffer when I prepare error report emails.

One step closer to releasing a version into the wild.

Swift Protocols with Default Implementations as UI Mixins

Oliver Drobnik of Cocoanetics posted a little gist about a protocol that offers pull-to-refresh for your UITableViews: https://gist.github.com/odrobnik/ae16f4f071ead51d915712818a2279d8

@objc protocol Refreshable
{
    /// The refresh control
    var refreshControl: UIRefreshControl? { get set }
    
    /// The table view
    var tableView: UITableView! { get set }
    
    /// the function to call when the user pulls down to refresh
    @objc func handleRefresh(_ sender: Any);
}


extension Refreshable where Self: UIViewController
{
    /// Install the refresh control on the table view
    func installRefreshControl()
    {
        let refreshControl = UIRefreshControl()
        refreshControl.tintColor = .primaryColor
        refreshControl.addTarget(self, action: #selector(handleRefresh(_:)), for: .valueChanged)
        self.refreshControl = refreshControl
        
        if #available(iOS 10.0, *)
        {
            tableView.refreshControl = refreshControl
        }
        else
        {
            tableView.backgroundView = refreshControl
        }
    }
}

I use protocols for interface abstractions in my model and service layer a lot; but in the UI, I often resort to delegation to classes. I almost never use protocols in the UI that come with default implementations. Now that I think about it, I believe most custom protocols that I do implement in the UI layer are of DisplaysBananas kind – implementations for the view protocol of a presenter.

Oliver’s gist made me think about other techniques to separate concerns in the UI. Not just delegation to sub-view controllers and encapsulation of view data in structs, but maybe a few more protocol abstractions here and there. When they make sense, that is.

Clean Cocoa Blog Redesign

I started and kind-of-finished this step after TableFlip’s release back in November 2016. But then I never pulled the trigger. So the redesign and usage of the cleancocoa.com URL didn’t really happen. Until today.

The website is now hosted on GitHub Pages. And I’m working on building a knowledge base as wiki. Since the website is hosted on GitHub, everyone can propose changes.

I want to provide higher-level knowledge about iOS and macOS software application development. It’s okay to host lists of components/libraries for certain tasks. But these things change fast, and I cannot keep up with maintaining a list of libraries by myself.

I believe manual curation of knowledge is the only way to make starting application development feasible. Googling will only bring up popular results; but personal recommendations may provide a totally different angle.

So here’s to the next step in my grand scheme to empower Cocoa developers on every level, from code to marketing and lifestyle choices.

My personal website at christiantietze.de will gradually transition to an overview about all my projects. There was no headquarters for my apps until now. My personal website will now become such a place, including “press releases” and update announcements. Stuff my app business customers might be interested in, but programmers, not so much.

Browse the archive

Subscribe via RSS