Setting the Line Height of a NSTextView

NSTextView (and UITextView for that matter) have a defaultParagraphStyle attribute where you can set the text’s line height. That works swell – if you display text statically. Once the user can enter something, you can run into trouble: It’s your usual RTF nightmare. I know this behavior from rich text editors; and I developed my own way to make sense of it in the process. It might not be what is really going on, but it’s a good heuristic: it’s just like the opposite of making a word bold, placing your cursor after that word, type, and get more bold text. There, the “bold text” information is carried on. The cursor inherits this info from the character left to it. But if you start at the beginning of a line, your cursor will not inherit what comes afterward. And since there is nothing before its position, it starts with empty info, and thus empty line height settings. Since the whole paragraph is affected by this, the latest change wins. Beginning to type at the beginning of a paragraph with empty paragraph settings removes them from what comes afterwards.

Continue reading …

Handle Pending File Changes with ReSwift as Your Backbone

Teaser image

Automatic saving of changes in some user interface component to a file should be handled differently when you employ ReSwift. In short, you have to extract the state information from the “save file” action and store it in the overall app’s state somehow. I append these to a collection of PendingFileChanges, a ReSwift.StateType that is part of my overall app state.

Continue reading …

Recording of Wednesday's Webinar

Sadly, the recording doesn’t contain the webcam stream. I find videos like this pretty hard to follow. Especially if the speaker isn’t native English, then it can be quite a pain sometimes. I hope it’s not too bad in this case!

I promised not to distribute any follow-up material until next week so that webinar attendees have early access.

But you can get a 20% discount on “Make Money Outside the Mac App Store” by using the coupon code MORECONTROL, good until March 31st!

Register for My Webinar About Ditching the Mac App Store

I will be hosting a webinar about distributing your app outside the Mac App Store next week. It’s free, and you’re very welcome to attend!

Wednesday, February 15th, 2017 @ 10:00 AM PST (will run 1 hour)

→ Register Now

Topics include:

  • Ditching the Mac App Store – Why, and what it means.
  • Is There Life After the Mac App Store? – Choosing an e-commerce provider.
  • Getting Back to Development – How you change your code to work outside the Mac App Store.

Plus you’ll see me live. That alone should be motivation for you to visit, no matter the topic :)

Disclaimer, aka Code of Honesty and Transparency

Maybe you just arrived on my blog and don’t know how I do things around here, yet, and how much I value morality over profit anytime. So let me erase your doubts about this webinar cooperation.

I use FastSpring to sell my stuff. I really like their service, so I wrote a guide in 2015. FastSpring in turn was impressed by my initiative and helped me spread the word a bit and provide background info whenever I needed anything. I am not getting paid by FastSpring for the book. It’s my own creative work. I maintain it because I think it helps you, fellow developer, to set up your own indie business.

Then late 2016, FastSpring approached me as their go-to expert for Mac app development. They plan to show how easy it is to use FastSpring to distribute Mac apps. In other words, they want to own part of the good news for obvious marketing reasons.

With the recent Out-of-App-Store Success Stories by Rogue Amoeba and Kapeli, it may even be a growing market.

I was skeptical at first. I will not violate my strong ethics; teaching people the One True Way™ is more important than easy money. But I came to find FastSpring values delivering useful content over running a 60-minute ad show. From the get go, FastSpring wanted me to create the content. Not even once did they suggest I add something to my slides. They totally risk I go live on Wednesday and tell people to use a competing service. But I won’t, because I know no better service provider. I liked the concept, so I agreed. I am getting paid by FastSpring for this webinar gig. But it’s 100% my webinar.

To stay true to myself, I will give genuinely helpful advice to empower the attendees to become independent. Of course I’ll show FastSpring’s features, just like the screenshots I put in my book. All because I believe in their service, not because they bought my loyalty with the speaker fee.

In short, this is not an advertisement for FastSpring. I haven’t sold my soul. It’s a cooperation out of mutual respect.

Hope to be seeing you around on Wednesday!

Express Either–Or-Relationships as Enums

If you want to encapsulate the notion of “either A or B” (also called “lifting” in functional parlance), an enum type in Swift is the best fit: You can use associated values to wrap types with enums, too: These things seem to be expressible through a common ancestor type or protocol. But bananas and apples can be modeled in totally different manners (apart from sharing nutritional value, for example).

Continue reading …

Core Data is Invasive. You Can Hide It, Or You Can Embrace It

Found this nice post about using Swift protocols to expose read-only properties of Core Data managed objects so you don’t couple your whole app to Core Data. Using Swift protocols in Core Data NSManagedObjects is a great way to limit the visibility of properties and methods. In my 1st book on Mac app development I talked about this, too, and this is a lot easier to handle than a custom layer of structs that you have to map to NSManagedObject and back again. Core Data is designed to be invasive and convenient. It’s not designed to be used as a simple object-relational mapper.

Continue reading …