Apple Sells a Product, Not a PC

While speaking with a co-worker today, the topic of OS X being unavailable for use in VirtualBox led to a tangentially related discussion regarding Apple’s licensing restrictions for OS X. We shared the same sentiment: If Microsoft were to require users to purchase a PC from them as the only method to acquire their operating system, there would be a lawsuit. So, why does Apple get away with it?

Immediately after the conversation, I came to the realization that I, and many others like me (programmers, computer geeks, tech bloggers, etc.), have always thought about Apple in the wrong way: Apple as a computer company. I realized that Apple can control their operating system the way that it does because Apple doesn’t sell an operating system nor do they sell computers, they sell a product.

When you buy a GPS device for your car, do you get upset that you can’t install the operating system from that particular device onto a competitor’s device? Of course not. The operating system is specifically designed for that particular hardware and it would be ridiculous to think that it could (or should) be able to be easily ported to any other device. The hardware and the software are designed simultaneously in order to work together in as integrated a manner as possible. You are not buying the GPS operating system, you are buying a GPS device.

Apple wants (has wanted) to change the way we think about computers. This is the whole premise behind the “Think Different” campaign. Once this realization set in, a comment Steve Jobs made during an interview at D8 immediately made more sense:

We never saw ourselves in a platform war with Microsoft, and maybe that’s why we lost. We just wanted to make the best thing — we just thought about how can we build a better product.(Steve Jobs at D8)

We never think of Apple this way because our experience with computers comes from the likes of Microsoft and the various Linux variants. We’ve become accustomed to installing an operating system on any combination of assorted motherboards, processors, drives, etc. and then just installing the necessary drivers to make everything run as it should (in some cases this is a serious pain in the ass2). But this isn’t how Apple operates. They don’t sell you computer parts. That’s why they make it so hard to do hardware upgrades or to access the battery, because you’re not supposed to.

For consumers to think of Apple products as appliances, not as computers, is what I believe Apple wants. It explains many of the decisions that they have made regarding the iPhone, iPad and iOS. When you look at things from this perspective, it all makes perfect sense.

Those of us who don’t understand why people “drink the Apple ‘Kool-Aid’” don’t get it. And the reason we don’t get it is because we look at it the wrong way. Apple isn’t about tech specs, customization, or feature lists because the only people that care about that are geeks like me. All people want is a way to check their email, browse the web (i.e., FaceBook, Twitter, etc.) and not worry about what’s under the hood.

This, I think, is why so many iPhone vs. Android flame wars erupt on tech blogs. It’s like comparing a luxury car to a Formula-1 race car. One is all about speed and performance, the other one just wants you to get to where you want in as comfortable a way as possible. It’s ridiculous to compare the two and people who try don’t “get it”. They’re not even in the same category. Apple doesn’t want to be in the same category. That was never their intention.

As for me, I think I finally “get it”2.


1. In the past I have spent days trying to get integrated Intel graphics chips to work properly in an earlier version of Ubuntu.

2. One might expect an iOS developer to understand why people would choose Apple products, and I thought I did. But I found that despite the fact that I enjoyed my various Apple purchases, I could never explain or justify them to others. I think that now I can.

Kana Kanji Funtime

Kana Kanji FuntimeTwo things. First, I just finished/added a new app, check it out in iTunes: Kana Kanji Funtime. The goal with Kana Kanji Funtime was to create a fun and casual app that I (and others) could use to quickly quiz my kanji knowledge in a way that wouldn’t require actually sitting down and studying. It helps to mix things up from time to time and I think this is definitely more exciting than just drilling with flashcards. In the least, its a way to have preset goals to achieve and it encourages me to try to beat my previous high score. Anyway, I’ve been enjoying it and I hope you will too.

Second, a quick update on other things. There are some big updates coming to the other apps. Specifically, Learning Japanese and the Japanese Alphabet Study Guide. I don’t want to get into details, but I will say this – the plan is to convert both apps to universal binaries that will allow them to properly scale for the iPad. That is, after you download the version 2.0 updates, the apps will work natively on the iPad. I can’t commit to a timeline just yet, but I may post screenshots in the near future to show progress.

As always, thanks for reading.

