Aug 16

Total props go to Ben Christensen for this little gem that had me slamming my head against the wall. If you’re trying to perform a Subversion checkout and getting some meaningless error such as:

svn: To better debug SSH connection problems, remove the -q option from 'ssh' in the [tunnels] section of your Subversion configuration file.

or

svn: Network connection closed unexpectedly.

The simple answer is to delete your known_hosts file in your .ssh folder:

indy:~ terryblanchard$ ls -al .ssh
drwx------   3 terryblanchard  staff  102 Aug 16 23:01 .
drwxr-xr-x+ 29 terryblanchard  staff  986 Jul 15 12:59 ..
-rw-r--r--   1 terryblanchard  staff  474 Aug 16 23:01 known_hosts
indy:~ terryblanchard$ rm .ssh/known_hosts

Written by Terry Blanchard \\ tags: , , , ,

Jan 17

Alex Payne has written a wonderful article about why cross-platform development environments ultimately fail to deliver what customers really want; a great experience. Alex says:

This post is about platforms and doing the right thing by your customers. It’s about the one big thing that I think HipChat and some other great companies are doing wrong.

He nails the reason that cross-platform development tools and environments like Adobe’s Flash and AIR products are attractive from a business perspective but end up failing from the customers perspective. Ultimately, that circle of life will come back to haunt the business.

Many businesses are attracted to the idea of writing software once and deploying it across multiple platforms. From their perspective they have one development team, one code base, and one release cycle. What’s not to love?

That’s where most businesses stop their investigation. They fail to even think about what their customers want. They’ll quickly jump up and say, “What they want is our product on their platform. We’re giving them that!”

Yeah, but you’re giving them a turd and that’s insulting. I hear the next bit of verbal diarrhea spilling out of their mouth … and this part kills me.

“Well, at least they’ll have our product on their platform.”

Ouch. I think I just threw up a little while typing that.

What you’re communicating with a poorly-done AIR app is that your business priorities – namely, saving time and money – are more important than what your customers want.

Ironically paradoxical in nature because without customers there is no business.

Alex points out a few very well known products such as TweetDeck, Pandora, and Remember the Milk, where their users are begging for a native application. Sadly, the folks screaming for a native application for Remember The Milk have been flat out ignored by that company since 2007. Actually, that’s not ignoring them. That’s giving them the finger.

My team experienced a number of the usual problems one has with AIR applications: lousy performance, odd interface bugs, key combinations and UI elements that didn’t conform to our operating system. AIR apps exist in an uncanny valley between a web application and a desktop application, and the result is unsettling and annoying. Pretty soon, we were itching to go back to Campfire (via the native Mac client Propane), even though HipChat has better features and the promise of improved reliability.

Why are these cross-platform products so bad? Do users even know if a product is using a cross-platform development environment? Yup, they sure do. Users, even if they’re not geeks or developers like me, can smell a cross-development turd. I love how Alex wrote this:

Humans are gifted with extremely sensitive bullshit detectors. The average computer user may not internalize the difference between an AIR app and a native app, but he knows when something doesn’t feel right or work correctly. Your tech-stunted uncle may not ever request a native application with that terminology, but he’ll sure complain about his computer acting funny when he experiences the oddities of an AIR app.

Just read the comments at this site and you’ll quickly see the common threads:

  • Slow
  • Sucks up CPU cycles better than a Dyson
  • Doesn’t conform/take advantage of native UI
  • Lack of support for native OS features. Instead, uses the least common denominator solution that works across all-platforms
  • Security issues

With comments like that, do you really think “investing” in that type of development environment is going to save you money/time in the long-run? Does this seem like the path to huge business profits and long-term customer loyalty?

Is it more expensive to create native applications across all of the different platforms? Yes and no. Yes, because it is an investment in the development of your product. No, because unless you’ve misjudged the market, this investment will more than pay for itself.

“We don’t have time” is the common excuse for delivering an AIR app instead of a good native app. Money, though, can buy someone else’s time. For a price, you can find a great contractor to build a native app for any platform under the sun. It’s an investment. Eventually, unless you’ve misjudged your market, the investment should pay off.

What should a company do when they don’t have the time, resources, or expertise to deliver a native application? You start by clicking on the link above.

Written by Terry Blanchard \\ tags: , , , , ,

Dec 23

Accessibility Zoom
Accessibility is one of those areas that most software engineers and product teams seem to have little or no knowledge of. When it is brought to the attention of the decision makers, I’ve heard all too often, “We’ll do that if we have time at the end of the project” or, “What is that? Why do I care about it?” What’s worse, is that in the eyes of many companies and project leads, they can easily rationalize to themselves why accessibility shouldn’t be included in the development cycle:

“Why would a blind person own a touch screen device?”

“I think you’re solving a problem that doesn’t exist.”

“That’s not our target demographic.”

“I can’t see how this would improve our App Store ratings.”

“QA doesn’t know how to test it.”

It’s really sad. Especially when Apple has made it so incredibly simple for us to implement. They’ve done all they heavy lifting for us and simply said, “Carry the baton across the finish line. Please.” And most of us drop the baton.

Honestly, it takes minutes to make your application accessible to a population that all too often gets the shaft. I am a fan of Matt Gemmell. Everything from his tweets to his blog. Even if you’re not a fan, I implore you to read just one article. It’ll make you a better software engineer, and you’ll make your software usable to an audience that seems to lack a voice.

See Matt Legend Gemmell’s article:
http://mattgemmell.com/2010/12/19/accessibility-for-iphone-and-ipad-apps

John Gruber of Daring Fireball quoted this article as:

