Oleg Andreev



Software designer from Paris, France.

Author of Gitbox version control app.

Locked into choice

Yesterday you had many great ways to create and digitally distribute your content. First, you could make a website with gorgeous latest web-technologies which is perfectly accessible with every modern browser on all major computer platforms. Or create an ebook based on the open standard Epub, also supported by all major reading software and devices. Third option is to make a movie (encoded in a couple of wildly supported video formats: from FLV to H.264 and Ogg). Finally, you could write a native app for Windows, Mac, iOS, Android etc.

Every platform vendor: Microsoft, Apple, Google, Facebook, Adobe and others work hard every day to give you better ways to create and communicate with people.

Today Apple released three apps: iBooks 2, iBooks Author and iTunes U. Every app is available for free. iBooks now runs interactive books created with iBooks Author and iTunes U integrates books and apps with video materials in a very useful UI.

So today you have one more wonderful option in addition to those listed above. Yet, some people start screaming about “lock in”, how Apple does not care enough about education to make everything open; about many evils of proprietary formats, proprietary apps, proprietary operating systems and proprietary devices.

These people are fantasizing a world where everything is right, cheap and every good is available in an infinite number of options. And at least one of those options is exactly what is right for them (and there must also be a right one for any other person too for fairness’ sake).

Guess what. This is the world we are living in. And everybody has her own idea of the perfect world order and while we are not enslaving or destroying ourselves, our world indeed moves towards better ways to live a life. Nothing is 100% right for you, but it is so for everybody. And this is why we all are working together everyday to make us happier.

Today’s Apple announcement is just one more achievement of human civilization, in addition to iPad, Android, Windows XP, World Wide Web, printing press and alphabet. Choose what you like in any combination and go do something great with it.

Fun with concurrency on a single core

I have a single-core chip on iPhone 4 and an app with OpenGL rendering controlled by touch events.

This morning the app was rendering graphics on the main thread. 90% of CPU time was spent on graphics, 10% on gesture recognition and related computations. Overall CPU utilization was about 30%.

These 30% were noticeable: touch events were processed with delays and frame rate was low and not very stable.

In order to make app snappier, I moved the OpenGL rendering into separate serial dispatch queue. Now event loop was much less loaded, and I expected overall improvement. Not a higher framerate, but more stable one and with more accurate touch recognition.

In reality, the rendering was indeed slightly smoother, but touches were still delayed.

Profiler was showing now that 70% of CPU time was spent on graphics (in background thread) and 30% was spent on gesture recognition. Also, overall CPU usage increased up to 50%.

In terms of raw performance of algorithms nothing was changed at all. Threading code that was added is a simple dispatch_async() call consuming almost no time.

Now, I have a theory that explains this. Since the main event loop became 90% less loaded after moving graphics to background thread, it was able to process more touch events per second. Gesture recognition computations increased load on a single CPU core making graphics rendering slower than expected.

In result, framerate was not improved, but became more stable and touches didn’t get much smoother because of the increased pressure on CPU and main thread.

It turns out that rearranging stuff on a single core does not really help unless it is accompanied by actual performance improvements.

Block concatenation

This little function concatenates two blocks in a single one.

Useful when you have a single async operation running while multiple callers wish to subscribe for its completion event with a single message like [self doSomethingWithBlock:^{ … }]. The first caller will start the operation, for all the others the block will be concatenated with the first one.

void(^OABlockConcat(void(^block1)(), void(^block2)()))()
{
  block1 = [[block1 copy] autorelease];
  block2 = [[block2 copy] autorelease];
  
  if (!block1) return block2;
  if (!block2) return block1;
  
  void(^block3)() = ^{
    block1();
    block2();
  };
  
  return [[block3 copy] autorelease];
}

Managing default applications on a Mac

1. Download “Default Apps” Preference Pane: http://www.macupdate.com/app/mac/14618/rcdefaultapp

2. Select “URLs”

3. Select the URL schema. E.g. “github-mac”.

4. Change the app.

Gitbox is 1 year old: status report

Gitbox is on birthday sale: full version for only $9.99.

In May, 2010 I started experimenting with a UI for staging and committing to Git repository because it’s not easy to “git rm” a bunch of files that are already moved to trash (tab does not help). Also, I was tired of typing “gs” (“git status”) all the time just to see that everything is the way I want. Soon I realized I could make the app much more useful if I could integrate history cleanly without too much additional elements. I’ve spent a couple of days thinking about it and realized that the “stage” is a special case of a commit. I quickly came up with a two-pane window — history on the left and changes on the right. Stage was a special item in the top of the history. Since then a lot of good design decisions were coming quickly. Branches went to the drop-down menus in the toolbar with pull/push button between them.

