What to Do When You Want to Affect the Order of Subscription Callbacks in ReSwift

This blog post was originally meant as a reply to the ReSwift issue “Any way to control the priority of subscription callbacks?” – If you find asking yourself this question, this should help. This implementation detail is hidden by design. If you find yourself wanting to affect the order of subscription callbacks, there’s a concept of a sequence waiting to be extracted somehow. Or, the other way around: if you want to affect the order, your design is wonky.

Continue reading …

Processing David Epstein: Range (S01E02)

I uploaded episode two of the book processing video series on David Epstein’s book Range:

In this episode, I process the few highlights from Chapter 1. I end up with many more links than last time already. I also employ the method of creating a forward-link, i.e. adding a link to a note that does not exist but that I need at a certain location in my structure note, then add the details. The upside: you already have 1 connection!

Episode list:

  • Episode 1: Introduction
  • Episode 2: Chapter 1, “The Cult of the Head Start”
  • Episode 3: Chapter 2, “How the Wicked World Was Made”
  • Episode 4: Chapter 3, “When Less of the Same Is More”
  • Episode 5: Chapter 4, “Learning, Fast and Slow”
  • Episode 6: Chapter 5, “Thinking Outside Experience”

Add an Internet Access Policy to Your App

The devs of Little Snitch came up with a convention to annotate network traffic, so to speak. It’s called “Internet Access Policy” and will show the purpose of your app establishing a connection in Little Snitch’s warning dialogs.

It is implemented by adding a InternetAccessPolicy.plist to the app bundle with a dictionary of connection details. This could potentially be used by other 3rd party firewalls as well. That’s what I like most about it: it provides useful information to end users without locking developers into anything. A Property List is innocent enough and could potentially spawn other uses.

Look at the project website to see how many of the big names have added IAP’s to their apps already, plus yours truly: Acorn, BBEdit, MindNode, Ulysses, Paw – and many others.

This reminds me of a time 10 years ago when macOS didn’t support tagging of files, yet, and the OpenMeta tagging convention was introduced by indie devs and became a roaring success with various productivity apps.

Calendar Paste v3.3.0 Hits the App Store

Teaser image

I have just released an update to my very first commercial app, Calendar Paste. It’s now v3.3.0 and sports iOS 13 compatibility, Dark Mode, and overall better layout. So it’s mostly a cosmetic and “minor tweaks” update.

Calendar Paste 1 was introduced back in late 2012. That’s 7 years ago! So, happy birthday, Calendar Paste!

To celebrate, Calendar Paste 3 will be available for free from Oct 1st until Oct 6th, and then 50% off until the end of October. The App Store listing doesn’t seem to be updated despite it being “Ready for Sale”, for whatever reason, though. Maybe it’s already fixed when you read this. v3.2 will work just fine, but not sport Dark Mode, yet.

The app was my first real app project, sufficiently simple to start with, yet interesting enough to be sold on the store.

Calendar Paste 1 kicked off my indie app developer business. I still don’t make a lot of money and have to freelance to stay afloat, but this is a very cool path to have taken. I’m loving it. In case you wonder: it never was a huge commercial success. For 7 years, it brought in something between $3 and $130 per month, with a guesstimated average of $18.53/month. Unless it didn’t sell at all, that is. So much for the dreams of yours truly in 2012 to get rich quickly, right? But I learned to code in Objective-C, use Core Data, program for iOS 5 (and then iOS 6 before the app was finished). That’s worth a lot.

That’s why I don’t sunset Calendar Paste, even though each year’s iOS update takes away time for maintenance. And I cannot warrant to add all the planned features to the app because the time is better spent on other, larger projects.

I also wrote a diary of the progress, taking extensive notes in a tutorial-like fashion, that I eventually wanted to publish as a $5 ebook – but I never did. It just didn’t seem to be worth the trouble, and shortly after most of the code was already outdated, and the lessons learned not easily applicable to Swift.

Sorry if you’re still waiting for iCloud sync. It’s theroetically possible, but would take about a week or two to implement and test, and that’s just too costly at the moment. One day I’d like to out-source development of features like this, but to do that I’d need to accumulate larger savings – so either me or someone else working on the app depends on the same solution and y’all have to hold out a bit longer.