Apple’s Updated App Store Guidelines

What a (welcome) surprise. Although these changes enable me (and other developers) to use third-party tools to develop iPhone applications (i.e. Unity, MonoTouch, Flash CS5, etc.), I think I’m going to stick with using XCode. There’s no harm in knowing more than one programming/scripting language, and I don’t have to buy any software.

John Gruber outlines the major changes to Apple’s app store guidelines on his site. Definitely worth a read. Additionally, Engadget has the official list of what will be rejected. It’s nice to – finally – know what will be rejected before spending hours of development time beforehand.

Japanese Alphabet Study Guide

Today marks two weeks of availability in the app store for my Japanese Alphabet Study Guide app and I thought I’d share my experience and what I’ve learned regarding iOS software development.

You can read about the rationale for creating the app, etc., if you’d like, via my guest post at JapanGaku. It’s not too long, but for the sake of the topic at hand, here’s a summary:

Learning the Kana (Hiragana & Katakana) is one of the first steps in learning the language. And, since Romaji isn’t used in Tae Kim’s guide, it seemed like a great place to start. … I looked at some of what appeared to be the more popular Kana/Kanji apps and tried to include in my own app what users felt was lacking in others (based on the reviews they were leaving). Ultimately, I decided not to include everything I initially wanted to before releasing the app. … [Doing so would have been] a significant effort, and as already mentioned, it makes little sense to invest in something that won’t be used (I’m reminded of the YAGNI programming mantra: You Ain’t Gonna Need It). (Source)

So, I had a pretty good idea of what I wanted to do before I started doing anything. In addition to researching related applications, I did some reading regarding the user interface design of an iOS app, and I looked at examples of some well-designed apps before deciding where to start. With some ideas in mind, I started throwing together some mockups together in Adobe Photoshop.

Japanese Alphabet Study Guide Photoshop app mockups

Initial design concepts for the Japanese Alphabet Study Guide iOS app in Photoshop

If you already know what the app looks like, it is evident that, graphically, a lot has changed (to me, anyway) since the initial design concept, but structurally, the app did not change significantly.

After deciding what I, basically, wanted the app to look like. I started putting together some prototypes, both in code and on paper, and began writing down ideas regarding application flow and functionality.

Japanese Alphabet Study Guide Prototyping

Japanese Alphabet Study Guide Prototyping

Typically, I might start with prototyping before I even think about how the design should look and feel, but since I already had in mind how the app was going to work, I did things a bit backwards this time around.

I learned a lot while creating my first application (I spent a lot of time on Stack Overflow), so I made sure to repeat those things that were beneficial/helpful the first time around. User testing, for example. I never realized how great a resource my Japanese meetup group was for testing until I started writing software. I would install beta versions of my apps on my phone to bring for testing and observe how various people interacted with the apps. It became immediately obvious that the way I thought the apps should work was different from the way other people expected them to work. What’s more, these people were/are actually my target demographic – perfect!

Screenshot of Japanese Alphabet Study Guide To-dosAdditionally, organizing things/”to-do”s that needed to be completed and adding tasks and ideas as they popped up was simplified thanks to the Things application. Things is probably one of my favorite apps, especially for getting things done. I can’t describe how valuable it has been to be able to add items/tasks to my to-do lists as they would come into my head (while trying to sleep, watching TV, reading articles, etc.). If you already have a to-do list manager, great! Use what works for you, but if you’re looking for one that’s simple, powerful, and elegant. Give Things a try.

Finally, keep in mind that you’re not really done with your application once it’s available for sale. If you’re fortunate enough, you’ll get some users that will leave meaningful reviews and provide insight into how you can improve your app (i.e. “If this app had feature X, it would perfect”, etc.). If users start complaining about crashes, be sure to check the crash logs provided in iTunes Connect.

Well, I guess that about wraps it up. I feel like I’ve kind of rambled my way through this, but hopefully what I’ve shared here can be useful to someone starting out in iOS (or software in general) development. In bullet points:

  • Plan & Research
  • Prototype & Design
  • User Testing
  • Review

10 things non-technical users don’t understand about your software

Came across this today, definitely worth a read if you develop software:

