Oct 23

In the last week a lot has been written about Apple’s change to allow In App Purchase in free apps. Here are some of the more informative articles I’ve found:

Thoughts on In-App-Purchasing For Free Apps
A thorough post by Jeff Scott at 148Apps describing the good news and the bad news for both developers and consumers.

In-App purchases could fundamentally change Apple’s App Store
Seth Weintraub at ComputerWorld postulates that everything will change. The (unanswered) question is how?

In-App Purchase now available for free apps
Marco Arment was one of the first iPhone developers to comment on the change.

Apple relents: in-app purchase for free apps allows demo-to-paid
Another good developer summary by Erica Sadun at TUAW.

Free In-App Purchases Will Change…. Little?
A somewhat pessimistic look at In App Purchase by Arnold Kim.

In App Purchase and the state of iPhone piracy
Much has been written about Apple’s statement that “Using In App Purchase in your app can also help combat some of the problems of software piracy by allowing you to verify In App Purchases”. Most of it has been ill-informed speculations by non-developers. In this post Dominique Bongard goes into great depth about the challenges of using In App Purchase to combat piracy. It’s not from a developers perspective, but from someone who has been involved in anti-piracy monitoring.

Do In App Purchases count towards the Top Grossing list?
This is one of the questions I asked in my original article. The answer seems to be yes. Freeverse analyzed the rankings of three of their games on the Top Paid list vs. the Top Grossing list. And Distmo discovered that several free apps have made it onto the Top Grossing list.

iTunes Connect Updated
On October 22 Apple made an update to iTunes Connect. After this update I was finally able to add In App Purchase to free apps, and it was also possible to change the price of an existing app with In App Purchase to free.

iPhone Developer Program License Agreement Updated
When you login to iPhone Dev Center you will be prompted to accept a new iPhone Developer Program License Agreement. I have not compared the entire document against the previous version, but one thing that I noticed had changed was specifically to allow for In App Purchase in free apps.

written by Nick \\ tags:

Oct 19

I just received my session survey feedback from 360|iDev Denver 2009:

  • Agree that the Session was Informative? 100%
  • Agree that the Speaker was Authoritative? 100%
  • Agree that the Session was What you Expected? 100%
  • Overall rating (1-5, 5 being best) Avg : 5

Wow! I could literally not have asked for anything more. Thank you to all of you who attended my talk. If you have not checked out the presentation, it’s available here: UIWebView – The Most Versatile Class in UIKit.

While on the topic of feedback, feel free to suggest topics you would like to see covered here on the iPhone Development Blog in the future. Is there anything you would like to see more of? Less? Comments are open.

written by Nick

Oct 16

Back in the old days while the NDA was still in effect, us old-time developers had to walk miles through snow without shoes to find any information about iPhone development and the iPhone SDK. These days, there’s too much information available and it’s hard to know where to start.

It’s great if you have a veteran iPhone developer at your side to guide you through the jungle. To make sure that you understand the Cocoa Touch principles, get a good application architecture in place from the start, etc, etc.

Luckily you can have one of the best teachers in the business by your side for two days to get you started the right way. Dan Grigsby of Mobile Orchard fame is teaching his Two Day Beginning iPhone Programming Training Class in Portland, Nov 12-13 and in Los Angeles, Nov 19-20. You don’t need any iPhone or Mac programming experience before the class, but you should have some prior development experience, e.g. being a web developer.

More information here. If you enter the coupon code “nick”, you’ll get a nice discount if you sign up during early registration. (And no, I’m not getting any kickbacks on this.)

If you’re already past the beginner level, then you should definitely subscribe to the Mobile Orchard Podcast. It has great interviews with iPhone developers and gets into wonderfully gory details about iPhone programming and other development issues.

written by Nick

Oct 15

I just wrote a blog post on our corporate blog about Apple’s announcement that In App Purchase is now allowed for free apps. This is a huge change and you should know how it impacts you as a developer.

written by Nick \\ tags:

Oct 08

A quick Internet search to find out how to get the disk space on a device showed a number of blog posts that proposed solutions similar to this:

#include <sys/param.h>
#include <sys/mount.h>

+(float)getTotalDiskSpaceInBytes {
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);	
	struct statfs tStats;
	statfs([[paths lastObject] cString], &tStats);
	float totalSpace = (float)(tStats.f_blocks * tStats.f_bsize);
	
    return totalSpace;
}