Always Ask for MailChimp Newsletter Reconfirmation Outside of MailChimp

When you want to merge newsletters in MailChimp like I do and tell your subscribers to sign up at the new list and unsubscribe from the old to not receive any notifications – then you’re setting yourself up for trouble! Because it turns out that mass-migrations from list A to list B mostly register as mass unsubscribes from list A. And an unsubscribe rate of 9% or higher (I don’t know the actual minimum value, but 9.23% triggered it for my account) will automatically up the risk level of your whole MailChimp account.

Continue reading …

Don’t Wait. Show Up. Or It Might Be Too Late Again

When someone close to the family dies, a lot of dust is stirred up. My godfather died last week, and I was informed that his burial will be tomorrow – more by accident than by plan. We hadn’t talked in 5 years, and in late 2018 I became curious what he and his wife were up to. Why not visit them for a change, since they don’t come visit anymore? I was at their place a couple times, but most of the time, like once every month plus for birthdays or so, my godfather and his wife visited us at home, back when I lived with my father.

Continue reading …

Processing a Book to Extract Notes, a Video

For the Zettelkasten knowledge project, I’ve recorded and cut my first video. The process was a pain, and I think I’m going to write about it later – but for now, I’m happy with the result and very proud to have finished this mini project.

It’s part of an ongoing series to demonstrate the method we talk about on our blog. Here’s the video:

Comments are very, very welcome. So head over to the forums and tell us what you think of it!

Episode list:

  • Episode 1: Introduction
  • Episode 2: Chapter 1, “The Cult of the Head Start”
  • Episode 3: Chapter 2, “How the Wicked World Was Made”
  • Episode 4: Chapter 3, “When Less of the Same Is More”
  • Episode 5: Chapter 4, “Learning, Fast and Slow”
  • Episode 6: Chapter 5, “Thinking Outside Experience”

Make Money Outside the MAS v2 Book Writing Stage is Done

My ebook update routine has changed a bit for Swift 5 this year: I’ve expanded the “Make Money Outside the Mac App Store” book typoscript a lot. It’s about twice as long, with many more explanations for the setup, many new additional feature discussions, and practices that I’ve learned of in the last years. FastSpring’s revamped store kind of forced me to re-take screenshots anyway, so I figured I might as well take more.

Continue reading …

Newsletter Revival

Not everybody knows how to consume RSS, so I wanted to try to make updates to the blog available via email. That’s why I have now revived the newsletter signup page. This is the plan: I’ll experiment with this setup for a while, but I think the current options cover almost anything I currently do, or plan to do, so that both developers and customers of my apps get something interesting in their mailboxes.

Continue reading …

Please Also Change Your Feed URL’s Inside Your Apps

In my post about redirecting the DevMate update feed, I missed the opportunity to mention that you should probably also update your app very soon to not rely on DevMate’s framework.

Mr Boy van Amstel at Danger Cove picked up the topic and explains how you can change your feed URL inside the app using the Sparkle SUUpdaterDelegate methods. DevMate’s closed-source framework wraps this in its DM_SUUpdaterDelegate_DevMateInteraction protocol.

Your battle plan thus should be:

  1. Redirect the remote feed URL to deploy updates to existing customers working with old versions, and
  2. Change the feed URL used inside the app as soon as possible and deploy an update to not rely on the redirect for too long.

I use the SUUpdaterDelegate to switch feed URL’s in The Archive and WordCounter, too, in case you wonder if this is a good idea in the first place.

See also:

I Am at Macoun 2019

I’ll be at this year’s Macoun developer conference in Frankfurt (Main) again. This time, I’m not giving a tech talk, but hosting a workshop with Oliver Böhm. The Macoun is a German conference, and it isn’t expensive. I think that’s a great combo. You should go if you can. The community, or family, built around the conference over the past dozen years is very, very welcoming. You cannot not learn something when you attend.

Continue reading …

Wireframe for Server-Side License Activation