Gitbox 0.9 looked very simple.

Quickly, everybody at our Pierlis office started using it. Staging, committing, pull, push became much more efficient than in Terminal or any other GUI starting with version 0.1. It was my first Mac app (I’ve already done some iOS projects for our customers), I loved it but still I was shy to release it. In June on WWDC10 my boss told me once more that “real artists ship” and I shipped Gitbox with version 0.9 for free. It looked clumsy and I really worried that nobody would like it.

But it was a success. A lot of people got interested by a concept of “one-button” Git client. Never before version control app, especially for Git, was expected to be “simple” or “minimalistic” yet useful. A lot of people dismissed it for a lack of features. But still many fell in love with it from day one and continued using it daily. For many it became the only way to work with Git repos without exploding their brains.

I got quite serious about it. I decided to polish it, add several more important features, streamline the UI (mostly by adding a sidebar for the repos) and released it in the end of November 2010 for $40 with a free version limited by 3 repositories (and no time limit).

It was a success again. Over a couple of days it made about $3000 which was totally unexpected as I was hoping for at least upgrading my notebook. Over months, it was steadily bringing some noticeable profit that helped paying for my wedding and honeymoon later in 2011.

I was amazed that something I designed, wrote, productized and marketed was actually appreciated by consumers. I even appreciate that keygens were released within a week after
each new version release.

I developed a long list of features and tweaks, rearchitectured the whole app several times (hello, responder chain and GCD!), was trying to keep focus and regularly deliver updates with both fixes, improvements and new wonderful features. It is still a “weekend” project, so I don’t have a lot of time to work on it. But what matters more is to keep going and improve it every day, at least a little bit.

Gitbox is still lacking some interesting things like built-in diff viewer, line-by-line staging, tree view or submodules. Those will come soon. But many more important things were already done: very responsive UI, instant full-history search (even by diff contents), undo for common operations like commit, pull and push (and more to be added in later updates), ubiquitous drag and drop and powerful keyboard shortcuts. Also, a lot of stuff was ignored that would cripple and complicate the UI. Some power features were delayed until the right place for them was found.

I consider Gitbox a right UI to do Git version control. The core design principles worked very well so far and allowed me to extend it to more and more new capabilities. UI is still, like in v1.0 very simple and clean, but is able to do so much more and will in the future.

Thank you all.

Monospaced font

Some people would love to use proportional fonts for the programming code, but blame languages and text editing software for not being ready for them yet. The problem is that most proportional fonts (e.g. Helvetica, Lucida Grande) make punctuation characters too narrow making many statements hard to read.

Compare:

Monospaced font: if ([link isKindOfClass:[NSURL class]])

Proportional font: if ([link isKindOfClass:[NSURL class]])

Programming languages usually contain a lot of little syntactical features that are important to read and notice. One extra pair of parentheses or a semicolon may change the whole meaning of a line of code. And, unlike the real text, you cannot make a single typo.

If monospaced fonts look clunky, that’s because the programming languages normally require equal attention to every single character.

Obj-C snippet: jumping to background

When you need to do CPU-heavy work, there is a nice pattern using GCD: jump to a background queue to do the work, and then back to caller’s queue to report the results. Do not forget to retain the caller’s queue because it may be deallocated while doing background work. Although compiler inserts retains for the ObjC objects referenced within blocks, queues are declared as opaque C structs (dispatch_queue_t), so they won’t be automatically retained.

dispatch_queue_t callerQueue = dispatch_get_current_queue();
dispatch_retain(callerQueue);

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
	
	// Do the work in the other thread...
	// Example: NSArray* items = parseJSON(data);
	
	dispatch_async(callerQueue, ^{
		
		// Report results to the caller...
		// Example: [self didParseItems:items];

		dispatch_release(callerQueue);
	});
});

Ruby and Objective-C

Ruby is very similar to Objective-C because both have a lot of similarities with Smalltalk. However, Ruby is a messy language on many levels. Many consider it a mostly a feature, not a bug, but it indeed makes interoperability with Objective-C less nice.

