markjnet

Memory Management Basics Tutorial Video

This article is a screen cast video of my tutorial for beginner iPhone programmers, it’s about the basics of memory management in Objective-C. Memory management is a tough nut for the beginner to crack, particularly in Objective-C and Cocoa for iPhone. Check out my iPhone memory management reading list for more voices on memory management.

The tutorial covers: Objective-C object retain counts; using retain, release, and autorelease; explains the autorelease pool in detail and how it works with the event loop; rule of thumb for if an object is in the autorelase pool.



Part 1: retain counts



Part 2: auto-release pool and the event loop



Part 3: auto-release pool and the event loop with retain



Part 4: auto-release pool wrap up



Part 5: properties, dealloc, bugs, auto-release rule of thumb

Thanks for watching!

[Slashdot] [Digg] [del.icio.us] [StumbleUpon]

iPhone Memory Management Reading List

Memory Management in Objective-C for the iPhone gets a lot of beginners confused. It’s a topic that can be explained several different ways, so keep reading and experimenting till it clicks for you. Here’s a list of places to learn about it:

My video lessons: Basics of iPhone Memory Management.

Books

Online

[Slashdot] [Digg] [del.icio.us] [StumbleUpon]

6 Months of iPhone App Sales Stats, Cause and Effect.

My iPhone game Hit Tennis is a simple iPhone tennis game, but with really fun engaging gameplay I designed specifically for playing tennis with the touch screen. You swing your finger across the screen to hit the ball, controlling strength and direction, so you get the feeling of real rallies as you play. The game has been out for 6 months, durring which I’ve been working on the consulting side of my business, but I’m planning Hit Tennis 2 (as an upgrade) with much deeper gameplay. I’m sharing six months of sales figures from this app in order to demonstrate effect on sales of various events, some under my control and some not. Here’s that 6 months of sales:

rev6m.psd

Launch

I launched in November 08 in a real hurry. Consequently I had a bunch of bugs which manifested as a lousy umpire who annoyed my players, so I had to do several quick updates. The reason for rushing was that I’d been developing Hit Tennis during a lull while Apple spent 101 days approving my app Smart Caller, which made me fearful of long waits for approval and I wanted Hit Tennis to be on sale in time for Christmas. My launch strategy was a simple online press campaign by emailing review sites with a YouTube demo vid, and starting off as a free app to ensure lots downloads. I quickly got small news stories and reviews on some good gaming and iPhone sites, and the first 2 days saw about 70,000 free downloads. On day 3 I switched to my planned price of $1.99. Why not 99c? I’d put a lot of effort into the basic gameplay, and I think I was too proud to price the same as all the 99c toy apps.

Christmas and TV Ad

Christmas saw a huge sales spike 4x over normal and welcome extra revenue, and then through January sales came back down to pre Christmas levels. January through April I worked on other projects and did no promotion of Hit Tennis, but I got a little lucky. A competing Tennis app Touchsports Tennis was shown for a few seconds in Apple’s TV ad for the iPod touch in February. It got people looking for Tennis in the App Store, and as my basic SEO was OK of course they found my app and I got increased sales. I was not tracking app store rankings at the time, but this sales spike probably lifted my rank in the sports games category, leading to ongoing sales in March.

March Sales Decline

March saw no promotion or updates from me, and no external events. I took the sales data for March and plotted it with a linear trend line to describe the decline in easy to understand terms:

marchUnits.png

The trend line has a gradient of -0.5, meaning that on average, every two days sales went down by 1 unit. Just using that trend line to ‘predict’ sales (by calculating the area under the line) we get 1021 units, which for a $1.99 app predicts $1,422 in revenue (after Apple’s 30%, and not accounting for currency differences). In fact my March financial report gave my earnings as $1,364. The point here though is that if sales keep declining by 1 unit every 2 days, then by now (May) Hit Tennis wouldn’t be selling much at all.

Tracking App Store Rank