Server-side app license code validation, as I imagine it, in a nutshell: If the token expires and there’s no server connection, you have to figure out how punishing you want to be. I suggest you do not punish by default and assume people have good intentions. Possible escalations: Remote or server-side deactivation of licenses can be useful to prevent continued use after refunds.

Continue reading …

Become an Acquired Taste

Seth Godin points out that people usually say “an acquired taste” as if that is something bad. I never thought about this phrase much, but he does have a point here. Indie developers and creators in general should consider to be a pleasure for the introduces few: that thought is in line with getting your first 1000 true fans, and everything the crew at Basecamp (formerly 37 Signals) around Jason Fried preach for years. Retain your individuality. Make something that is indispensible for people instead of making a throwaway mass product.

Continue reading …

UINavigationController Inside a Popover

Noah Gilmore wrote about his approach to use UINavigationController inside a popover without subclassing the navigation controller. Even though I don’t work on iOS apps, like, at all these days, this sounds too useful to go by unnoticed.

Hopefully this was a helpful look into the world of preferredContentSize, view controller wrapping, and UIKit popovers. Here’s a tl;dr:

  • To define the size of your popover with autolayout, set preferredContentSize to the result of systemLayoutSizeFitting
  • To animate popover size updates at the same time as navigation controller animations, wrap your UINavigationController in a PopoverPushController (see code below)
  • When you change your controller’s preferredContentSize, be sure to change the preferredContentSize of your controller’s popoverPresentationController’s presentedViewController as well

See NGPopoverForceResizeTest, the resulting sample app on GitHub.

With DevMate Closing Shop, Here’s What You Can Do

Teaser image

DevMate are closing their doors. The announcement isn’t news anymore, but since I didn’t use their service, I didn’t think much of it. I did report back in 2016 when they changed their pricing model. Nowadays I discover more and more people struggling to migrate away, and my blog pops up in their searches – apparently because I wrote a book on selling apps on FastSpring.

Continue reading …

Prying Open the Vanilla Forum Control Flow to Create Discussions in Embedded Forms

We’re using a Vanilla Forum for the Zettelkasten Method and ME Improved. It’s a PHP-based forum, and I like how modular it’s built. Writing plugins and themes isn’t a pain, and that’s something in my book already. It also allows us to power the comments with the forum. When you are the first to write a comment, the built-in “System” user creates a discussion with the blog post’s title and a short excerpt and your comment is added.

Continue reading …

Detect When Your macOS App Has Been Moved During Runtime

Daniel Jalkut of MarsEdit fame released a little Swift helper to detect when a macOS app has been moved during runtime. His write-up explains everything. In short, moving an .app bundle while the app is running will inevitable result in resources not being found, and occasional also in crashes.

This or a similar helper is a practical necessity in all applications that are distributed outside the Mac App Store.

  • Check out RSAppMovementMonitor on GitHub.
  • The long defunct LetsMove used to be a tool that tried to prevent the issue by offering to move the app to /Applications upon launch from any other directory.

Live FastSpring Store Examples

Teaser image
The demo page with a modal shopping cart shows perfectly how you can make your own website into a store; you don’t need to switch to an e-commerce website provider at all!

I discovered the FastSpring Examples page the other day. There, you can interact with different store setups to get a feeling for the capabilities of FastSpring’s new and updates Store Builder API. The examples also either include or link to documentation pages and CodePen-like source code demos.

All in all, I think this is a very cool addition to the docs.

When you play around with the examples, you will see that the new store styles aren’t just for fancier checkout pages. The new store has an API that you can easily (!) use to transform even a static HTML website into a dynamic store front, including a live shopping cart. This is very, very powerful.

See also:

Looking for a Family Altar’s Totem

Last December, my grand-father died. His breathing got shallow, he wasn’t hungry all of a sudden, then went to take a nap in his favorite chair. There, he slowly, and I hope painlessly, began to tune out a bit, fall asleep, and eventually cease to … live. In the days after his death, I helped a bit with the funeral preparations, and I take care of my nearly blind grand-mother once a week ever since. I spent a lot of time with my grand-parents. We were pretty close. I love them, and so I begin to crave for some kind of totem that keeps a piece of my grand-father’s live somewhere visibly in my life.

Continue reading …