If you are writing consumer software you have to understand that you and your average user have a very different level of understanding of computers. When you first start doing support it can be a shock to realize just how vast this gulf is. It doesn’t mean that your users are stupid, just that they haven’t spent the thousands of hours in front of a computer that you have. (Source)

Read more: 10 things non-technical users don’t understand about your software.

Busy Year

I don’t normally do “status updates”, but it’s been a while since I’ve posted anything, so I’ll go ahead and do one. The past year has been kind of crazy, a lot of stuff going on. I’ve moved to ASP.Net C# as my primary back-end development language, although I still use PHP for most projects. I definitely believe in using the right tool for the right job, and sometimes .Net isn’t the right tool (sometimes PHP isn’t the right tool either). I’ve always been a fan of the strictness and type-safety of C#, and finally getting to use it on a daily basis is pretty exciting for me (Who gets excited about code anyway? Heh, I know I do).

I’ve also moved away from Flash development and into the “mobile sphere”. I’m still willing to do Flash where necessary, but I just don’t think that it makes sense for most websites. We’ve come a long way since the “All Flash” website “glory days”… I think that it’s fairly evident that mobile devices are the future. I’ve completed two iPhone apps (Learning Japanese and Japanese Alphabet Study Guide) and will probably start doing some Android development next year. I may even start posting more often… See you around.

Getting Smarty 3.0 to work with Zend Framework 1.9

Assuming you’re using the method demonstrated in the Zend Framework Manual, the first thing you need is to configure the Zend AutoLoader. Add this to the index.php file in your public directory:

// Configure autoloader
require_once 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();

// Require Smarty Engine
require_once 'Smarty/Smarty.class.php'; // Assuming that you have the Smarty engine at "library/Smarty"
$autoloader->pushAutoloader('Smarty', 'smartyAutoload');

Change the following line in “Smarty/Smarty.class.php” (about line 91) from this:

if (set_include_path(SMARTY_SYSPLUGINS_DIR . PATH_SEPARATOR . get_include_path()) !== false) {

To this:

if (!class_exists('Zend_Loader_Autoloader') && set_include_path(SMARTY_SYSPLUGINS_DIR . PATH_SEPARATOR . get_include_path()) !== false) {

Next, comment out the line in the Smarty Constructor (about line 237):

//$this->template_dir = array('.' . DS . 'templates' . DS);

We want to keep it a null value (which is the default). If we don’t make this change in the constructor (mentioned just above), we’ll get PHP Notices that Zend_Controller_Action_Helper_ViewRenderer tried to convert an array to a string.

Finally, add this to your bootstrapper class:

protected function _initView()
{
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(‘ViewRenderer’);
$view = new Zend_View_Smarty();

$viewRenderer->setView($view)
->setViewScriptPathSpec(APPLICATION_PATH . ‘/views/scripts/:controller/:action.:suffix’)
->setViewSuffix(‘tpl’);
}

If you’re using modules, you might want to make a slight change to the setViewScriptPathSpec method:

setViewScriptPathSpec(APPLICATION_PATH . ‘/modules/:module/views/scripts/:controller/:action.:suffix’);

You should be good to go. I should mention that this will cause your layouts to be parsed via Smarty as well; which presents its own problems. A potential work around is to include a common header and footer for each individual template, although this is far from ideal. In that case, what you might want to do is disable the view renderer’s auto render feature and create a custom plugin or action helper that will render the templates and layouts. I’m considering expounding on this in another post…

Zend Framework Migration and File Not Found

Recently I went through and upgraded a website from Zend Framework 1.7 to the latest 1.9 minor version. Everything worked great for the most part (aside from a minor code change involving Zend Filter for requests), but there was one significant change that was a bit of a hassle to fix (i.e. “File not found” and “directory listings prohibited” Apache errors).

One of the major changes since 1.7 is the functionality of the Zend Framework class AutoLoader. In previous versions of Zend Framework all you had to do was instantiate the AutoLoader and the classes would magically load as needed. But now it’s not quite so simple. The rationale, and it’s quite good, for the change can be read about in this Zend devzone article.

It’s important to mention at this point that if, for examle, your “IndexController” inherits directly from “Zend_Controller_Action”, you will not need to do any of this because in that scenario, you should not have any of these issues. These hurdles are only applicable if you extend the Zend Framework classes with your own.

Moving on… Instead of just instantiating the AutoLoader, you must now declare all namespaces that will be used throughout your application. For example, in your application controllers directory you might have a class named “BlogController.php” and your class would be named something like “IndexController” which extends a custom controller in the library that looks like “Blog_Controller_Action” and that class would extend “Zend_Controller_Action”. The AutoLoader knows where to find “Zend_Controller_Action”, but it doesn’t know where to look for “Blog_Controller_Action”. There are two solutions to this problem.

The easy answer is you to add the “$autoloader->setFallbackAutoloader(true);” function call, but this is kind of hack. In addition, using the Zend Framework default loader as a fallback means that every request to your site will result in an error, and then Zend Framework will try to use the default loader to resolve the request. This means extra load time and extra stress on the server. Granted, there is an “$autoloader->suppressNotFoundWarnings(true);” function, but it doesn’t work the way you think. Read more about the default autoloader on the Zend Framework manual here.

The correct solution to this problem is to declare all your namespaces and instantiate a unique AutoLoader for your models and controllers. For example:

// Set up autoload.
require_once 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);
// Just in case there's something we missed, we can leave the fallback

// Add resource loader, otherwise "file not found" errors are raised
$resourceLoader = new Zend_Loader_Autoloader_Resource(array(
    'basePath'  	=> '../library/Blog/',
    'namespace' 	=> 'Blog',
	'resourceTypes'	=> array(
		'model'			=> array(
			'path'		=> 'model/',
			'namespace'	=> 'Model',
		),
		'controller'	=> array(
			'path'		=> 'controller/',
			'namespace'	=> 'Controller'
		)
	)
));

$autoloader->pushAutoloader($resourceLoader);

You can read all the details here. It’s quite a change from the simplicity before, but it’s a good change.

In addition, you’ll need to make sure to update your .htaccess to the following or else you’ll get a bunch of “Directory indexes prohibited by server configuration” errors:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]