I’d occasionally take a peak at Hit Tennis’ rank in the app store by using the Mobclix’s website, but in April I started using MajicRank to check my stats. (Check out my posting about these and other sales stats tools). To begin with I’d misunderstood what MajicRank does, and I wasn’t sure it was reporting my rankings correctly because the numbers didn’t match Mobclix’s. However I finally figured out that Mobclix and MajicRank report on different ranking lists, they are both right, but MajicRank’s number are more important than Mobclix’s now that the App Store ranks paid and free apps in separate lists. (All the different ranking lists are explained in my posting Understanding App Store Top 100s.) MajicRank showed that Hit Tennis was present in the sports games top 100 paid list in most countries, and in a few countries it was in the top 10. (I’m very happy to be ranked well in Croatia, but it only takes a couple of sales a week!) Finding out that Hit Tennis was not completely buried inspired me to see what I could do to increase sales, short of the big update I have planned for later.

Cut Price to 99c

On April 21st I cut the price from $1.99 to 99c. I did not publicize the price change as I wanted to see the elasticity of demand among app shoppers who happened across Hit Tennis by whatever means customers had been finding the app for the previous weeks. As you can see below in the graph of unit sales for March, sales climbed steadily for a few days. The increase in volume did offset the lower price, and as you can see in the revenue graph, revenue (at that time) held and then grew also. Due to the increase in volume my rankings went up somewhat. (I’m dumb for not recording them. MajicRank now records them for me :-)

unitsMarchWorld2.png

revMarchWorld2.png

Version Update and Release Date Trick

Mean time I’d been working on an update. Hit Tennis was my first time programming 3D graphics, so I did everything with simple billboarding 2D textures and alpha masks to create shapes. Pseudo 3D if you will. It worked for the simple game that Hit Tennis is, but several reviews in the app store had said ‘it should be more 3D’, and in fact due to the tennis racket’s 2D existence, it would disappear when you saw it side on. Saving gameplay enhancements for later, for this update I replaced the 2D tennis rackets with real 3D objects. A fun journey which had me learn to buy stock 3D models, edit them with Cheetah 3D (which I highly recommend), and load them into the game using Jeff LaMarche’s Obj File loader.

The update came out on the 28th. Apple had just stopped sending out ‘your app is approved’ emails, but I’d noticed that app approvals have been reliably taking 7-8 days so I knew when to expect it. On the 28th I changed the availability date in iTunes Connect to 28th April. This is the ‘release date trick’. It requires careful timing and a bit of luck to make it work, but when it works it gives a sales boost. As I explained in Understanding App Store Top 100s an app’s release date is important in one place: the default view of a category in iTunes on the desktop. With the release date trick I got Hit Tennis near the top of that page, and it stayed there for a several days. This update almost doubled sales. There were two other effects with the update that may have been factors in the increased sales. The new version triggered several thousand updates per day (see below), proving that I still have a lot of people that play the game. Maybe Apple uses updates in the ranking algorithm and it helped raise my ranking? Secondly, stars are now reported in the app store by version, so the new version gave me a chance to shake off my two and a half stars and start over (I’m now much happier with three stars :-).

upgMarchWorld.psd

Translating App Store Copy to French and Top 100 Paid Games

I’d not localized any of my apps, but Hit Tennis was relatively popular in France and I wanted to see the effect on sales of translating the app store description into French (and I knew a French person who would translate it for me). It could only increase sales right? Right. MajicRank reported the next day that sales had gone up enough to get Hit Tennis ranked not just in the top 100 sports games in France, but Hit Tennis was now placed in the top 100 paid games in France. Pretty lucky! You can see below that this brought a huge boost, and in fact for a couple of days I made more from sales in France than I did in the USA. Revenue in France for the period shown was 7x revenue in France for the previous month.

revMarchFrance.psd

Sales Back in Decline

It’s been a few weeks now since my Hit Tennis update, and sales are back down to ‘normal’. I hope sharing these 6 months of data along with looking at cause and effect on sales is helpful for other app sellers.

…and just in case you were wondering, here is the geographic breakdown for the 6 months of revenue:

200905190226.jpg

[Slashdot] [Digg] [del.icio.us] [StumbleUpon]

Fixing Blurry Subviews

The app I’m currently working on uses a small panel with extra info in a small font drawn over the top of an image. It’s implemented of course as a UIView nested as the subview in another UIView. My code loads the info panel view from a separate xib file and positions it in the main view with some code like this:

	NSArray *nibContent = [[NSBundle mainBundle] loadNibNamed:@"Box"
                                                     owner:self options:NULL];
	UIView* overlayBox1 = [nibContent objectAtIndex:0];
	[worksheet addSubview:overlayBox1];
	overlayBox1.center = worksheet.center;
	overlayBox1.frame = CGRectOffset(overlayBox1.frame, 0, -140);