1. Ruby has a messy syntax. It inherits several features from Perl, Bash, Python and C-like languages and mix them together without any clean distinction. You have always many ways to do the same thing and it is never obvious which one is the best. With Objective-C it is much easier to write a lot of boring and obvious code than with Ruby. Of course, this property appeals to coders who love funny things in their code, but it does not play well with people who want to ship huge complex applications and systems in time.

2. Ruby has a messy standard library. Many things in standard library are not well-thought, not consistent with other things, redundant or lacking essential functionality. Things like File vs. FileUtils, Date/Time/DateTime + ActiveSupport extensions demonstrate horrible inconsistencies at some core things.

3. Ruby has a messy culture. Ruby coders *love* smart tricks and hate boring code. Everybody wants to DRY all the code for better or worse or pretend being a cool meta-programming lisp hacker (not the best professional quality in itself). People are not careful about containing their libraries as humble as possible. Many people are okay to inject methods into core classes and do a lot of meta programming tricks and be proud of it. All this leads to maintenance issues and is not compatible with Objective C culture.

These three key things make Ruby incompatible with Objective-C or Cocoa framework.

It’s important to add that all of this is not unique for Ruby, but pretty much for any hobby technology, particularly backed up by some open source community.

MacRuby is irrelevant

Apple clearly puts a lot of effort into making LLVM infrastructure and Objective-C a powerful general-purpose toolkit for themselves. If they miss some feature, they are more likely to add it to LLVM and/or ObjC rather than spinning off additional separate projects. They already have WebKit and JS and that covers a lot of what they want to do. And they are bold enough and smart enough to improve things in both technologies whenever they want or need to.

Forget about MacRuby, MacPython and other languages in that respect, they are clearly are only interesting to people who focus more on typing codes than on shipping products.

Objective-C @property attribute suggestion

I would love to have the following feature in Objective-C:

@property(retain, auto) id something;

Where “auto” attribute would mean:

1) automatic @synthesize (already present in modern Clang compiler)
2) “nonatomic” if not stated otherwise
3) automatic release (if “retain” or “copy” is used) and nullifying of instance variable on dealloc

Xcode 4: good parts and bad parts

Xcode 4 slowly replaces Xcode 3 for my projects. Benefits become more important than problems. So here is my list of things I like and dislike about Xcode 4:

Like:

1. Tabs
2. “Open Quickly” with fuzzy search by filename (cmd+shift+O), like cmd+T in Textmate.
3. Jump bar
4. Smarter autocompletion

Finally, the tabs and jump bar turned out to be the single reason to use Xcode 4 despite all of its annoyances. On a complex project window management consumes a lot of time.


Dislike:

1. The major problem with Xcode 4 is performance: switching between tabs, opening sidebars, autocompletion — all happen with noticeable delay even on iMac with i7 processor and 8 Gb of RAM. Bonus track for the latest Macbook Air: sometimes Xcode 4 eats 150-200% of CPU doing something (no matter whether debugger is launched or not). And when the debugger is connected to iOS Simulator fans just never stop. I hope this will be resolved with next updates.

2. No retina display mode yet in Interface Builder (but IB 4 is slow as hell, so I use IB 3 instead anyway).

3. Stupid (== “too smart”) assistant editor. When I choose another file manually, it is sometimes reset to some counterpart. And Open Quickly always opens in the left pane. Assistant editor has no value to me until these issues are fixed.

4. LLVM and LLDB. Turns out, the latest LLVM compiler has subtle bugs with nested blocks (sometimes self becomes an incorrect pointer) and LLDB does not display values for properties which were declared without corresponding ivars.


There are some things about Xcode 4 I don’t really care about:

1. Git support. I have a Gitbox anyway, which offers complete set of operations (committing from Xcode is a nightmare and pushing is simply not possible). Surprisingly, I’ve never used blame or in-editor diff. Those features sound useful, but in practice are rarely needed and feel sluggish.

2. IB drag-and-drop to source code to create actions and outlets. Xcode is slow and produces some awful code which needs cleanup anyway. Same thing goes for code snippets that take more time to find/drag/edit than to simply type the stuff.

3. iTunes-like status panel. I usually collapse the toolbar anyway, so I don’t see all those distracting animations.

On programming languages

When you develop some interesting software, you care to make architecture simple, boring and flexible as much as possible. When you think hard about user interaction or work around some weird system integration, the code should get out of the way . Whatever language you choose, you try to stick to some limited set of features and use them predictably and consistently. Ninja tricks are interesting on their own, but better not get mixed with an actual product.