Must-read for developers. Both a good high-level overview of what accessibility really means and who it helps, and a technical overview of how iOS developers can take advantage of it. iOS is simply leaps and bounds ahead of the competition in accessibility.

Written by Terry Blanchard \\ tags: , , , , ,

Dec 22

Multithreading
Everyone has their own vision of how things should work. As you gain more experience in your craft, you become more grizzled. Well learned. After some time, you earn the privledge of passing this experinece on. Oscar Wilde said it best:

Experience is simply the name we give our mistakes.

Multi-threading in software engineering has been around for a long time. Many mistakes have been made, thankfully. From those mistakes, experience was born. Most of the engineering books talk about the essentials, and the dangers that must be respected and adhered to. But while they talk about the pitfalls of what could happen, none of them really give you great guidelines. I’ve been doing this a long time and I’ve worked with people who should not have made some of the mistakes I’ve witnessed.

Are they bad engineers?
No.

Was there a fundamental misunderstanding about multi-threading?
No.

But there are some fantastic guidelines that aren’t well-established. It seems like Brent Simmons and I agree on a lot of the same principles. He’s written a great blog post about Cocoa Threading that every Cocoa developer should read and understand. He refers to his post as his, “barely-organized thoughts on threading and Cocoa applications” but it covers the points in a concise manner.

Thread Communication Exclusively on the Main Thread

First up is his philosophy on all communication between threads taking place on the main thread. He extends this to notifications as well. I’ll add one more to that list which is KVO notifications. This is essential because UIKit and Core Data don’t like operating on secondary threads. I don’t know how many times I’ve seen

NSAssert( [NSThread isMainThread], @"This needs to run in the main thread" );

 go off because I received a notification or call from a secondary thread.

Communication between systems always happens on the main thread. (A system is one or more objects that work together.) In most cases, communication between objects in the same system happens on the main thread too.

If an object does something in the background, that is that object’s business and nobody else’s.

This extends to notifications: from background threads, I always make sure notifications get posted on the main thread. This way every notification observer can always assume that it’s getting called on the main thread.

Regarding KVO, Brent has this to say:

KVO is a trickier thing. Here’s how I handle that: anything happening in a background thread is not observable (by convention). Whatever is going on is private. When it’s time to set public stuff, stuff that could be observed, those things are set on the main thread.

Threading Methods

There’s almost as many different ways to spin off a thread as there are people in the United States. Brent and I also agree on which methods we use:

I’m very deliberate about my threading. I like Grand Central Dispatch, but for my purposes NSOperationQueue works best. The formal, easily-monitored approach of NSOperationQueue works best here. I definitely recommend against anything but GCD and NSOperationQueue — anything else (NSThread’s detach method, etc.) is too random. (Yes, we used it for years, but we have better stuff now.) (In fact, I almost never even use NSInvocationOperation — I much prefer the structure and defined stop/start of NSOperation.)

I use an NSOperation subclass that takes a target and selector in its init method. When it’s finished, it calls the target and selector on the main thread. This way the caller only ever sees the main thread — it creates the operation on the main thread, then gets called back on the main thread. The fact that the operation happens in the background is unknown to the caller: the caller just knows that it’s async, and doesn’t know anything else.

I almost exclusively use NSOperation subclasses with NSOperationQueue in my applications for the same reasons that Brent outlines. You can create multiple NSOperationQueue’s if you need different operating parameters (for example, one queue that is sequential, another queue that can operate concurrently). Making dependencies between various NSOperation’s is as simple as making an addDependency call. Plus, they can have dependencies across different NSOperationQueue’s.

Locking

NSCache seems to have suffered from poor marketing. It’s a little gem that very few people seem to know about. I’ll bet most of you have written your own class that performs much of the same functionality. I’ll take the very-well tested and used NSCache, which is also thread-safe, any day.

Locking sucks. If you have to do it, you have to do it. It doesn’t mean you’ve failed — failure would be not-locking when you really do need a lock.

There are a couple other things you can do which make sense.

  1. Use performSelectorOnMainThread to set some data that would otherwise require locking. (This is not a trick to use willy-nilly, though — typically it comes at the very end of an operation, not sprinkled throughout.)
  2. Use NSCache — it’s thread-safe.

I highly recommend you read Brent’s full article, “Some Notes on Threading” over at his site.

Written by Terry Blanchard \\ tags: , , , , , , , , , ,

Jul 30

You can’t just open up your editor of choice to modify the /etc/hosts file on your Mac. You can open the file without any problem, you just can’t save it.

To do this you must have super user privileges. Just being an Administrator isn’t enough. Fortunately, there’s a way to temporarily get super user privileges using the SUDO command. So I fired up Terminal and typed in:

sudo textedit /etc/hosts

Ruh-roh. It wouldn’t let me save the file. Crap. I’m not a Unix guy and VI makes my skin crawl and head hurt, but I was able to use sudo vi /etc/hosts and save the file.

So why couldn’t I get any of the GUI apps to save it?

Turns out, that you need to sudo the actual executable which is inside the TextEdit.app bundle. So the command I issued is this:

sudo /Applications/TextEdit.app/Contents/MacOS/TextEdit /etc/hosts

Voila!!

If you happen to own TextMate, then you can save yourself a lot of typing and heartache. TextMate installs a Terminal command called “mate” that allows you to perform the above sudo command. Just type:

mate /etc/hosts

BBEdit also has this capability:

bbedit /etc/hosts

TextWrangler as well:

edit /etc/hosts

Voila, again!! When you go to save your file, you will be prompted for your password.

Written by Terry Blanchard \\ tags: , , , , , ,