Our BlogTips, Tricks, and Thoughts from Cerebral Gardens

A Year From Now

Hello again iDevBlogADay readers!

For those that are unaware, Cerebral Gardens has been pretty much a one man shop since it's inception. Well, more like an eighth of a man shop since I've had a full time job the entire time. Earlier this month, I came across a quote:

A year from now you may wish you had started today.
-Karen Lamb

After reading it, I thought to myself, 'self, I wish I had started more than a year ago actually', and so I knew it was time.

As of October 1st, Cerebral Gardens will become a whole man shop! Plus a woman of course to keep me focused; someone has to crack the whip, and she's way more organized than I.

We have some exciting products that we'll be able to finish and bring to market soon. Plus, I'll be able to spend a bit of time writing more blogs for iDevBlogADay (ones more relevant to you than this one was).

If you're the type of person that likes to be inspired by quotes, you can check out a simple app I built a while ago to test Apple's push notifications. Carpe Diem. Message me if you'd like a promo code, I'll give them out in the order requested.

Add the Power of Dropbox to Every App

Ok, maybe not every single app, but if your app has any sort of data, then yes, you should add Dropbox support to the app. Certainly if the app is a tool of some sort, you understand that the user values the data that has been generated; but even if the app is a game, the user still values that data! If they've spent 5 hours to complete a tonne of levels, it's nice to have that accomplishment backed up, or available on a second device. This is where Dropbox comes in.

If you've been living under a rock and don't know what Dropbox is, it's a service that allows users to create a special folder on their computer that automatically syncs itself to the Dropbox servers and then any other computers also using the same account. This provides the user with a cloud based backup service (with a basic version control too). Using the official Dropbox iOS, Android and Blackberry apps, the user can access any of the files in their Dropbox account on the go. Sounds simple, and it is. So simple that everyone should be using it (especially since the basic service is free).

So how can you use this magical service in your apps? Dropbox provides an SDK for developers that lets you access a user's Dropbox account (with their permission of course). Now it's up to you to implement a solution to use it.

Before I go into detail on using the SDK (a future post), I'm going to suggest a directory hierarchy that we all follow. Remember that the root folder of the Dropbox is actually a directory on the user's computer that they're using. We don't want to clutter that folder with all kinds of stuff the user doesn't understand, they're likely to delete it.

One of the first apps I used that was Dropbox enabled was 1Password (An awesome app by the way). Their solution was to create a file called

.ws.agile.1Password.settings

