Oleg Andreev



Software designer with focus on user experience and security.

You may start with my selection of articles on Bitcoin.

Переводы некоторых статей на русский.



Product architect at Chain.

Author of Gitbox version control app.

Author of CoreBitcoin, a Bitcoin toolkit for Objective-C.

Author of BTCRuby, a Bitcoin toolkit for Ruby.

Former lead dev of FunGolf GPS, the best golfer's personal assistant.



I am happy to give you an interview or provide you with a consultation.
I am very interested in innovative ways to secure property and personal interactions: all the way from cryptography to user interfaces. I am not interested in trading, mining or building exchanges.

This blog enlightens people thanks to your generous donations: 1TipsuQ7CSqfQsjA9KU5jarSB1AnrVLLo

Why Apple products are well designed and buggy

Following the discussion on Hacker News how MS had resources and liberty to experiment with their developer tools, but the new Visual Studio 11 is committee-designed and is based on the same crufty UI which is many years old now.

Both Apple and Microsoft are free to throw away old problematic UI and rethink some parts from scratch. If anybody is hurt in the process, it’s not a bottom line. Microsoft sells Excel and Apple sells computers, they don’t have to prove anybody anything with their developer tools, except for themselves. And they have all resources and expertise for that, of course.

However, there is a difference in approaches. Apple, comparing to others, is not afraid to break things while executing some ideas they think are great. For instance, when Xcode 4 was released, it integrated Interface Builder very neatly into main window, but they broke support for third-party UI components. So while some people would have to type a bit of boring code to setup those components, many others are enjoying unified workflow. Also, the first builds of Xcode were very slow. Xcode team found a way to represent tons of useful information in only three panels with very little cognitive load, but didn’t take time to optimize the performance. It was super-useful and super-annoying at first. But that was a non-trivial decision from their part.

When Apple released Final Cut Pro X with awesome new design, increased productivity and 70% price drop, they omitted some very important features. They finally added missing stuff, but before that they got a huge shitstorm from the customers for not having all they needed from the beginning.

As with Xcode 4 and FCP X, nobody was forced (even in a weak sense of this word) to upgrade. Xcode 3 worked well (I was using it while working on a slow notebook), FCP 7 was not killed too. What Apple had is basically a courage for an “release early, release often” type of operation. Why did they make these particular compromises, not the others? It was important for them to make a great new design and try it out as soon as possible at full scale. There is absolutely nothing interesting in performance optimization and bug fixes. You already know it’ll be awesome if you do them.

When you are designing, you are taking risk to decide for others and you don’t know if your are right until you show it. It also means, you cannot ship half-designed product. The reaction on unfinished design (non-thought through, that is) is skewed. It does not help you to understand if you made it right. It’s not a problem if it’s slow and buggy, those things do not obscure (at least, should not obscure) the vision of how product works.

Since you have to spend time designing every aspect of the product to the last detail to get sensible feedback, you don’t have much time left to resolve less relevant issues. You are already quite late, for that matter. And if your decisions need some improvement it’s better to know it before you start optimizing them.

So in the end, every new Apple product has what they consider a finished design with new ideas, but with rough edges like crashes, performance issues or some less relevant features omitted to be reworked later. Those having time to polish secondary aspects of their products are not pushing forward hard enough.

If you like the post, follow @oleganza on Twitter and buy my well-designed version control app: Gitbox. It’s super-smart, fast, and, of course, sometimes buggy ;-)

How to rebuild Info.plist on each run in Xcode

If you define some variables in projects settings that are included in Info.plist (usually, it is build version), you may notice that Info.plist is not always up to date. This is because when you change the variable in project settings, the Info.plist is not actually modified and Xcode may skip its compilation.

If you try to add Run Script phase with “touch $PROJECT_DIR/Info.plist”, it won’t help much because it will always run after processing of Info.plist. At best, Info.plist will be up to date every other run. It is very confusing to say the least.

How to fix:

1. Add a new target “Other” — “Aggregate” with a name “TouchInfoPlist”

2. Add Run Script phase with this line: touch $PROJECT_DIR/Info.plist

3. Go to your actual product targets, select Build Phases tab and add dependency TouchInfoPlist.

4. Edit schemas and remove schema “TouchInfoPlist”. You’ll never need to run it directly.

Enjoy always up to date Info.plist.

The Main Apple Doc

Apple has a lot of great documentation: from the very basic guides and tutorials down to particular API references. But for a very long time newcomers were wondering: where should I start?

Now you know the answer:

For iOS: Start Developing iOS Apps Today

For OS X: Your First Mac App

iOS guide is even better: it shows you all necessary areas from the beginning to the end giving relevant links at each step. Just start with first page and move on.

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

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.