LGPL and the iPhone

The entire point of the LGPL is to give closed source applications access to an open-source library in a way that maintains the freedom of the library. Specifically, the user of the application must be able to change the LGPL library and have the application use it.

To achieve this, the
LGPL gives you a few options for compliance. I am not a lawyer, but I believe that all of them are incompatible with iPhone apps delivered legally through the AppStore. I will lay out my reasoning here:

Section 4d gives two options for compliance: Either provide the source or object files suitable for relinking (4d0) or use a shared library (4d1).

Shared libraries are out, because Apple does not permit their use in the AppStore.

Section 4d0 is a little more complicated. For an application targeted to a PC or Mac, it would be easy to comply by just packaging up your .o files, the LGPL library, a makefile, and documentation. However there are subclauses in section 4 that make me believe that there is no way to comply on the iPhone. Specifically:

Section 4d0 not only specifies that you must convey the minimal source and object files, but you must also provide terms. Together they must “permit the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work”

Section 4e requires that you provide instructions that allows some to change the LGPL portions, create a new combined work and install and execute that combined work.

To do either of these things, the user would need to be enrolled in Apple’s developer program which costs $99/year. These terms are implicitly part of your terms, meaning that it’s basically equivalent to you charging $99/year for the user to make modifications.

The GPL allows you to charge what you want to convey the Combined Work to begin with, but section 10 of the GPL (which I think still applies to the LGPL) states:

You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License.

Now, obviously, being able to develop isn’t free, but those costs are not as directly related to exercising your rights as the $99/year is. Specifically, you cannot create an executable or put in on a device without the certificates you obtain from the program.

Here’s an alternative view from
Huy Zing -- I think the “Spirit of the LPGL” section in the blog is actually required by the text of the license.

Here’s a discussion on the cocos2d forum about
switching away from LGPL. They tried adding to the license at first and then moved to an MIT license.

I haven’t been able to find any official ruling on gnu.org, so I will write them and see if they can add to their FAQ (
as they did for Java when it was an issue).

Understanding EXC_BAD_ACCESS

A couple of days ago, I wrote about how to debug a crash that reports EXC_BAD_ACCESS. One thing I didn’t cover is what EXC_BAD_ACCESS means, which I’ll try to do now, as it will clear up a lot of the questions I’m getting about the previous blog.

The description here is a high-level way of thinking about it. The details are quite a bit more complicated, so I’m simplifying it.

On the iPhone (and most modern OS’s), your application is given memory as you need it. The memory is given in chunks that are bigger than your request, and then the unused parts are parceled out over the next few requests.

When you deallocate an object, that chunk can’t be returned to the OS right away. It has to wait until all of the memory in the chunk is deallocated.

Inside all of this memory is a complex data structure that is maintained by the alloc and dealloc messages to organize how each part of the allocated memory is being used. The pointers you hold are just part of that datastructure (where the object is), there are other parts that are only used by the allocator.

What EXC_BAD_ACCESS is saying is that you did something that caused a pointer (yours, one internal to the iPhone, or one that the allocator is using) to be dereferenced and that memory location isn’t inside one of the chunks assigned to your program.

This could be because
  1. The pointer used to point to memory that was ok, but its chunk was deallocated.
  2. The pointer is corrupt.
The line of code that your app crashes on is not the root cause of the problem. The problem in #1 is whatever line of code caused the premature deallocation, and the problem in #2 is whatever line of code corrupted the pointer.

Your goal in debugging this is to make the problem line of code be flagged by either the compiler or debugger.

If you do that, then fixing it becomes a lot easier.

Of the two possible problems, #1 is far easier to find. It’s almost definitely because you didn’t use retain/release correctly and there where either too many releases or too few retains.

Do this:
  1. Run Build and Analyze. Make sure you fix or understand every single error it flags. I personally have 0 Build and Analyze errors in every project I have and I go out of my way to keep it that way. If I ever get a false positive, I figure out how to make Build and Analyze understand what is going on, so that it doesn’t flag it.
  2. Run scan-build with all checks on. This isn’t built in, so if you’re in a hurry, skip this for now. scan-build is the project that Build and Analyze is based on. It can be run with much more thorough settings.
  3. Set up Xcode so that it never deallocates. Instead, it turns objects into Zombies that complain if they are used. See Tip #1 on this post for instructions.