in the root folder that only contained the location of their actual data. This lets users store their data wherever they want (provided it's still under the main Dropbox folder), and 1Password can still find it. There's a problem with this though, when you have lots of apps installed, all using a similar plan, you're going to have a tonne of junk in the root folder. Not user friendly at all. Not to mention, that while Mac OS X will hide a file starting with a dot by default, some of your users might not have switched from Windows yet and Windows will show the 'hidden' file in the folder, just waiting to be deleted.

My proposal, is that we create a folder in the Dropbox root called

.apps

as a central repository for third party app data. From there you use a reverse domain name system similar to your bundle id, but instead of dots, use new directories, and only use lowercase. So keeping with the 1Password example, they would store their data in

.apps/ws/agile/1password/

This will be consistent for their iPhone, iPad, Android, Mac OS X and Windows clients. All of their 1Password apps will be able to find the data regardless of system being used. Any data that is system specific can be stored further down the hierarchy.

This system should keep everything clean, organized and out of view of the user. Windows users will still see the .apps folder but at least it's just one folder and it's name should make it's meaning clear to most users.

Be aware that because you're now backing up your user's data to their Dropbox, they can now easily browse (and even modify) that data if they're so inclined. So make sure you protect this data if it shouldn't be seen or modified. For example, if you're game has 10 levels and you have to complete them in order to advance to the next one, don't record level completion in a simple format that lets the user effectively just check off that they've completed a level. If reading the data is ok (high score list etc), you can still use a simple format to store the info, just add some sort of validation to ensure the file hasn't been modified. A hash file will probably be fine for most simple cases (use some salt that you're keeping secret).1

Update (added this paragraph that was accidentally cut during my editing phase): Why bother using Dropbox in your app when iTunes backs everything up during a sync anyway? Well there are lots of reasons:

  • Not everyone syncs on a regular basis; shocking I know
  • If a user deletes an app, it deletes the data too, next sync, the backup is deleted too, if the user decides to put your app back on their phone, they have to start from scratch
  • Using Dropbox allows multiple devices to access the same data, play a game on your iPad, and continue later on your phone
  • It may be your app, but it’s the users data, so making it easy for them to access is a good thing

1 Note that the above point about checking for modified data files etc is vital even if you're not syncing to Dropbox, it's trivial for users to access/modify your data files through jailbreaking or even iTunes backups. Another issue is that the Dropbox folder is exposed to unknown other apps that might try to use the data contained within maliciously, scan for emails to spam, or account passwords etc. Those apps could be Windows malware etc so definitely encrypt sensitive data.

Will iOS 4.3 Change the App Store Ecosystem?

All indications point to the imminent release of iOS 4.3, if not this week, then certainly by next week. As always with new releases, a host of new features will be included, not just for users, but also for developers.

The rumour is that 4.3 will introduce subscription pricing options to the app store. This is in response to newspaper and magazine publishers looking for better pricing options for daily, weekly and/or monthly editions. But, who says subscriptions need to be limited to publications. Apple's Terms of Services don't. More on that in a bit.

One of the challenges of iOS development is earning enough revenue to make a living. It's been said that there are two app stores, App Store A, where you sell apps with mass market appeal, hoping to generate a lot of revenue in a very short time, and App Store B where you sell apps that target a narrower audience, aiming to generate a steady revenue stream for years.

App Store A is often compared to buying a lottery ticket, and has just recently made an appearance in Dilbert.

Dilbert.com

App Store B is considered to be the more attainable, long term success strategy. Since you're aiming at a narrower target market, it helps to be able to generate recurring revenue from your users.

I've long wanted to try charging a monthly or yearly fee to use an app, something that will support the development process after the initial sale. Every other software platform allows you to charge for upgrades in order to generate some recurring revenue from your installed user base. A few apps on the App Store have phased out the original version and released a new version, with a new charge. There a few problems with this approach, a) users who buy the app just before the switch, kind of get screwed, b) there's no easy way for a user to transfer their data from version 1 to version 2 (it can be done, but you have to build in a solution, unlike normal app upgrades), c) not all users of version 1 will even know version 2 is available.

Another option is to add new features and charge for them though in-app purchases, then a user can decide if the new features are worth the extra money to them, if not, no harm, they keep using the app as they bought it.

Back to the new subscription option. With subscription pricing there will be a new opportunity to generate recurring revenue from your user base. And to the user, it will be a well defined, easily understood method. $x per time period. Just like paying your monthly phone bill, or a yearly magazine subscription. You can cancel at any time, or keep paying and take advantage of all new features as they're released. For developers, you now have recurring revenue. Earnings to enable you to continue to maintain and support the app, while still feeding your kids.

There's no indication yet what the options will be from Apple, but it's a good guess that the same pricing tiers we're using now will apply, and that you'll be able to select from a variety of time periods, likely: weekly, bi-weekly, monthly, quarterly, yearly. As an example, you'll be able to charge $0.99 a quarter, instead of a one time fee of $2.99. If the user doesn't like your app, they save money. If they like the app, and continue to use it, you'll break even after 3 quarters, and earn more for the entire length of time the user uses your app.

The largest obstacle I foresee moving to this model will be the blow back from customers. The current app ecosystem has bred a sense of entitlement where users (not all, but a lot), feel they deserve an app, all future updates, full support etc, all for the low cost of $0.99. For most developers, and most apps, this isn't sustainable. Using a subscription will help solve this. As more of us developers begin to use this model, customers will begin to accept it and most likely actually prefer it, since they'll know exactly what they're getting and for how much, and their apps will constantly improve at no additional cost. And, all things considered, they'll still be getting their apps at a ridiculously low price.

Update: Apple officially released the information on subscriptions today. Subscription term lengths are: weekly, monthly, bi-monthly, quarterly, bi-yearly or yearly. Thanks Apple for giving developers more opportunity to become profitable!


iOS 4.3 is currently available as a beta and thus is under an NDA. Nothing I discuss here is covered under the NDA to my knowledge as there's been no official word about subscriptions other than the now public iTunes Terms and Conditions. If you feel I have disclosed something in the NDA, please let me know and I'll edit the post accordingly.

Copyright

© sabby

8 Developer Tools You Should Use

Today I'm going to cover some awesome developer tools that can make your life easier. These are listed in no particular order.

AppViz: http://www.ideaswarm.com/products/appviz/

AppViz is a tool for automatically downloading your sales, trends and financial reports from iTunes Connect, as well as the reviews for your apps. The app works by scrapping the information from the web so it breaks whenever Apple changes something at iTC, but, IdeaSwarm, the creators, are insanely fast at analyzing the changes and pushing out an update to accommodate. This is by far the best $30 I've spent, and to be honest, I don't know of a single developer with published apps, that isn't already using AppViz. So I guess this tip is for newbies. Get this app now, you'll love it.

MajicRank: http://majicjungle.com/majicrank.html

MajicRank by David Frampton (of Chopper 2 fame) is the tool to use to track how your apps are doing in the top 200 lists. It scans all regions, so you can see results in countries you can't normally access. It's similar to AppViz in that it scraps info from the web and so it can break, but it rarely does. MajicRank is free so there's no excuse not to use it.

TestFlight: http://testflightapp.com/

I mentioned TestFlight a couple of weeks ago but they're worth adding to this list too. They've created a great service so far, it's almost too easy to use! There are still some kinks to work out, but note that they moved quickly to resolve the security issue I pointed out in the last article.

DropBox: http://dropbox.com/

DropBox is a fantastic cloud storage system for users. It lets anyone backup important files or easily transfer files to another place/person effortlessly. They provide an SDK that lets you add DropBox support to your apps so that you can let your users backup and/or transfer their app data easily.

Amazon AWS: http://aws.amazon.com/

Amazon Web Services actually consists of several great tools. The two most popular so far seem to be S3 (another cloud storage system, but intended for companies not users), and SimpleDB (a simple database in the cloud). If your app is data intensive, there doesn't seem to be a better solution than Amazon for hosting that data. They now have a free starter plan too so you can try it out at no risk.

Matt Gemmell: http://mattgemmell.com/

Mr. Matt Legend Gemmell isn't really a dev tool, but he does make a few that you can use in your apps. The most popular ones are MGTwitterEngine (an implementation of the Twitter API) and MGSplitViewController (a replacement for the iPad's UISplitViewController that gives you more control/options). Check them out here: http://mattgemmell.com/source

