Introducing Big Red Button for Apple Watch

Are you the president of a nuclear weapon wielding superpower? Congratulations! There’s an app for that.

Introducing the “Big Red Button” app for the Apple Watch — launch the nukes from the convenience of your wrist.

Targeting has never been so easy with a variety of options:

  • Select your target destinations with Siri dictation. Relies on Apple Maps. It’s never wrong
  • Tap a location on a zoomable map
  • A Favourites list of your colleagues from other countries will automatically target their location
  • Quickly rotate and let go of the digital crown to randomly select from a list of predefined targets and let it go. We call this feature “Atomic Russian Roulette”. It’s addicting, you’ll want to rotate and rotate!

Additional groundbreaking features include:

  • Approve launches by signing with your finger on the watch face or by dictating “Sure, why not”
  • Satellite view and the map update in almost-realtime after the target is hit by downloading latest imagery from military satellites. Terraforming has never been so fun
  • Feel the hearts of your enemies stopping with the fantastic haptic feedback of your new toy. (Requires an In-App-Purchase of a backdoor access to their Apple Watches)
  • Uses Force Touch technology to select the size of the warhead. Press harder to hit them harder
  • Game Center integration to compete with your foes, complete with Leaderboards and Achievements

Download now or you’ll be out of the game first!

My most successful client project

Successfully completed a client project in record time and budget by convincing the client that there’s no need for it.

Of course I wasn’t paid for the couple of hours it took me to research the idea and communicate my thoughts on it with the potential client. But it was the correct thing to do and I’d do the same again. Going for it could’ve ended very frustrating to all the parties involved.

Song: Cocoa Police

I covered Radiohead’s Karma Police with modified lyrics about some of the attitude towards Apple’s new programming language, Swift, that I saw on the net.

It’s meant to be fun. Lyrics embedded in the video. Enjoy.

App Camp for Girls and an interview at AppStories

I’ve been following the App Camp for Girls project since it started not a long time ago. App Camp for Girls is a non-profit founded by my friend Jean MacDonald from Smile. Its mission is:

App Camp For Girls wants to address the gender imbalance among software developers by giving girls the chance to learn how to build apps, to be inspired by women instructors, and to get exposure to software development as a career.

They’re currently raising funds for the project, so consider donating to this fine endeavor. While it’s already reached its initial funding goal, they’re thinking about expanding the program to additional locations, so any contribution will help.

To inspire young people to learn application development they started App Stories, where they interview developers about their first steps in software development.

There are already several interesting interviews available from developers and designers, including an interview with yours truly. More interviews with seasoned developers are going to be published on the site later, so you might want to add it to your RSS feed.

Have I already asked you to donate? Just a reminder. 🙂

Toggle hosts file for less distractions (in Haskell)

I decided to edit the /etc/hosts file to block access to some domains that I compulsory visit when working, in order to reduce my distractions. The usual suspects are Twitter, Facebook, Hacker News, and some real-world news sites.

So I edited the file and added the following lines:

# -- WORK --

Now they’re blocked. But I also wanted the option to quickly comment this section out and back again.

I could do it quickly in Ruby but I thought that it would be a great way to exercise my basic Haskell skills.

It took me quite a while to get it right — my Haskell is rusty. But after it compiled, I only had one little logical bug, which I quickly found out and fixed.

The final code is below. It also backs up hosts file (just in case) and prints the resulting hosts file. Both of these steps could be removed, as they’re not important for its main functionality.

import Data.List

-- Starts toggling the comment after a line that starts with "# --"

processLine switch line
    | length line == 0                          = (switch, line)
    | switch == False && take 4 line == "# --"  = (True, line)
    | switch == True                            = (True, toggleLine line)
    | otherwise                                 = (switch, line)
      where toggleLine l
              | head l == '#' = tail l
              | otherwise     = "#" ++ l

process = snd . mapAccumL processLine False

main = do
  hosts <- readFile "/etc/hosts"
  writeFile "/etc/hosts.backup" hosts
  let newHosts = unlines $ process (lines hosts)
  putStrLn newHosts
  writeFile "/etc/hosts" newHosts

I’m sure this could be done shorter, as everything in Haskell, but I’m just a beginner.

I then compiled the code and put the binary in my user’s bin folder.

