Make Money Outside the Mac App Store book cover

My book is out: Make Money Outside the Mac App Store.

Own your products and know your customers: sell outside the Mac App Store. In a few hours, you’ll have in-app purchases, a trial mode, and piracy protection all set. The book includes fully functional sample projects and code to ready to be copied into your app.

Extract Private Functions as Collaborators

“Using a private function means having a hardwired link to an anonymous collaborator. Over time, this will slowly hurt more.” (@jbrains) I was thinking about this the other day when I wrote tests for a presenter. It receives a date, formats it, and makes the view update a label with the result. Simple. (The real thing actually does a bit more, but that doesn’t matter much.)

Continue reading …

Symmetry

At first, this was all there was:

protocol DisplaysDateRange {
    func showDateRange(dateRange: DateRangeData)
}

class DateRangeViewController: NSViewController, DisplaysDateRange {

    @IBOutlet var dateRangeButton: NSButton!

    func showDateRange(dateRange: DateRangeData) {
        dateRangeButton.title = dateRange.range
    }
}

Then I implemented a sub-view controller and delegated to it, too:

class DateRangePickerController: NSViewController, DisplaysDateRange { 
    // ... 
}

class DateRangeViewController: NSViewController, DisplaysDateRange {
    
    @IBOutlet var dateRangeButton: NSButton!
    @IBOutlet var dateRangePickerController: DateRangePickerController!

    func showDateRange(dateRange: DateRangeData) {
        dateRangeButton.title = dateRange.range
        dateRangePickerController.showDateRange(dateRange)
    }
}

Then, by habit, I remembered Kent Beck’s advise to keep symmetry high for clean and maintainable code:

class DateRangeButton: NSButton, DisplaysDateRange {
    
    func showDateRange(dateRange: DateRangeData) {
        title = dateRange.range
    }
}

class DateRangeViewController: NSViewController, DisplaysDateRange {

    @IBOutlet var dateRangeButton: DateRangeButton!
    @IBOutlet var dateRangePickerController: DateRangePickerController!
    
    func showDateRange(dateRange: DateRangeData) {
        dateRangeButton.showDateRange(dateRange)
        dateRangePickerController.showDateRange(dateRange)
    }
}
petals
Photo credit: Layers of petals by n.a.t.u.r.e. License: CC BY-NC-ND 2.0

Sure, now there’s a subclass of NSButton that doesn’t do much and will not be reused in the app. But the intent of delegating DateRangeData to the sub-components is clearer.

Clean and maintainable code will help you see what’s going on when you read the code. title = dateRange.range doesn’t convey everything showDateRange(dateRange) does.

Always Write Functions to Cope with all Possible Parameter Values

Matt Galagher is back writing at Cocoa with Love. His goal is maintainability, which is the greatest of all, I think. It’s easy to copy code samples together to create an app, bur it’s hard to create a product you can keep alive and make better over years. In that vein, his first article, “Partial functions in Swift, Part 1: Avoidance”, includes a lot of details why partial functions will hurt you. This is a great topic. Read his post for the basic set theory involved.

Continue reading …

Block-Based API vs. Delegates – a Comparison

As I’m exploring the use of block based API, which means to assign closures or functions handles to properties or pass them around as parameters to other functions, I found a few benefits and drawbacks in comparison to protocol-based object interactions. Here’s a breakdown of criteria for blocks and delegates.

Continue reading …

Make Money Outside the Mac App Store now Available on Amazon

book cover

My e-book about creating and selling apps for Mac without the Mac App Store is now available on amazon.com if you prefer a print edition!

Why does print cost less?
The digital edition will be updated regularly with the latest Swift syntax. Further editions and major revisions are free for customers, too. I can’t do that with a print edition on your bookshelf, obviously. That’s why.

It feels weird, I know, because paper costs money and print book feel more precious. I’m making about 50% less with each sale, so there’s quite some cost involved printing the book. The feeling of physical good in your hand is part of the perceived value, and everyone would tell me I should factor that in, but I’m a bad businessman. It’s the right thing to do. Why should you pay more for something with less long-term value only because my costs are higher?

Move! Review at Softpedia

Teaser image

My humble work break timer Move! has been reviewed by Catalin Chelariu over at Softpedia. I didn’t find any Twitter account or anything to thank him, so here it is: thanks for the review!

Catalin had one wish, though:

However, it would be great if there was an option to postpone the break, as it simply may not be possible to interrupt your current activity in certain situations.

I have to say that I totally understand where this comes from – I used AntiRSI and similar software in the past which offered a postpone button. It was useful. But it was also opening the doors to hell.

So I’m sorry to say that if your job demands you to sit down for whatever reason, then Move! isn’t going to be your app. It’s made for everyone, because everyone needs to get up more often. 30mins really isn’t that bad. Some corporate environments don’t care about your health, though, so you may need to increase the work duration.

What I wish for this app myself is the ability to start a break early, i.e. when I have to leave the desk for a while. Or a setting for work hours, so that it doesn’t interfere me watching a movie after 9 p.m., for example.

Subscribe to the Clean Cocoa Newsletter!

Write clean code effortlessly and become a happy programmer. Let me help you get the latest recommendations on time. No spam, guaranteed.

* indicates required