Accessorizer: http://www.kevincallahan.org/software/accessorizer.html

I found out about Accessorizer through Jeff LaMarche who said it was one of his favourite apps. I can see why. The app is a source code generator. You teach it your coding style, and then it pumps out code for you. No, it won't build your next app for you, but it will save you tonnes of repetitive typing setting up all your class properties etc. If you value your time, Accessorizer will save a lot of it for you.

TouchXML: https://github.com/TouchCode/TouchXML

TouchXML is a library for reading in and parsing XML files. If you store your app's data and/or configuration in XML files, this is a far faster way of getting that info than using libxml. You can quickly extract exactly what you need from XML in just a few lines of code. Truly indispensable. And if you'd prefer JSON over XML, there's a TouchJSON available too.

Hopefully some of these tools will help you or a friend on your next project.

TestFlight Your Apps

You've been working on your new app for ages and it's finally ready for beta testing. Prior to iOS 4.0, it was a considerable pain in the neck to get a build on to your testers devices. You needed to package up your apps and ad hoc profile, send them to each tester, and then they needed to use iTunes to install the profile and app on their device. It seemed like an art more than a science getting an app installed, never mind an updated build later. It was a very clunky system, and it didn't always go smoothly.

With iOS 4.0, Apple made it much easier to install test apps on a device. It's now possible to install profiles and apps without going through iTunes. Using XCode's Build and Archive option, you can create an .ipa file that embeds the ad hoc profile. Just put the .ipa file on a web server, (or your public Dropbox folder), and send the link to your testers. They can install the build by clicking the link in mobile Safari.

You're still required to collect your users UDID's, add their devices to your developer account and create an ad hoc profile that includes their devices.

Last week, TestFlight, a new service for distributing your test builds to your beta testers, went live. TestFlight promises to revolutionize the way developers beta test their apps, and after testing it out for a bit, I'm pretty sure they're going to do just that.