Since it edits the /etc/hosts file, it has to be run with sudo. I added a line to sudo permissions (run sudo visudo to edit the file) to allow me to run it without a password:

jacob ALL = NOPASSWD: /Users/jacob/bin/switch_hosts

Then, I added an action to Keyboard Maestro to run sudo /Users/jacob/bin/switch_hosts using a trigger in its system menu. You could do a hotkey trigger or use a TextExpander expansion, or use LaunchBar, or Alfred, or just type it in the Terminal.

It just was this kind of day. I couldn’t do real work, but I could play a little to make my environment better for when I’ll be able to work.

Of course, there are commercial products that can help with distraction-free work environment, like Concentrate, which offers this and more. But I prefer to run less applications, if possible.

Introducing ReactiveCoreData

Lately I’ve became seriously interested in the fantastic projects that several bright guys at GitHub open-sourced. I’m talking about ReactiveCocoa and some of its derivatives, like ReactiveCocoaLayout. If you don’t know what these are, first go and read about them. I’ll wait.

While working on UI code for Cashculator 2, I decided to utilize both of above frameworks and, so far, I’m very happy with my decision. Especially I loved how ReactiveCocoaLayout allowed me to create behaviors similar to Cocoa’s AutoLayout, which I can’t use in Cashculator for performance reasons.

Like many applications, Cashculator uses Core Data for data persistence. So I had the idea of trying to bring Core Data into the ReactiveCocoa world.

Thus, ReactiveCoreData (RCD) was born. I’ve already implemented most of the basic functionality that I wanted to include in a hypothetical 1.0. Or is it 0.1. There’s also a proof of concept demo application for the Mac, which shows only a little of how to use it.

But there are also specs which verify all the functionality, which include easy fetching, insertion, performing stuff on a background context, saving, merging. All of this in the ReactiveCocoa’s signals domain, so it looks neat and can interoperate with your other ReactiveCocoa world.

A short example:

RAC(self.filteredParents) = [[[[Parent findAll]
  where:@"name" contains:filterText options:@"cd"]

This will update filteredParents property (an NSArray) to the all the Parents whose name contains text in the signal filterText (that comes from a search field, for example), sort by name and fetch.

It will fetch when either the filterText signal sends a next value or when objectsChanged signal fires (it will fire after new Parent objects were added or removed, for example).

The where: and sortBy: commands modify the NSFetchRequest that’s started with the findAll method of Parent and pass it next. Then, fetch: runs the NSFetchRequest in the current NSManagedObjectContext and sends the NSArray of the result, which gets assigned to self.filteredParents.

There’s more to ReactiveCoreData than that, but it’s a nice example.

Check ReactiveCoreData on GitHub.

I’ll be happy to get any feedback: suggestions, critique, pull requests. Use GitHub, if possible.

If you prefer to give feedback over Twitter, I’m @apparentsoft. But you better use I’m @apparentsoft over there as well.

Orange is the new Blue

Ever since Microsoft Windows days the blue color was the dominant hue used in user interfaces. Blue is considered to be comfortable on the eyes, especially when used as background and other large surfaces in the user interfaces.

In HTML, the default link color is also blue. It’s distinguishable from the default black while still possessing the “blue” qualities of being easy on the eyes.

But in the last year or so I notice following trend:

orange is the new blue

Several prominent publications had designed or redesigned their sites to use a darker shade of orange as the main emphasis and link color. The Verge, The Next Web and Ars Technica are now all look similar, as far as their main color palette goes:

Ars technicaThe vergeThe next web

Don’t get me wrong. I actually do like the new designs. I especially love the design on The Verge. It was the first site where I saw orange used prominently. I think other have followed, though I believe that Ars used the orange cycle in its logo for a long time and some of its elements were orange then, but the new design is much heavier on the color. Same with The Next Web. I believe it had more red colors in its old design and certainly not so much of orange.

I wonder if other big sites will follow this trend:



I’m @apparentsoft both on Twitter and on

Software Architecture cheat sheet

For the past several weeks I’ve been focusing my efforts on learning how to approach software architecture. Despite my experience in developing several applications, I wanted to read and learn more about this to do a better job in the future, for our upcoming project.

I’ve read some articles and a couple of books on this topic. My goal was to extract relevant pieces of knowledge with the final goal of producing one sheet of paper with the most important points. I wanted to stick it onto the wall behind my screen so that I could refer to it with only a glance. It had to have the most important questions that I should ask myself before committing to anything important during software design.

Today, I finally condensed all I wanted to write, prepared this page, printed and glued it to the wall:

I prepared a PDF that you can download and print to put in your workplace if you like this.

Here are the points and their explanations:

Is this a “Good Idea”?

I took this one from Avoid “Good Ideas”

The really insidious thing about “good ideas” is that they are “good.” Everyone can recognize and reject “bad” ideas out of hand – It’s the good ones that slip through and cause trouble with scope, complexity, and sheer wasted effort incorporating something into the application that isn’t necessary to meet the business need.

In other words, think if this is necessary or is it just feature creep. Software complexity increases exponentially so having twice the features makes the code complicated by much more than twice.

DRY. Don’t Repeat Yourself

DRY is a well-known software design principle. Explained in Pragmatic Programmers, it means that “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.”

I already have an ingrained instinct about DRY. Still, I wanted to have a good in-the-face reminder so as not to forget it in a middle of a passionate idea.


In other words, how independent is this module or block from other parts of the system? Modularity in software is important. It makes life easier later. It’s easy to understand and easy to overlook.


Think how you will test this part of the system. Is it designed in such a way that makes testing easy? Testability depends on modularity, complexity, code style. Don’t neglect testability of your system or code. Testing is important. Manual testing is good. Automatic testing is much better.

Is there another way?

This is also from Pragmatic Programmers. It contains good quotes in every chapter. Here’s one by Emil-Auguste Chartier — “Nothing is more dangerous than an idea if it’s the only one you have.”

Often, when thinking about problems we come up with a solution and run to implement it, feeling happy that we have one. Unfortunately, often the first solution won’t be the best. Think again, be creative, try a different approach. When you come up with more ideas, it will often be the case that the first one was too rushed and that the next ones are, in fact, much better.

Costs of changing this later

Consider the decision you’re about to take. What will it cost you to change it at later stages of the project? Can you defer this decision? If you’re not sure about the decision, can you design the system in such a way that changing it later will not break things and cause unnecessary work?

What if I didn’t have this problem?

This one is from Don’t Be a Problem Solver.

Because architects tend to immediately enter problem-solving mode, we forget, or rather have never learned how, to interrogate the problem itself. We must learn, like a telephoto lens, to zoom in and zoom out, in order to ensure the question is really framed properly, and that we’re not merely accepting what we’re given.

Instead of immediately working to solve the problem as presented, see if you can change the problem. Ask yourself, what would the architecture look like if I just didn’t have this problem? This can lead ultimately to more elegant and sustainable solutions.

What are facts and assumptions? Document rationale.

The last two are from Challenge assumptions – especially your own.

Best practices in software architecture state that you should document the rationale behind each decision that is made, especially when that decision involves a trade-off (performance versus maintainability, cost versus time-to-market, and so on)…

This practice is valuable because by way of listing these factors, it helps highlight assumptions that the architects may have that are affecting important decisions regarding the software that is being designed. Very often these assumptions are based on “historical reasons”, opinion, developer lore, FUDs…

In other words, if you’re designing software architecture, write down why specific decisions are made and then think what of these are facts and what are assumptions. Check your assumptions.

Facts and assumptions are the pillars on which your software will be built. Whatever they are, make sure the foundations are solid.

Download the PDF with these question to stick on your wall.

I’m @jacobgorban on Twitter

I think I have a million-dollar idea

Late night two days ago, before retiring to bed, I went to the bathroom, as usual. Suddenly, right there, an idea hit me, which is not as usual.

Moreover, the idea itself is not a usual one for me. It had nothing to do with computers or high-tech, for that matter. It was about the light switch to the bathroom.

You see, I have two kids. One of them is now 4 years old. She feels old enough to go to the bathroom by herself. In fact, she can do the whole procedure herself. Except one thing. Turning the lights on and off. So it happens like this:

I’m half-lying comfortably in our bean bag chair, minding my own business. She comes to me and notifies that she wants to pee. I say “Sure, let’s go”. “No, I’m big enough, I can go myself!”, she replies. I feel lucky that I no longer have to get up from the bean bag chair for this, because it’s quite an exercise, in fact. She feels grown-up.

So she leaves, arrives to the bathroom and calls me from there: “Light!”. Oh, man.

So I had this idea about designing a light switch that usually looks and behaves like a regular one. But, when you have such kids at home, you can pull a rope from there that will allow the them to pull it and turn the lights on and off. There are “pull the rope” switches like that available but I never saw one integrated with a regular light switch, so that both parents and kids could use it. And it should be retractable into the switch when the kids grow, for esthetics.

Yes, I know that kids can stand on a short footstool to make themselves high enough to reach the regular switch. Yet it’s not so comfortable. She needs to carry it between the rooms. Yes, there’s the same problem with her room lights as well.

As far as marketing of this special switch — when the expecting couple comes to the baby store to buy the needed stuff for the upcoming baby, have the seller propose these switches to them along with all the other stuff that they buy. This way they’ll be ready to pull the rope on the first “I can go to bathroom alone”.

And the kid will also feel more empowered since she doesn’t need to ask for your help and spoil her achievement.

So here, take the idea and make a million bucks if you believe it’s worth it. I don’t know anything about designing, manufacturing and selling commodity hardware. I’m just a software guy. Pressing keys on the keyboard is all I know.

Using multi-resolution TIFF files with WebKit on Mac for Retina support

I’m working on Retina support for our Mac application Trickster. Most of the things are pretty standard – either creating PDF images instead of PNGs or creating two PNGs for regular and @2x image.

During the build process the latest Xcode will take the two PNGs and create one multi-image TIFF file which is inserted into the built application’s Resource folder.

Trickster uses WebKit to display its Help screens. Two are just text but one is an image.

Previously I only loaded the image directly, without HTML with:

[[NSBundle mainBundle] URLForImageResource:@"Trickster Help"];

To support Retina version of the image, I created the @2x version, added it to the bundle and went to look how to use the media queries and other CSS tricks to display the double-resolution image on Retina display. I had to build an HTML file and load it into WebKit instead of the PNG:

[[NSBundle mainBundle] URLForResource:@"Trickster Help" withExtension:@"html"];

I built the HTML:

<!DOCTYPE html>
    <style type="text/css" media="screen">
    body { margin:0 }

    div#help {
        width: 740px;
        height: 562px;
        background-image: url(Trickster%20Help.png);
        background-size: 740px 562px;       

    @media screen and (-webkit-min-device-pixel-ratio: 1.5), screen and (min-device-pixel-ratio: 1.5) {
      div#help {
        background-image: url(Trickster%20Help@2x.png);  

    <div id="help"></div>

It worked great when I checked it in the standalone Safari. Safari even dynamically substituted the image used based on where the window was when I dragged it.

The problem was in the built application. The PNGs are converted to TIFF, by default, and the HTML can’t find them so it doesn’t display anything.

I thought “OK, I’ll just change the CSS to point to TIFF image”. Then I thought – but I only have one TIFF, what do I put in the media query?

The solution was unexpectedly simple: point background-image URL to the TIFF file and don’t use the media query at all. WebKit handles the double-resolution TIFFs automatically and selects the Retina version when the window is on the Retina screen and regular one, when on regular screens. Yes, it even does that dynamically when dragging Trickster’s help window.

Here’s the final HTML:

<!DOCTYPE html>
    <style type="text/css" media="screen">
    div#help {
        width: 740px;
        height: 562px;
        background-image: url(Trickster%20Help.tiff);
        background-size: 740px 562px;       
    body {
        margin: 0;

    <div id="help"></div>

To sum it up — using WebKit with Retina images inside your Mac application becomes very easy. It just works if you point your HTML to multi-resolution TIFF files instead of PNGs. And Xcode generates these TIFF files by automatically. Easy win!

It’s probably not an appropriate solution for general Web use as I don’t think that other browser will support multi-resolution TIFFs. It also requires visitors to download large TIFFs even if they don’t use them (and let’s not forget – most people don’t have Retina displays).

I wonder if a similar solution works on iOS. I haven’t tried. Would love to hear result, if you try it.

You can get in touch with me on Twitter at @apparentsoft.