Gorban.org

Indie software business and Cocoa development

0 notes &

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. :)

Filed under interview

1 note &

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 --
127.0.0.1     news.ycombinator.com
127.0.0.1     facebook.com
127.0.0.1     twitter.com

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.

Filed under Haskell distraction productivity programming

1 note &

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"]
  sortBy:@"name"]
  fetchWithTrigger:objectsChanged];

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 App.net. I’m @apparentsoft over there as well.

1 note &

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:

TUAW

Gizomodo

I’m @apparentsoft both on Twitter and on App.net.

44 notes &

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’ve 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 actually 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.

Orthogonal?

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.

Testable?

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.

Jacob.
I’m @apparentsoft both on Twitter and on App.net.

Filed under software archtecture tips cheet sheet

1 note &

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.

Filed under ideas

1 note &

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>
<html>
<head>
    <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);  
      }
    }

    </style>
</head>
<body>
    <div id="help"></div>
</body>
</html>

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>
<html>
<head>
    <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;
    }

    </style>
</head>
<body>
    <div id="help"></div>
</body>
</html>

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.

1 note &

Using dictation software to study foreign languages

There are many ways to study a foreign language. Books, private teachers, reading, listening, watching movies, writing articles are all valid strategies. But if you don’t live in an environment where the language isn’t spoken by its native speakers, you may have little speaking experience.

English is not my 1st language. In fact, it’s more of a 3rd one. But I do most of my work in English. I read articles and books, listen to podcasts, give interviews, write articles, talk to colleagues and speak at conferences. Still, I don’t speak English as much as I’d like to.

Last year I had a neighbor who emigrated from the United States. He wanted to study Hebrew and I wanted to practice my English. So we arranged to meet a couple of times each week for an hour or two. During the meetings we’ll talk English half the time and Hebrew the other. Later he left our neighborhood and I started to look for other solutions.

What I started to do is using dictation software on my Mac to write articles, reply to support requests and sometimes even for e-mail. I’ve also started to do the same on the iPhone and the iPad.

Dictating text instead of typing it has several benefits as a language study tool:

  • it teaches and trains the correct pronunciation of words
  • it forces to improve the accent
  • it improves enunciation
  • it can help with the fluency of speech

Of these, I find the pronunciation and accent aspects the most beneficial.

Dictation solutions

There are dedicated dictation software applications available for Macs and PCs. The best ones are available from Nuance. These are full-featured applications, they process your speech locally on your computer and they adapt to you. You can teach them both your vocabulary and train them to recognize your voice. They are not cheap, though.

The other solutions use cloud services to send your recorded speech to some servers that process the recording and send back the transcribed text. This is how dictation works on iOS devices and in various solutions by Google, including Android phones, Google voice search and Google Translate. These solutions are a little slower and require an Internet connection.

One interesting benefit of cloud solutions though is that they don’t adapt to your specific accent and speaking style. The cloud solutions assume a “standard” accent. In some cases, like on iOS, you can choose which accent you use to speak (American, UK, Canadian etc). But that’s the only configuration option available. This puts even more “pressure” on you to speak with the correct accent and improve your enunciation.

Of cloud solutions it seems that Google recognizes the most languages including Russian, Polish, Turkish, Arabic languages, Hebrew, Chinese, Dutch, Portuguese, Korean and more. You can download the Google Translate app for iOS and see exactly which languages it recognizes. Unfortunately Google Translate web site only appears to support English dictation for some reason.

To sum it up, if you’re studying a foreign language consider using the multitude of the available dictation solutions to train your speaking abilities in that language.

This article was dictated using Dragon Dictate for Mac from Nuance with some editing done later in the text editor.

7 notes &

Think it later

I love the concept of “read it later” services. Whenever I hit something that is too long to read at that moment I send it to Instapaper. Later, when I actually have time to read, I launch Instapaper app and see the list of the articles that I queued for reading.

In my previous article, “Thinking time”, I described how I love to schedule dedicated time for thinking about my business. Sometimes, though, the time comes and I’m not sure what’s on my agenda.

So lately I’ve come up with a concept of “Think it later” notes. The idea is so simple that it’s embarrassing. During the week, whenever I get a thought that requires time or depth of thought, I add it to “Think it later” list. These notes are then my “thinks to do” during the “Thinking time”.

Technically, you can use anything for your “Think it later” notes. It can be your favorite note-taking application on your phone, plain pen and paper, or you can use your favorite to-do application. If you use a system based on GTD you can create a special context called “Thinking” and use it for this purpose.

Even if you don’t set a dedicated time for thinking you can refer to this list whenever there’s some time that you can use for this purpose.

If you like this idea but not sure how to implement it, just write it down and think about it later.

Filed under Business productivity Thoughts

27 notes &

Thinking Time

Being an indie software developer, developing products and running the business, takes lots of time. I work during normal working hours and then often have a “second shift”, when the family, or at least the kids, fall asleep. Still, I have enough planned stuff to do, when I’m near my Mac, to fill months of work. And most of this better be done sooner than later.

I’m pretty sure that if you’re an indie software developer, a designer, a business man or almost anything where you have some control over your time and work, you know what I’m talking about.

In this state, we may become so reactive to the tasks that need to get done that we just don’t stop, take a step back and reflect on the whole situation. We may just forget to think deeply, strategically about the business and even about the work tasks themselves.

Enter “Thinking Time”

When I was at the uniquely great NSConference 2011 this March, I had the opportunity to discuss some of this with Matt Gemmell during a dinner there. Matt is a well-known Cocoa developer, conference speaker and, should I say, thinker. He appears to think deeply about stuff and publishes many of his thoughts in the articles on his blog.

So I asked him how he approached the thinking about software design, and his answer included something like “I take a walk, in the nature, by the river, and only take my Moleskine and a pen with me.” It’s not a quote but the gist of his reply.

And I thought to myself, “Why, that’s a good idea. Step back from the monitor, the distractions, and devote time to just thinking for some time, writing thoughts down with analog pen and paper”.

So, on my way back home I grabbed a couple of notebooks at the airport (they just happened to be Moleskine, of course), one for me and one for my partner, Kosta, and decided on having “Thinking Time”.

I put it in my calendar, weekly, as the first thing to do each week. It’s a good way to start a new work-week. While most of the population rushes to the jobs thinking “It’s @#$%@#$ Monday again”, I start the week slower, walking the streets or sitting on a park bench or under a tree to write things down, breathing real air. If the weather doesn’t allow being outside, I’ll sometimes go to a cafe, instead of skipping it completely.

During such couple of hours I can make good progress planning software architecture, sketching application design, preparing a conference talk, or thinking about strategic business stuff.

Then, by noon, I come back to my home-office, feeling refreshed, satisfied that I already did something important today, and overall feeling inspired for the rest of the week.

Try it yourself

If you don’t yet have such “Thinking Time” on your schedule, I suggest you to try it. The beginning of the week works the best for me. But maybe you’ll feel that the middle is actually better because it splits your work week and you get some kind of a break from your regular tasks.

In this age of Internet and social networks with all the fun distractions that they provide, it becomes more important to go away from it all at least for a couple of hours each week, sit down with a pen and a paper (or even an iPad running some notepad-type application), and just think it all through.

Update: take a look at my other article related to this: Think it later

Filed under business thoughts