The free service, found at testflightapp.com, allows a developer to invite people to become a beta tester. The tester creates an account through the web site in Mobile Safari on their device, and then they register their device with the system. This process involves installing a configuration profile (different from an ad hoc profile, but listed in the same area on the device's settings). This gathers the device UDID and reports it back to the server. A tester can register more than one device. The tester, and her device(s) then show up in the developer's account. As a developer, you can export the UDID's of all your testers and import them into Apple's iOS Provisioning Portal. One issue I found here though, is that if you attempt to import a file of UDID's that contain a record that you've already added to the Portal, it will reject the entire file, instead of just ignoring that record.

Once you've imported all the new UDID's into the iOS Provisioning Portal, you can update your ad hoc profile to include all of your testers. Then, use it to create a test build of your app. You still need to use XCode's Build and Archive Option, and then use it's sharing wizard to create the .ipa file (all in all, a simple process, more details here: http://iphonedevelopment.blogspot.com/2010/05/xcode-32-build-and-archive.html).

Next, you upload your .ipa file to the TestFlight web site, and select the testers you'd like to notify of the new build. TestFlight emails each of them a link to a page that lets them install the build easily.

TestFlight lets you see how many times the .ipa file was downloaded (though, not by whom for some reason). I had one person delete it from their phone and redownload it, and it counted as another download. So a list of 5 people, with 5 downloads, doesn't really mean they all downloaded it. But it will likely be close.

I tested this entire process with some extremely non-technical people, not one had an issue. They were all able to create their accounts, register their devices, and install my test app with ease.

If you need more beta testers, TestFlight offers a recruitment tool. You can start recruiting random people through Twitter, your web site, or wherever. It's just a link you post. When people sign up to be a beta tester for you, you can accept or reject them based on whatever criteria you like.

Overall, I'm very impressed with the initial service offering TestFlight has. And, remember, it's entirely free (for now) for developers. They are charging for enterprise accounts.

I do have to point out one concern I have with TestFlight however. During my limited testing of the service over the last couple of days, I uploaded a few builds, sent them out to some testers, including myself, and then deleted the builds. When I went back to one of my test devices, I still had the link open in Safari to do the install, for a build that I had deleted in the TestFlight dashboard. So, I tested, and tried to install the build, that should have been deleted. It installed perfectly. This is my concern, because I had deleted the build! Which means, that TestFlight, is not actually deleting the bits of the builds you tell it to delete, it's just removing them from your dashboard. Whether or not you consider this acceptable is up to you (and your personal level of paranoia) . But remember, that when you upload your .ipa to TestFlight, you're letting unknown people view and test your ideas (yes, the TestFlight people can view and run your .ipa files, if they so choose).

If you are concerned, you can use Hockey to manage your beta installs. It's not as easy to manage as TestFlight, but you con trol everything on your servers so it's arguably more secure.

You can even mix and match some of the TestFlight features (UDID collection, recruitment etc), and then deliver the actual builds via Hockey.

Paranoia aside, TestFlight is excellent so far, and will change the way you deliver your test builds to your testers. Down the road, they plan to support additional features, such as adding analytics so you can view what your testers tested and for how long.

Dev Tips & Tricks

Today I'm going to cover some useful tips and tricks. These are presented in no particular order, and are pretty much unrelated to each other. Hopefully you'll find some, or all of them useful.

1. Regarding the upcoming iPad 2

Reports are starting to surface that the next version of the iPad will support a retina type display. Apple will no doubt repeat what they did with the iPhone 4 and double the resolution (4 times the number of pixels). This makes it easy to support old apps on the new device by employing pixel doubling.

But, you can start preparing for this now! For every iPad image you use, include a higher resolution (double sized) image with the @2x suffix. And for icons, include a 144x144 (double 72x72) icon. I've included a 144x144 icon in all my iPad apps since the iPhone 4 was announced, betting on Apple doubling the iPad resolution. It's cheap to do, and if the predictions are wrong, there's no harm in having an unused icon.

As a sub tip, you should include the following sizes for your icons: 144x144, 114x114, 72x72, 58x58, 57x57, 50x50, 29x29

2. self.var vs var

In your classes, when use the following syntax:

DWClass.h

@interface DWClass : NSObject {
    NSObject *myObject;
}

@property (nonatomic, retain) NSObject *myObject;

DWClass.m

@synthesize myObject;

You're telling the compiler that your new class DWClass will have a property called myObject, and that it should create setMyObject (setter) and myObject (getter) methods to access that property. And that those methods should handle your retain/release cycles for you. Any other objects that need to interact with your myObject property, will do so by like this:

dwClass.myObject // (assuming dwClass is an instance of DWClass)

And this will actually call the appropriate setter/getter for the myObject property, which in turn interacts with the myObject instance variable of the dwClass.

Inside the DWClass however, you can access the property like this:

self.myObject

And the same setter/getter methods are used.

Inside the DWClass, you can also access the myObject instance variable directly just by referencing it. DO NOT do this. If you do that, you're not using the setter/getter methods, which means you're not automatically handling the retain/release calls. This is a surefire way to create hard to find bugs in your code. Plus, there are other problems with doing this. If down the road, you need to do something special whenever that property is accessed or updated, so you ditch the @synthesize and create your own setter/getter methods, you're now going to miss even more than the retain/release calls, you're going to miss whatever else you've added.

This entire tip also applies to non-object properties. Even if you're using a standard int as a property, always use the self.variable syntax to access it. It's just good practice and will save you headaches down the road.

3. Keeping your secrets, secret

Often when you're accessing other services, Twitter, Dropbox, your own servers etc, you may need to store passwords, API keys, etc in your code. It's dead easy to just have a constant like this: @"MySuperSecretKey" and be done with it. If you do that though, you may as well post the secret on your web site for all to see. Since, it's trivial for a bad guy to extract your secret from the compiled code they download from the App Store after your release. This is a bad thing. In the case of Twitter for example, some spammer could put your secret key into a rogue app that spam blasts users. Every one of those tweets will say it was sent by your app, and your legit app will be blocked pretty quickly. Your users will be locked out until you submit a fix and have it approved by Apple, say goodbye to two weeks of sales, not to mention, all the bad reviews you'll receive for selling a non-functioning app.

So, keep your secrets secret, use some encryption inside of your app to encrypt your keys etc. It doesn't have to be complex as the bad guy usually just looks for low hanging fruit (unless they are specifically targeting you). You can use one of the many encryption libraries available, or even roll your own if you're so inclined.

4. Ensure the App Store knows you support multiple languages when you do so

This tip comes from a mistake I made in version 1.0 of the Cruze app. The app supported English and French from the get go, but it was done by detecting the language of the user via code and loading the correct set of files for the primary language. This worked great and was way less work than using Apple's recommended method of localization for every nib etc.

One problem though, once the app was released to the store, the only supported language listed in iTunes was English. Because I used my own language detection iTunes Connect didn't detect French. I fixed this in 1.5 by using Apple's localization on a small dummy text file. One that I don't actually use for anything in the app, but that is enough to trigger the language detection tools Apple uses.

Update: see Ovogame's comment below for an even better way to fix this issue.

5. AppName_Prefix.pch

There's a file in your XCode project named AppName_Prefix.pch (where AppName, is your app's name). This file is included at the top of every source file in your project. It's a great place for you to store any constants you need across your app.

6. A Better NSLog()

A common method of debugging is to add NSLog() calls throughout your code. The messages are echoed to the screen as the code runs and you can see what's happening, giving you hints as to what's causing bugs. When you're finished however, and you want to do your final build, all of those NSLog() calls remain in your final build and all of those strings are available for anyone looking through your binaries to see. Who knows what secrets you might disclose.

Instead of using NSLog(), I use DebugLog(). This is a tweak of a function I’ve seen others use, based on the answer here: http://stackoverflow.com/questions/300673/is-it-true-that-one-should-not-use-nslog-on-production-code.

Add this to your AppName_Prefix.pch file:

#ifndef DebugLog
#ifdef DEBUG
#define DebugLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, \
	[[NSString stringWithUTF8String:__FUNCTION__] lastPathComponent], __LINE__, \
	[NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DebugLog( s, ... )
#endif // DEBUG
#endif // DebugLog

Now, replace all of your NSLog() debugging statements with DebugLog(), and define DEBUG in your debug configuration (sub tip 2: go to your Project Info, Debug configuration, search for Preprocessor Macros, add DEBUG).

After this, use DebugLog() all you like, and the strings are skipped over in your Release and Distribution builds. You also have the added bonus of having the function name and line number included with all debug statements now, making it clear what's generating the messages.

7. *.dSYM files

Whenever you build your app, XCode will output the *.app files, as well as a *.dSYM file. For Debug and Release builds, you can just toss/ignore the *.dSYM file. But for your distribution build, that you're going to submit to the App Store, make sure you keep the .dSYM file. You'll need this later, to analyze crash reports. I'll go into more detail on this in a later post, just know you need to keep the files. For the impatient, you can read more on this here: http://www.anoshkin.net/blog/2008/09/09/iphone-crash-logs/

8. Push Notification Certificates

If you have an app that uses push notifications, you need to generate a certificate with Apple, one of the first steps, is to create a Certificate Request file (CertificateSigningRequest.certSigningRequest), that you send to Apple. Keep this file. When your certificate expires, you'll need to request a new one. You can reuse the same Certificate Request file and skip the first few steps.

9. [object release]; object = nil;

With NSObjects, when you're done with them, you call release to reduce the retain count and let the system know you no longer need it. When that retain count hits 0, the system free's the object and releases the memory allocated back for use later.

It is common practice, to set the object to nil after you call release. This prevents a possible crash later, if you attempt to call a method on an object that has been freed. That's because if you try to call a method on a nil object, the system just ignores it, no error, all is good (or is it). If you don't set the object to nil, then it will still point to the memory address that was allocated for that object. There's a chance that object is still there (if something else was using it and increased the retain count for example). In that case, calling a method on that released object, will still work. But if that memory had actually been released calling the method would cause a crash.

This is why developers often set the object to nil, to prevent that crash in the case of a bug. But, this doesn't fix the bug, it just hides it from you. So, I subscribe to the second school of thought you shouldn't set the object to nil. If you have a bug, let the app crash while you're developing and you'll be able to find and fix that bug. When you no longer have any crashes, you'll know you're (closer to being) bug free, and that you haven't just masked your bugs.

Open Source, the GPL, and the App Store

I am a believer in the idea that a large subset of humanity enjoys helping one another to be successful, and that they become better themselves in the process. One way this occurs is with the Open Source movement. People that write software not for the profit that can be made with the software, but to give it away so that others can use it, as an end product to accomplish a task, or even to use as part of another project. This enables the next person to get a jump start on what they're working on in order to become successful faster than they would have been if they'd had to start from scratch.

Ideally the next person becomes a link in a chain so that others can benefit from their work and become successful themselves. Everyone does their part and everyone benefits.

Not all Open Source products are equal however. Just because someone releases their code as open source, doesn't mean you can do whatever you want with it. There is always a license of some sort attached to the code that governs what you're allowed to do. The Open Source Initiative site lists 67 different licenses that they've approved as meeting the existing community norms and expectations of what an open source license should be. Before we go any further, let me clarify that I am not a lawyer, I don't even play one on TV. So you should always consult your own legal council when dealing with legal matters.

Of all of the open source licenses, there are a few that are used more than others. The GNU General Public License (GPL), the Apache License, BSD License and the MIT License are the most popular. The latter 3 are very similar and impose the least restrictions on users of the code they license. The GPL imposes some very specific implications on users of the code it licenses and is the reason I'm writing this article today.

In simplified terms, the Apache, BSD and MIT licenses allow you to use the code they cover in other products and allow you apply a license of your choice to the new product. It doesn't have to be an open source license and so you're not required to provide the source of your product to others. You do have to include the appropriate copyrights for the source you've used that was created by others, and you do have to accept the fact that the source is provided to you AS IS, that there's no warranty of any kind given by the original creators of the code you're using.

The GPL however forces you to use it as the license for your new product. In this way, it has been described as a virus license since it effectively reproduces itself onto your product, and limits what you're allowed to do with your product. That is, you're forced to release the source code of your new product, and you must allow others to redistribute your product for free, in both source and object code. The philosophy behind this is that if you're benefiting from the work of others, you should be forced to share your work in the same way so that others can benefit. These restrictions make the GPL incompatible with the App Store, which means, as an iOS developer, you should avoid using any code that is covered by the GPL.

The reason that GPL code is incompatible with the App Store is the requirement that someone receiving the product be able to redistribute that product to someone else. Since all apps in the App Store have Digital Rights Management (DRM) applied to them, users are unable to directly share the apps with others. Because a developer is unable to give that right to the user, they are effectively barred from distributing their app through the App Store.

Just yesterday, this became an issue on the App Store as the popular app VLC was pulled by Apple due to complaints that it's presence on the App Store was a violation of the GPL. Even though the app was available for free, and the source code to the app was made available at http://git.videolan.org/ for anyone that wanted it, the DRM issue overrules and thus, no VLC for you.

As a user this is disappointing since the app allows you to play media files that no other app on the App Store, or built into iOS devices can play. But as developer, this is extremely alarming and should cause you to audit all the libraries you've used to ensure none are covered by the GPL, else your apps could suffer the same fate as VLC.

What's most disturbing about all of this, is that it seems as though, this is really just a silly technicality. The fact that a user is unable to share the exact binary they downloaded from Apple doesn't mean they can't share the app with a friend. The user can share the app just by sharing the iTunes link to the download (which is free), or alternately, provide the full source code. So the spirit of the GPL is still possible with the App Store, just not the letter of the GPL.

It would be possible for the Free Software Foundation (creators of the GPL) to release an updated version of the license to make it compatible with the App Store, but since they feel that all DRM is inherently evil, it's unlikely that will ever happen. Arguably, it might be possible for Apple to make DRM optional for certain apps, but that would require fundamental changes to the iOS architecture and might introduce security holes that make it easier to pirate apps. I don't see either side making any compromises here so your best bet, is to just avoid all GPL code and find (or create) alternatives that are licensed under the Apache, BSD, or MIT licenses.

Discussion - Reducing App Store Piracy

This week, I'd like to throw something out for discussion. These are ideas that have come up in the course of real life discussions with other app developers. I need to preface this by saying that I have not implemented any of these ideas, and that I'm only putting the ideas out there to encourage you to think about and discuss alternatives.

It surprises me that in an ecosystem of 99 cent apps, piracy rates are still incredibly high. For this article the assumption is that as an iOS developer, you are able to detect at runtime, if your app has been pirated. There are multiple ways to do this, but the technical details of which are not required for this article so I'm going to skip them.

One of the requirements to install a pirated version of an iOS app on a device, is that the device needs to be jailbroken. If the device has been jailbroken, then certain security features will have been disabled. This makes it possible for apps to do things on the device, that Apple doesn't allow under normal circumstances.

This means, that a normally well behaved app, could be made to 'go rogue' when it detects that it has been stolen by the user. For instance, a stolen version of your app, could make a phone call to a charge per call phone number that charges the cost of the app to the users phone bill, therefore recovering the cost of the app for the developer. Similarly, the app could send a premium text message out, also charging the cost to the user's phone bill.

Now, I'm not proposing that you actually build this into your apps, as it's almost definitely the wrong way to go about building up your business1. As iOS developers, is it not part of our job to educate users on the dangers of using pirated apps? The above ideas can be used in the same way we've warned against pirating desktop apps due to the dangers of viruses and other malware. Common users should be encouraged to live in Apple's walled garden as is indeed a great place for users and developers to be.

1 A user that has pirated your app is still a potential customer and needs to be treated as such.

Discussion - Apple's App Store Policy Against Name Squatting

Today I'd like to discuss Apple's recent policy change with regard to app name squatting. If you're unaware of the policy, Apple says you must now submit your binary for an app within 120 days of reserving the name. If you don't submit a binary, you'll receive warning emails with 30 and 7 days remaining in your 120 day grace period. At the end of 120 days, if you still haven't submitted a binary, the app is automatically deleted by iTunes Connect and you're forbidden from using that app name again in the future.

The idea behind this policy is likely to prevent the ridiculous name squatting environment the exists with domain names. Personally, I don't believe that Apple has come up with a great solution to the problem though. 120 days isn't long enough for an independent developer working in his/her spare time to create a good quality app. And there's a known work around anyway1, that just forces you to do an extra 5-10 minutes work per name to reset the 120 day count. So what has been accomplished? It makes it awkward for someone to register a tonne of app names and just sit on them, since the 5-10 minutes add up fast.

I propose that there is a better solution. Instead of an arbitrary time period to submit an app, why doesn't Apple limit each developer account (that is, per $99 fee), to an arbitrary number of incomplete apps. Lets say 10 for example. In my hypothetical world, you can squat on up to 10 names for each $99/year. Making app names cost about $10/year, similar to domains. But the domain ecosystem is a disaster you say. Well the difference is that with domains, there's a whois database. Everyone can find out who has registered a domain, and contact them in order to generate a sale. There is no current way to find out who has reserved an app name, and thus no way to buy the rights to a name. Which means, there is no market for buying and selling app names; crazy domain name ecosystem averted. The only people reserving app names will be those who plan to use them.

I'm sure there are problems with my proposal also, or that you have an even better solution. Please add to this discussion here.

1 Rename the app that's about to expire to some gibberish, and recreate a new app with a new SKU and the original name you're reserving. Credit: Daniel Jalkut

Three’s Company: Multiple XCode Versions Living Together Peacefully

Apple is making fantastic progress with iOS. They continue to release firmware updates and betas at a frequent pace, and with each new release, developers must download and install a new version of XCode compatible with the new firmware. Managing the various versions and their associated firmwares can be a challenge. In this article I'm going to give you a couple of tips that will hopefully help.

It's not uncommon for developers to have multiple versions of XCode installed on the same system in order to support development/testing across a wide range of devices and firmware versions. XCode by default installs in /Developer, and it is common practice to install the latest beta version in /DeveloperBeta. Those testing XCode4 know its default install folder is /XCode4. Personally I found this to be messy and inadequate.

My preferred setup now is to create a directory /XCode and install each version of XCode underneath using the version info as it's base folder name. Currently this looks like this:

/XCode/3.2.3_4.0.2
/XCode/3.2.4_4.1b3
/XCode/xcode4_dp2

When installing XCode in this fashion, you’ll find that in some cases, you won’t be able to install/debug a build on one of your devices because of a mismatch in firmware versions. For example, the XCode 4 Developer Preview 2 was released before firmwares 4.0.2 for iPhone and 3.2.2 for iPad. So if you’ve updated your devices to those firmwares, you’re now unable to use XCode 4 to directly install or debug.

There is a simple fix however. You just need to create symlinks from one version of XCode to another. Assuming you’re using a layout similar to what I’ve detailed above. If you look under /XCode/xcode4_dp2/Platforms/iPhoneOS.platform/DeviceSupport you’ll see folders for each version of iOS that you can install/debug on. 3.2.2 and 4.0.2 are obviously missing. If you’ve installed the latest version of XCode 3 with support for those versions, you can make XCode 4 work with them.

In terminal, issue the following commands to create the required symlinks:

ln -s /XCode/3.2.3_4.0.2/Platforms/iPhoneOS.platform/DeviceSupport/4.0.2 \
	/XCode/xcode4_dp2/Platforms/iPhoneOS.platform/DeviceSupport
ln -s /XCode/3.2.3_4.0.2/Platforms/iPhoneOS.platform/DeviceSupport/3.2.2 \
	/XCode/xcode4_dp2/Platforms/iPhoneOS.platform/DeviceSupport

Similarly, If you’re using the 4.1 beta 3 firmware on your iPhone, you’ll need XCode 3.2.4_4.1b3 installed, and can then enable support for that firmware version in XCode4 also:

ln -s /XCode/3.2.4_4.1b3/Platforms/iPhoneOS.platform/DeviceSupport/4.1\ \(8B5097d\) \
	/XCode/xcode4_dp2/Platforms/iPhoneOS.platform/DeviceSupport

If you have your XCode versions installed under a different directory structure (/Develper, /DeveloperBeta, and /XCode4 etc), you’ll just need to tweak the above lines to point to the correct folders.

A similar trick can be used to allow you to use a base SDK of 3.1.3 or earlier, which is no longer included in the latest versions of XCode. Just create links under the /XCode/Platforms/iPhoneOS.platform/Developer/SDKs to an older XCode that does include support for the SDK you need.

If you have any tips to improve upon this, see an error in what I’ve described, or otherwise have anything else to contribute, please let me know.

Some Thoughts on Tweetie

Everybody else seems to have a blog, so I suppose Cerebral Gardens ought to have one too. This will be written by me, Dave Wood, the founder and developer.

The issue that has compelled me to finally write something is the whole Tweetie upgrade pricing issue. First, I want to say that I always try to look at an issue from every side, though I'm not always successful at that. In this case it's pretty easy, since I'm both a developer and a user. Next, I'll admit that while I did buy Tweetie v1 for iPhone, I barely use it. I use Tweetdeck most of the time because of it's quick account changes. And Twitterific the rest of the time. Bought Tweetie just because it worked during the twitpocalypse. I do use Tweetie on my Mac exclusively (with the ads 'cause I like the ads, very relevant to me).

So, the issue with Tweetie v2 being a fully new version with no upgrade path is a tough one. Largely because developer’s choices are limited due to some of the restrictions imposed by the App Store. Enough people are writing about how to fix the store, so I'm going to present options that may work with the current setup of the store.

There are two main problems to deal with here (again, not counting the App Store issues). 1. Users expectations for free updates. 2. Developers needs for a sustainable business.

Regarding users expectations for free upgrades: I believe there should be an expectation for free upgrades for some length of time whenever someone buys software. That time is up for discussion. With a $1500+ Adobe Suite purchase or even Apples $69 iWork product, I believe that time period should be at least a year. With a $3 app, perhaps it should only be 30 days. Although I believe current users are expecting longer. Anyone expecting, or offering, lifetime updates is insane. That's obviously not sustainable.

But the expectations do exist; whether or not they should. Developers (myself included) need to start setting customer expectations to match our plans. Stating what the upgrade path will be in our app description for instance. Just stating something like 'free upgrades for 30 days' etc. As I type that I have to laugh. With a 14-20 day review process 30 days doesn’t seem like enough. 3 months perhaps.

John Gruber of Daring Fireball fame (whom I read religiously) compared buying a $3 app to a $3 cup of coffee. I don’t believe this is a fair comparison. The only thing they have in common is their price. A cup of coffee is a physical item, actual water, coffee beans, cream and sugar maybe, as well as a paper cup, and a plastic top. A person has to physically take your order, prepare the coffee to your taste, and hand it to you. The whole process takes a minute or so of someone’s day. If 1000 coffee’s are ordered at the same time, it takes a lot of people to serve them up in the time expected by the customer. Compare this to apps. There’s nothing physical with an app, not even a disc with iPhone apps. Once the app is made (and of course there is a cost there), it doesn’t cost much more per app ordered. It costs the developer (almost) the same to develop the app whether it ends up selling 10 copies, or 10 million copies. A closer comparison would be comparing apps to songs. We pay about $1.29 per song now. Imagine the uproar if songs were $3 each. Heck, I think $1.29 is expensive, but I pay it.

Continuing to compare to music, consumer’s expectations have been set; people buy a song or CD and they’re done. They don’t expect to get the same song again in a new format if it comes out; people joke about how many times they’ve bought the White album. They don’t expect to get an extended, or remixed version of the song for free if one comes out. The point here is that expectations of users can be set to be very low.

Perhaps this is what Atebits is starting to do. They’re reducing the expectations of their users, drastically. Possibly too fast, hence the uproar.

I've read that Atebits has said they would like to offer an upgrade path that gives current users a discount, but that it's not an option with the App Store. Here's one way it can be done. (This isn't pretty and I wouldn't recommend anyone else do this; further below is an option that could work for the rest of us, with time to plan).

Set Tweetie v1 to $999. No sane person would buy it at that price. If they do, Apple will refund it, (and hopefully not ding you the full refund price as indicated in the dev contracts). Then submit v2 as two apps, an update for v1 users, and a new app for $3 with text in the description to set the users expectations correctly. V1 users get the update they expected and also have their expectations for future updates set to nil. When v3 is ready, v1 and v2 are removed from sa le, v3 is submitted as a new app.

Regarding problem 2, the sustainable business: obviously developers have to be paid for their work, and continue to be paid for building upon that work. I’m going to assume that the incredibly low app prices aren’t going away; even if most developers raise their prices, there will always be bottom feeding app spammers (such as Brighthouse Labs) selling crap for $0.99.  So Atebit’s plan to release Tweetie v2 as a separate app actually makes sense (after setting expectations correctly).  But lets take it a step further.

I believe that we should be selling our software based on the time the user will use the app. Pick a value you want to charge per month of use, in this case, we’ll go with $1/month. Adjust these rates when/if prices in the App Store in general change. If you estimate your app has a 1 month life for the user, perhaps a game that will become boring/be completed in that time period, charge $1. If it's good for 3 months, charge $3. If the app is like Tweetie and useful for a year, charge $12. From here, we get my other possible solution (for the rest of us).

This option requires planning, so it's too late for Tweetie. If you expect a 6 month life of the app from v1 release to v2 release, price the app at $6. Each month drop the price of the app by $1. When v2 comes out, price it at $6 again. V1 goes to free, but is unsupported, or could even seize to function if that’s made clear to the user before they buy it. This is giving your users a set cost per month of usage. It’s not perfect, but much closer to what people expect, and it's a sustainable business model for us developers. I believe this will work extremely well if lots of us start using the model. This could likely be implemented via in app purchasing, by charging for each month of usage.

I’m going to stop here, without a final conclusion since I consider this just part of an ongoing discussion. I look forward to continuing to discuss these issues further and working with others in the community to solve these problems (among others) while creating successful businesses.