As the complexity and amount of stuff to be designed and improved grows, you are becoming more conservative about any language or technology you use. All the sudden, discussions about C++ template complexities, braces styles etc. look completely strange and irrelevant.

Your code is so simple, you wonder why you should write it at all. Most of the typing is spent on defining objects, giving names and connecting things together. Every interesting algorithm is carefully packaged out of the evolving structure and is rarely touched again.

File system tree does not feel expressive enough. You need some sort of rectangles on the screen to lay out the components and hide some parts within the others for goodness sake.

You become even more productive if some of those rectangles provide immediate feedback, e.g. user interface elements in the Interface Builder.

The future of software development is not the language or syntax, but the interactive tools with instant feedback and sophisticated data organization.

NFC and payments with a phone

Why are people so obsessed with the NFC buzzword?

The only safe and understandable way to conduct the payment with a phone is with the protocol like this:

1. Shop sends a payment request to your bank (via shop’s bank or directly)
2. You bank pings your phone and waits for confirmation.
3. You take your phone out and confirm the payment. You can do this securely over Wi-Fi, 3G, EDGE, Bluetooth, NFC and any other communication technology which lets you to speak TCP/IP and finally (after going through all the proxies and routers) connect to the Internet.
4. When bank gets the confirmation, it acknowledges the transaction and tells the shop about it.
5. Shop issues a ticket and you walk away.

This protocol is safe (contrary to modern credit card processing) because you never trust someone else’s device (you trust only your phone) and you never give away any secret information (like credit card number or a PIN code).

The only tricky thing here is how to give the shop your banking ID (which can be a phone number), so they can send it to your bank which will contact you for confirmation. This can be done in many different ways:

0. Tell the ID to the shop assistant - simple to understand, but needs remembering and typing in. Since we need a phone to confirm payment anyway, we don’t even count it.

1. Show the barcode on the phone’s screen and scan it. You need to launch a payment app anyway. Why not to display you bank ID as a barcode on the first screen so you can simply scan it.

2. Use NFC to announce your ID to the shop. This like barcode scanning, but without optical scanning. It has its issues, though. If you have many devices nearby, the receiver may confuse your device with someone else’s, or recognize your slower. Everybody knows how slow bluetooth is.

3. Do it in reverse with NFC: the shop will publish you bill and (if you are lucky) only your phone will see it, so you can send it to your bank.

To me, the most usable ways to conduct payments are #1 and #2. And #1 seems to be simpler and faster (but feels “lo-tech”).

Bottom line is: NFC is not a requirement for payments with a phone. You need any communications tech to connect to your bank and can use different ways to announce your banking ID.

I also hope, that the phone payments won’t be done in the same way as credit card processing is done. That is, by giving away secret codes and trusting the shop to confirm the transaction.

MacAppStore and external distribution

Gitbox started selling in November using old-school method: download a free version from gitboxapp.com, then upgrade to a paid version by buying a license.

Today Gitbox is available on Mac App Store as well. What this means to you?

If you have already purchased Gitbox, you don’t need to “connect” it to App Store. First, it is impossible to do for free: you’ll have to buy it again, from Apple. Second, you won’t miss much. Gitbox is a single-version application: there is no “lite”, “full”, “appstore” or “non-appstore” variant. The functionality is all the same. (Only difference is that binary in appstore has different autoupdating and license checking mechanisms.) Gitbox already provides automatic updates for free. There is one nice feature of the non-appstore purchase: updates can be released within minutes instead of a week.

Note that App Store marks the app as “installed” if it sees it on disk even if it was never downloaded from Apple. If you want to purchase it from Apple (maybe you have not yet purchased a license), then you should drop the app to Trash and restart App Store: the purchase button will become available. Your preferences won’t be affected.

So how do you decide where to purchase an app? Both distribution channels are great: appstore is more controlled, but sometimes much more convenient, another one is more flexible, but less integrated into OS. I believe it is important to keep both options available to you, but I want to avoid any confusion. So here is my policy:

1. Prices and discounts will always be the same and synchronized for both stores. The app is the same, hence the price is the same.

2. I will do my best to release big updates synchronously on both stores. I usually don’t release more often than once a week or two, so it is very possible to adjust to the appstore review delays.

3. In case of security updates or critical bug fixes, I will post an update immediately even if the appstore does not publish it as quick as I do on my website.

Enjoy Gitbox and buy it where you like. You will get the same support and love everywhere.