If you have a clean Build and Analyze and no Zombies complain of being accessed, and you still get EXC_BAD_ACCESS, then it’s a good bet that you are not accessing deallocated memory. It’s not a sure bet, because the iPhone SDK gives you access to the C library which uses a different kind of allocation, which you could be using wrong.

For #2, your task is harder. If a pointer is corrupt, there are lots of possible reasons
  1. The pointer could have never been initialized.
  2. The pointer could have been accidentally written over because you overstepped the bounds of an array
  3. The pointer could be part of an object that was casted incorrectly, and then written to
  4. Any of the above could have corrupted a different pointer that now points at or near this pointer, and using that one corrupts this one (and so on)

If this is the situation you are in, then these are the things that will help
  1. Enable Guard Malloc (Tip #2) - this makes the datastructure that represents the allocations much more sensitive to corruption. You need to use the enhanced features of the debugger to get anything out of it (explained in the tip).
  2. The line of code that triggers the crash is a clue to what pointer is corrupt. If you move it around it might be able to help you narrow down the point of corruption.
  3. If all else fails and you are desperate, try Valgrind.

Once one of these methods gives you a different problem (either a warning or another EXC_BAD_ACCESS), don’t worry that it seems completely unrelated to your original problem -- that’s a common problem with corruption.

Also, random changes to your program may make this problem “go away” -- it’s not really fixed, though. Your corruption or early deallocation is still there, but it’s not triggering an EXC_BAD_ACCESS. Its effects could be far worse, however, so it’s a good idea to try to keep reproducing it until you are sure you addressed the problem.

Things to remember
  1. Corrupting a pointer doesn’t immediately trigger EXC_BAD_ACCESS. Neither does using a corrupted pointer unless it’s specifically now pointing to memory that isn’t mapped to your application.
  2. Deallocating an object doesn’t immediately release the memory to the operating system -- only when the chunk is unused, can it be returned.
  3. The line of code that is triggering the EXC_BAD_ACCESS might not be the problem. It can be a good clue, but don’t assume the problem is this code.

Get iPhone programming tips in your inbox with my Beginner iPhone Programming Tips newsletter.

How to Debug an iPhone App Crash, Part 1: EXC_BAD_ACCESS

This is going to be a multi-part series on how to debug an iPhone crash.

This post is for how to debug crashes that show that the app received the signal EXC_BAD_ACCESS in the console. If you have this, the most likely thing that you are doing is sending a message to a released object. Another possibility is if you are using C/C++ allocations (or a library that uses it) and are overrunning memory or using freed memory.

Update: I explain this much better in a follow-up to this blog

Here are a few ways to debug that:

  1. Run Build and Analyze: This kind of Build is very good at finding retain/release bugs. Take a good look at everything it flags.
  2. Even better, run scan-build. I did a test recently, and found that some common errors are off by default in Build and Analyze that can be turned on in scan-build.
  3. Choose Run > Enable Guard Malloc in the menu, and then re-run your application. This finds a whole class of buffer overrun issues. If this detects it, you’ll see a better error in the console. Read this to see how to use Guard Malloc once it’s enabled.
  4. You can instruct the compiler to ignore release calls and then report if anyone is sending messages to objects that would have been deallocated. This results in much better errors in the Console if it detects them.
  5. Valgrind is the gold standard for finding memory bugs on Linux, and here’s a way to get it working in the iPhone Simulator.

Get iPhone programming tips in your inbox with my Beginner iPhone Programming Tips newsletter.

scan-build finds things Build and Analyze does not

Ever since I started using the latest Xcode, I’ve loved having scan-build built in as Build and Analyze. I did feel like it was less thorough, but I didn’t have time to prove it -- now I have.

There is one kind of bug that scan-build was very good at finding -- forgetting to set retained properties to nil in dealloc isn’t found by default in Build and Analyze. It’s not even part of the default scan-build any more (not sure why -- it was great).

Anyway, I recommend using scan-build directly instead of Build and Analyze. Here’s how:
  1. Download scan-build
  2. Just unpack it into any directory and add that directory to your PATH
  3. Open a Terminal and cd to your project’s root directory
  4. Run scan-build and view results

Here is a scan-build line that works for iOS 4.0:

scan-build -analyzer-check-objc-missing-dealloc -analyzer-check-llvm-conventions --experimental-checks -k -V -o scan-reports xcodebuild -configuration Debug -sdk iphonesimulator4.0 clean build

I’ve turned on all checks, and now it catches if you forget to set properties to nil in dealloc.

Run Build and Analyze often in Xcode, but every once and a while, run a full scan-build with the latest version as it finds problems that the Xcode version will not.

Get iPhone programming tips in your inbox with my Beginner iPhone Programming Tips newsletter.

Static Code Analysis for iPhone Apps

Starting with Habits 1.1, I started incorporating static analysis into my build. In my previous experience with things like Lint and FXCop -- I had found the signal to noise ratio to be too low to be useful. It's hard to believe, but scan-build is 100% signal -- every single issue it flagged was legitimate and needed to be fixed. Now, keeping Habits free from issues is easy, since I only have to deal with one or two at a time.

There were a couple of times I thought it was leading me in the wrong direction, but it was right so often that I just trusted it, and it was right about those too. I had a particularly interesting case with a custom table cell, where I wasn't releasing properly, and causing a crash when I dealloced the window. Scan-build helped me make sure I found that before release.

Get iPhone programming tips in your inbox with my Beginner iPhone Programming Tips newsletter.

Cocoa date functions are crazy

I thought Java was bad. Took me a while to figure this out and googling didn't help, so I am just putting this out there for the next person who needs this.

To get the number of days in a month:

+ (NSInteger) getDaysInMonth:(NSDate*)date
{
NSCalendar * cal = [NSCalendar currentCalendar];
return [cal rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date].length;
}

Reddit thread on iPhone Development

There's a great thread by an iPhone developer on Reddit.

Yay! It took several months but as of today I was able to search for my app and I saw it listed inside the app store. Now you may be saying "so what", but if you have ever looked into the steps that this takes, you know it's something to celebrate.My app is a very simple game, but I think I've learned enough during this process to distill some important lessons that may help you if this is something you've been wanting to do...

I wrote a similar post when I finally finished my iPhone App.

New iPhone Blog

Helen Crozier, the CalmTechCoach, has started a new iPhone Blog to keep all of her iPhone recommendations and reviews in one place. Check it out: My Fabulous iPhone

Start Habits not Resolutions

I saw this list of New Year's Resolutions on the Did I Get Things Done blog (originally from Amazon)

  • Lose Weight
  • Get Your Finances in Order
  • Go Greener
  • Curb Your Vices
  • Get in Shape
  • Relax More
  • Pursue a New Career
  • Upgrade Your Technology
  • Organize and Optimize
  • Start a New Hobby

The main reason that I have had a problem with a resolution is that I don't really think about them much a week or so after New Year's. A few years ago, I created a small web app for myself to log how well I was doing at keeping to resolutions I was making. A few months ago, I ported it to the iPhone as
Habits.

Instead of making resolutions this year, I created a few habits instead. I want to lose some weight this year (the #1 resolution), so I added a habit to run every 2-3 days, to do bicep/chest and shoulder/tricep weight training once a week. I want to keep my house in better order, so I added a habit to clean up and to process my mail pile more regularly.

A lot of these resolutions should just be a recurring task that you try to do as often as possible.

Habits reviewed in Macworld

Macworld reviewed some GTD iPhone applications including Habits:

Habits by Louis Franco helps users form good habits, which sounds simple enough. But developing habits requires a bit of time and discipline. It requires repetition and awareness. Habits keeps your calendar free from clutter associated with routine tasks or the general stuff of life.


Habits on Sale for $0.99 until the end of January

Habits is the perfect application to make sure that you stick to your New Year's resolutions, so from now until the end of January, I am putting Habits on sale for $0.99.

I am working on version 1.1, and I will post it at the end of January and return it to its old price. Until then, here's hoping that you're able to turn your resolutions into habits.

(The AppStore takes time to fully update -- please make sure it says that the price is $0.99 before you buy)

Buy Habits on the App Store

O'Reilly's iPhone AppStore Answers

iPhone AppStore Answers from O'Reilly's Inside iPhone Blog. There are frustrations with the AppStore, but as O'Reilly acknowledges, Apple appears to be listening:

Changes have been relatively slow to come to the App Store. However, with the addition of review copies, as well as limiting ratings to those who've purchased applications, Apple has made changes that have been welcomed by developers. I'm hopeful that the App Store will continue to improve over time and address additional issues.

The other major improvement is dropping the NDA for released SDK's, thus opening up the possibility of books, online tutorials and blogging about iPhone development.

More interesting iPhone pricing articles

From Chris Anderson's The Long Tail blog, I got this link to some interesting iPhone pricing and sales data.

Having more than doubled over the last two months, Gaming remains the largest category accounting for a quarter of all apps. The fastest growing categories were Education and Lifestyle. Medical is the newest app category and as of the end of November there were over 80 medical apps, the 10 most popular of which were free. Among Game apps, Racing, Music, and Sports were the fastest growing Game sub categories.

And, here's another iPhone app pricing article I got from John Gruber's DaringFireball. In the article, Peter Cooper uses popularity as a stand-in for units sold and and tries to figure out which apps have the most revenue. Put this one in your RSS feed if you are interested in hearing more as this installment covers mostly the Games category.

Seth Godin's iPhone App Ideas

Today, Seth Godin is giving away iPhone App ideas, the first one helps you avoid traffic:

Have the iPhone use the gps data... upload where I was a minute ago and where I am now. Figure out my speed and route. Use the data to tell other RadaR users which route is best. It's worth $20 a month if you live in a place with traffic jams. It's a natural monopoly--once someone figures it out, why wouldn't everyone want to use the market leader?

The Google Maps app on the iPhone has traffic data already--what's missing is that I don't think it takes that into account when selecting a route, or updates it if conditions change. If the traffic data is available with an API (like most google data), then this might be easier than even Seth thinks (no server side) -- of course, no lock-in either.

The second idea needs some kind of server-side dialier because Apple doesn't let apps run in the background:

Here's an easier one that you could probably sell as well. I type in a phone number and enter a time. Record a message and press go. I can cue up a bunch of messages that are based on time. I can have groups get the message I record, at the time I want them to get it.

Interesting iPhone App Pricing Articles

When I was trying to figure out a price for Habits, I found a few articles that were interesting. This one from Andy Finnell made the rounds on Reddit and advocates for busting through the $0.99 mentality and pricing applications in the $9.99 range.

The fix for pricing too low is really simple: raise your prices. Most $0.99 apps should become $9.99, $4.99 apps should become $14.99, and so on. With a $9.99 app, you’d make $7 per copy and at 16 copies per day, you’d make about $40,000/year. That’s not a great income, but that could potentially support one iPhone product being developed in some Iowan’s wheat field.

This other article from Andy is also good.

John Gruber made an interesting point when he linked to Andy (software with higher prices needs demos and refunds)

Tap, Tap, Tap has had a couple of AppStore hits, so what
they have to say is also very interesting.

iPhone apps are typically much smaller and more focused than desktop apps and as such, should be priced accordingly. In addition, you need to take into account the much larger market that you’re dealing with here… Apple is selling well over 10,000 iPhones per day and these are all potential new customers, plus all the existing iPhone owners and iPod touch sales.

Unit testing on the iPhone

Thanks to Google, there's a unit-testing framework for the iPhone. There's not much more to say about it -- the instructions are crystal clear and it worked exactly as described. It's compatible with OCUnit (the Objective-C unit test framework in XCode), so once you set it up, you can just create test cases the way you would for any ObjC project.

One quirk -- it instructs you to add a build step that runs the unit-tests during build time and shows the failures as compiler errors that you can then use XCode to track down. That's nice, but I have found that you don't really have enough of an environment to successfully run every kind of test -- they run fine if you run them in the simulator. The main problem I have is with setting up my database in my Documents folder -- I get errors at build-time that work just fine at run-time.

Get iPhone programming tips in your inbox with my Beginner iPhone Programming Tips newsletter.

How I use Habits

Habits was released last week, but before that, I had something like it on a private area of my website for me to use. This is what my Habits looks like right now (edited for brevity and to remove personal data):

habits-lou

Generally, I use Habits to help with Sharpen the Saw type of tasks -- things I want to make sure I do every once in a while, but not necessarily at a specific time. Also, unlike a recurring event in a calendar, I can record how well I do with them (if I do them late, early, or skip them).

Debugging memory based crashes on iPhone

On my Atalasoft blog, I wrote some tips for debugging unmanaged crashes in .NET that I figured out by debugging our .NET Imaging SDK. The idea is the same for iPhone -- namely:

[...] crash as early as possible. It's no fun to figure out a crash bug once the culprit function has already returned. You really want the root cause somewhere on the call stack when it's detected.

In Xcode, it's actually really easy to get information about how you might be managing memory incorrectly.

Tip 1: Set Deallocated objects to Zombies

Go to Project->Edit Active Executable, go to the Arguments tab and in the environment variables section, add

NSAutoreleaseFreedObjectCheckEnabled
NSZombieEnabled
NSDebugEnabled

And set each to YES. You can leave them there unchecked, but if you check them, then your application will now do some extra checking on autorelease and release and give you a good stack trace when you have done it wrong. A common problem is to think you need to call release when the object is already set to autorelease (see
yesterday's post on what the rules are for that).

Tip 2: Enable Guard Malloc


If you think you are having an issue where you go out of bounds of a heap allocated memory block, then in the Run menu, you can check "Enable Guard Malloc". This will tell you if you overrun your bounds. It's not going to be as handy as a Page Heap style check (where each heap allocation gets its own page and therefore crashes at the point of the mistake), but it's better than nothing.

After doing this, you get more capabilities in the debugger.
Read this article to see how to use them.

UPDATE: I wrote a much more detailed version of this that focuses on Understanding EXC_BAD_ACCESS.

Get iPhone programming tips in your inbox with my Beginner iPhone Programming Tips newsletter.

Managing memory in iPhone applications

I program all day in C# and C++ at my day job, so Objective-C is both natural to me (because of a mostly familiar syntax) and unnatural (because of it's many differences). In terms of memory management, Objective-C splits the difference between C# and C++. On the iPhone, Objective-C does not have a GC, but NSObject (the base class for all of your classes) supports reference counting. Of course, you could build the exact same mechanism in C++, but it's pervasive and included in ObjC and there's also some support in the app runtime for an autorelease concept (release will get called for you on an object at some point when the runtime has control -- you are safe in the rest of your stack frame).

When I first started
Habits, I didn't really read through the entire memory management API (there were so many other APIs to read) because I have been using reference counting for a long time (old COM programmer) and the awesome leak detector included in XCode was a good enough guide to what I was doing wrong.

However, the rules are really simple, and now that I know them, I never run into memory management issues:

  1. Declare all of your object pointer @properties as retain unless you have a really good reason not to. Then the setter that is generated will automatically call retain when you assign. When you reassign, it knows to call release on the old value.
  2. In your dealloc, assign all of your @properties to nil. This has the effect of calling release on the current values if they are not already nil.
  3. alloc returns an object with a reference count of 1 -- so you have to balance with a release.
  4. If you alloc, then you should try to release in that same function. To retain the value, assign it to something that retains. Exceptions are if you are a factory function that is returning a value up to be retained by the caller.
  5. Obviously, each retain call needs a release.
  6. Built-in convenience functions return objects that are autoreleased. That means you shouldn't call release on them -- the framework will call release at some point (they are registered in an autorelease pool that that is serviced when you return back to the framework). If you created the object without an alloc/init pair, you don't need to call release unless the docs say you do (but they probably don't)
  7. Check all of your work with the leak detector. Also, if you crash, you're probably doing it wrong -- I will have more to say on that soon.

I highly recommend that you read
Very Simple Rules for Memory Management in Cocoa on stepwise.com. Keep in mind that the suggestions for building proper setters is handled automatically if you declare your @properties correctly.

Get iPhone programming tips in your inbox with my Beginner iPhone Programming Tips newsletter.

iPhone Development Tips

Having now gone through getting Habits built, tested and on the App Store, I wanted to share these tips on getting started with iPhone development:

  1. Go enroll in the iPhone developer program before you start. Yeah, I know -- it's 99 bucks. But if you have an idea and a reasonable chance of doing it, just take the plunge. I joined after I finished, and that caused a lot of delays -- I could have been completing the other necessary steps in parallel.
  2. As soon as you're in, go get your application contracts going. If you want to make paid applications, you have to give Apple your tax and bank information. Again, it takes some time to get approved, so start early.
  3. If you don't know Objective-C -- don't worry, that's the easy part. The primer on the iPhone developer site should be good enough if you know C/C++.
  4. For Cocoa Touch, I recommend Erica Sadun's iPhone Developer's Cookbook. The chapter on coverflow is worth the price of the book, but everything else is there too (navigation, touch, location, contacts, etc)
  5. I also highly recommend iCodeBlog. Once you have some basic knowledge of the framework, check out the to-do application tutorial.

Update: just found this great flowchart of the right order to do things

Get iPhone programming tips in your inbox with my
Beginner iPhone Programming Tips newsletter.

Habits accepted to iPhone AppStore

Habits was accepted to the AppStore today.

Announcing Habits

I have been working on my first iPhone app for the last few weeks. It is a GTD companion application to help with recurring to do items with an indefinite schedule. It's called Habits, because I think it will help you form (good) habits. Soon to be available on the App Store.