It didn’t quite work though, because the detail view came out really blurry. It didn’t look blurry in Interface Builder, but both on the simulator and the iPhone it looked terrible, see below. I spent hours changing font properties and colors, thinking it was some weird text anti-aliasing gone wrong, but it always came out blurry. Can you guess the problem? It’s one of those things that will probably stump you until you’ve run across it yourself…

blurryview1

The problem is Core Graphics awesome power and screen co-ordinates that are floats, not integers. Core Graphics lets you compose your views from graphics not to 100% scale, it will scale everything for you, and it can even position views with sub-pixel accuracy, rendering ‘between’ each pixel with an anti-alias like effect. This is possible because view coordinates are specified with CGRect, which uses CGPoint, where x and y are floats, not ints.

The problem occurs when you have views that are supposed to be drawn normally, ie at 100% scale and at exact pixels. In the code snippet above the subview overlayBox1 is being positioned using its center. Center is a convenience method implemented as a property, it is really setting the frame origin. As the box is sized with an even number of pixels, 174 x 82, setting the origin relative to the center results in an origin at half pixels: 73.5, 69.5. Core Graphics goes ahead and renders at the half pixel position, but as the view is drawn at 100% it means every pixel in the view lies at half pixels on the screen, so each pixel is smeared between 4 neighboring pixels resulting in a big blur.

This is easily fixed, by positioning the view to whole pixels:

	overlayBox2.center = worksheet.center;
	CGRect overlay2Frame = overlayBox2.frame;
	overlay2Frame.origin.x = round(overlay2Frame.origin.x);
	overlay2Frame.origin.y = round(overlay2Frame.origin.y);
	overlayBox2.frame = overlay2Frame;

If you want to play around with this you can download the full example: blurryview.zip

#import "BlurryViewViewController.h"
 
@implementation BlurryViewViewController
 
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }
    return self;
}
 
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
	[super viewDidLoad];
 
	NSArray *nibContent = [[NSBundle mainBundle] loadNibNamed:@"Box" owner:self options:NULL];
	UIView* overlayBox1 = [nibContent objectAtIndex:0];
	[worksheet addSubview:overlayBox1];
	overlayBox1.center = worksheet.center; //WARNING! blur ahead.
	overlayBox1.frame = CGRectOffset(overlayBox1.frame, 0, -140);
 
	nibContent = [[NSBundle mainBundle] loadNibNamed:@"Box" owner:self options:NULL];
	UIView* overlayBox2 = [nibContent objectAtIndex:0];
	[worksheet addSubview:overlayBox2];
	overlayBox2.center = worksheet.center;
	CGRect overlay2Frame = overlayBox2.frame;
	overlay2Frame.origin.x = round(overlay2Frame.origin.x);
	overlay2Frame.origin.y = round(overlay2Frame.origin.y);
	overlayBox2.frame = overlay2Frame;
 
	NSLog(@"Worksheet1 origin: %f,%f",overlayBox1.frame.origin.x,overlayBox1.frame.origin.y);
}
 
- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
 
	// Release any cached data, images, etc that aren't in use.
}
 
- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
}
 
- (void)dealloc {
    [super dealloc];
}
 
@end

[Slashdot] [Digg] [del.icio.us] [StumbleUpon]

Understanding App Store Top 100s

Understanding the unique ways the app store works is critical in deciding app store marketing tactics and understanding the spikes and drops in app sales figures. This article explores how the top 100 lists in the app store work, and a future posting will look at how this applies to real sales data.

Top 100 lists.