This approach relies on the handy Unix statfs() function that provides the required file system information. I coded it up and it worked on my 3.x devices. Fine I thought, I’m off and running. Then when testing on a 2.x device, it crashed. The problem looks to be differences in the compiler settings between the two OS versions. Rather than figure that out (I leave that as an exercise to the reader 🙂 ), I continued my search and came across what I consider the “correct” solution since it uses the iPhone SDK itself, as given below.

+(float)getTotalDiskSpaceInBytes {
	float totalSpace = 0.0f;
	NSError *error = nil;
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);	
	NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];
	
	if (dictionary) {
		NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];
		totalSpace = [fileSystemSizeInBytes floatValue];
	} else {
		DLog(@"Error Obtaining File System Info: Domain = %@, Code = %@", [error domain], [error code]);
	}
	
    return totalSpace;
}

As stated in the documentation, these interfaces wrapper the statfs() function, so they ultimately do the same thing, but they have been a part of the SDK since version 2.0! Testing verified my assumption and this approach works for me on my 2.x and 3.x devices and the numbers match what iTunes shows as well.

written by Jess \\ tags: , ,

Oct 02

This week I had the pleasure of both attending and speaking at the 360|iDev iPhone Developers Conference in Denver. Tom and John did an awesome job organizing this conference and they managed to gather an amazing group of speakers and attendees.

My own humble talk was titled UIWebView – The Most Versatile Class in UIKit. A topic that should be familiar to longtime readers of this blog. For the presentation I also took the time to create complete working code examples. Another favorite request around here…

Here are the links to download the presentation and the sample code.

written by Nick \\ tags:

Sep 18

Today Apple launched the new App Store Resource Center. Calling it “new” is actually a bit of a stretch, since it seems to be mostly a collection of information that was previously scattered in several places. But we should still give Apple credit for the effort. The are moving in the right direction.

I still think my own App Store Rejection Reasons page is a good complement to Apple’s official documents. And I just updated the page with a few new items that I painfully encountered.

written by Nick \\ tags:

Sep 10

In this post How To Create Conditional Log Statements in Xcode I described how you could add a DEBUG flag to your Xcode project setting so that you could use statements like #ifdef DEBUG in your code.

If you follow the instructions in the post for a 3.0 project you will get an error:

There’s already another key named “GCC_PREPROCESSOR_DEFINITIONS”. Please enter a different name.

If you scroll through all the build settings you will not find one labeled GCC_PREPROCESSOR_DEFINITIONS. This is because this setting has helpfully been relabeled “Preprocessor Macros” and is now listed under the heading GCC 4.2 – Preprocessing:

PreprocessorMacros

To find out how any of these new “helpful” labels are actually translated to compiler settings, click on the Research Assistant button at bottom left corner of the window (the button that looks like a pair of reading classes on top of a stack of books) and you’ll see this:

Xcode Research Assitant

Note that I’ve only seen this change for projects that I’ve created in Xcode 3.1.3 (which by default only have a SDK 3.0 target). Projects that were created in older versions of Xcode (even if they can target SDK 3.0) still show the GCC_PREPROCESSOR_DEFINITIONS label under the heading User-Defined.

written by Nick \\ tags: ,

Sep 05

After a brief outage due to upgrading to the latest version of WordPress, we’re back.

If you are running a WordPress blog, now would be a good time to upgrade to version 2.8.4. There is a nasty worm that’s going around attacking all older versions of WordPress. Ominous security advisories abound.

written by Nick

Sep 02

To change the height of the cells in a UITableView, use the property rowHeight. Or change the value in Interface Builder.

There is a method called heightForRowAtIndexPath in UITableViewDelegate, where you can also set the height. However this is NOT recommended. Apple’s release notes states the following about this method:

It is very, very expensive to customize row heights (via tableView:heightForRowAtIndexPath:).

It makes sense that having rows with different heights in your table will wreak havoc with the table view’s reuse of cells. But it also turns out that if you return the same value from this method for each row, you also suffer a significant performance penalty.

So just use the simple rowHeight property. It’s less code to type, and it’s significantly faster.

Thanks to Brent for the performance testing.

Addendum: If you really, really must have different row heights in your table. Then heightForRowAtIndexPath is the only way to achieve this. If your table only has a handful of rows then performance will not be a big issue. But if you have hundreds of rows, all with varying heights, then I would suggest looking at constructing the table using HTML in a web view instead.

written by Nick \\ tags: , ,