This also has been modified and improved over previous versions, for one, it loads Flash files (and other non-standard extensions) without a problem. Strangely, I didn’t see the .htacces directives in the Zend Quickstart tutorial, but it is in the Zend Framework’s manual Application Quickstart. The page names are similar but they are completely different.

In summary, until we made the changes mentioned above to our Zend Framework configuration our Apache error log was riddled with thousands of “File not found” and “Directory indexes forbidden” errors. The AutoLoader change resolved the “file not found” errors, and the .htaccess update resolved the “Directory indexes forbidden” errors. Hope this was useful.

Zend Framework on MediaTemple DV

I’ve done this a few times already, and it seems every time I make the same time-wasting mistakes. So here’s the process quick and dirty (be sure to follow the links if there’s a point you don’t understand or know how to do):

  • SSH into your website, navigate to your virtual host directory – the directory above the webroot (the one right above httpdocs) – this is the default directory when connecting via FTP.
  • Via SSH, create the necessary “application” and “library” directories above your webroot (same level as the httpdocs folder).
  • Via SSH, chmod 0777 the “application” and the “library” directories.
  • Download the Zend Framework and upload it to your recently created “library” directory above the webroot (easiest with ftp, or you could do it the harder way via wget).
  • Add your newly created “application” and “library” directories to your approved includes directories via open_basedir configuration on your virtual host. You should be adding something that looks like: “/var/www/vhosts/mt-example.com/library:/var/www/vhosts/mt-example.com/application” – pay attention to colon, :, placement.
  • Make sure you restart the server.

If you’ve never used Zend Framework before, you may want to follow along with the Quickstart from here.

If you’re going to using Flash, make sure to make the change in the .htaccess I mention here. Also, if you plan on uploading images at some point and would like MIME type validation and/or file information you’ll need to install the PECL fileinfo extension as explained by Jeffrey Barke on his website.

That’s it. Kind of a pain since you have to do this every time you set up a new site (domain or subdomain), granted you could probably put the framework higher in the operating system and just link to it, but that has it’s own problems (i.e. framework version support/maintenance) and it wouldn’t save you any steps. Anyway, hope this is as useful to someone else as I know it will be to me.