Apple tracks the popularity of apps and ranks them in lists of top 100 apps. These are the ‘Top Paid’ and ‘Top Free’ lists you see when you browse the app store. The exact method is known only to Apple, but it seems that Apple measures app popularity by unit downloads over the last day, perhaps using a weighted method where downloads from previous days have a decaying influence on ranking. There are many ways that customers can find apps, eg searching iTunes, Google search, app review websites, word or mouth, ads in other apps, etc, but it’s clear that browsing the top 100 lists in the app store is very important app discovery method. Several developers have reported greatly increased sales when an app is in a top 100 list, and greatly reduced sales when their app slips off the bottom of a top 100 list. The two most important top 100 lists are top 100 paid apps and top 100 free apps, and then there are top 100 free and top 100 paid lists for each category and subcategory of games. In addition to the top 100 lists there are listings of apps by release date. Every one of these lists is maintained independently for every iTunes country, so an app that’s very popular in one country and in several top 100 lists for that country might be totally missing from the top 100 lists in other countries.

Browsing the App Store on the iPhone or iPod touch

The app store app on the iPhone or iPod touch opens to the last application tab that you were using: Featured, Categories, Top 25, Search, or Updates. On the top 25 tab you can see either the free or paid top 25 apps, selecting free or paid with the toolbar at the top. When if first opens it will default to whichever of free or paid you were looking at last. 5 apps fit on the screen at once, so in fact to begin with you see top 5. Scrolling down through 5 screens worth gets you the whole top 25. At the bottom of the table is a link to ‘Show top 50′, taping this gets 25 more apps added to the table, so you can scroll through the top 50 free or paid. At the end of 50 there’s no link to see more, so on the device you can’t see the entire top 100 overall apps, only the top 50.

Screenshot_a.png Screenshot_b.png

Via the Categories tab you can browse the top 100 paid and free lists for each category. Tapping on a particular category opens that categories top paid list as a table. The table has 25 apps listed, and at the bottom is a link ‘Twenty Five More…’. You can use that 3 times to get the table to show the full top 100 list. The toolbar at the top of the table switches between the top paid, top free, and listing apps by release date. Note that the table always opens showing the top paid list when you go into a category, it doesn’t remember if you were last viewing top paid, top free, or by release date. Note that this is different to iTunes on the desktop, which defaults its category view to release date. When viewing by release date, you can keep tapping the ‘Twenty Five More…’ link and get up to 350 apps listed.

Browsing in iTunes on the Desktop

In the App Store page in iTunes, the middle of the screen is full of special areas ‘New and Noteworthy’, ‘What’s Hot’ etc that the iTunes editorial team uses to promote apps it has hand picked. The overall top 10 paid apps is shown in the right column, and underneath that the overall top 10 free apps. (Note how paid gets billing over free, though headline billing is in the hand picked areas in the middle, which can include paid and free). Clicking on one of the top 100 links goes to a page that shows all top on screen.

On the left side of the main app store screen is the list of categories. Clicking on a category goes to thats categories app listing (screen shot below). When this page opens it lists the apps by release date. So here’s why the app release date is important – release date is the default view of an app store category in iTunes on the desktop. It’s possible to manipulate the release date during an app update to get an old app back onto this page. The first 20 apps are show, and you can page through all of them 20 at a time. The app listing can be changed to sort by most popular or by name. Sorting by most popular shows a popularity ranked list for free and paid apps combined. It’s interesting to see which paid apps show up in this list competing with the free apps in that category.

screen2.png

On the left and right side, the top 20 paid and top 20 free apps for this category are shown, and there are links to go to the full top 100 list for each. The top 100 lists show 100 apps, and there is no paging to get to apps 101-200.

screen3.png

Tools to examine Rankings

As a seller of apps, its important to keep an eye on the rankings of your app, your competitors apps, and different apps in order to understand your market. Using iTunes to find apps rankings is laborious, especially because the rankings are different for each country. There are a couple of wonderful tools I use to help. MajicRank will connect to the iTunes servers for you and find the current rankings of any apps you’ve configured in it, and it will do that for every country or just the ‘big 8′ countries. What it doesn’t do is remember your rankings and chart them over time, though the developer is working on this. MajicRank uses the individual category top 100 ranking lists for each country.

Mobclix tracks all apps rankings over time, and over on their website you can get ranking history charts for free. What Mobclix is charting is the free and paid combined popularity that you can see in a category in iTunes USA. So if you use Mobclix and MajicRank together, the rankings won’t match because they show ranking in different lists.

[Slashdot] [Digg] [del.icio.us] [StumbleUpon]

« Previous PageNext Page »

  • Categories

  • markjnet