Skip to content

Archive

Tag: iPhone

Don’t retain anything unless you must

Regarding reference counting, this is the idea I’d like a developer to at least consider. For several reasons.

  • A dangling pointer / weak reference needn’t be evil. During development hitting a dangling pointer is better than preventing an object to deallocate when it should. An object that exceeds it’s intended lifetime can behave in undesirable, unpredictable ways. All it takes to detect an invalid object is turning NSZombieEnabled on.
  • Everything retained needs to be released. Retain less = less work.
  • If the sums don’t add up (over-released/over-retained object) it’s easier to work out what’s wrong when the number of objects involved is small (e.g. 1, 2 or 3)
  • Potentially any object that retains a target will increase the target’s lifetime; this a priori translates into increased memory usage.
  • Whenever retaining an object we risk creating a cyclic reference. Of course ‘we know what we’re doing’ (and cyclic dependencies can be removed) but isn’t it just easier to avoid getting too many of these.

Unwanted objects that remain inside the runtime after they should have deallocated will harm you. The more your system is dynamic (e.g. game, simulation) the more these objects are likely to generate functional bugs that are hard to figure.

I read a little about automated reference counting (ARC) which we are getting in iOS5. If I understand correctly (reading here) the central idea of this article will translate to ‘don’t abuse strong references’. Now that I more or less get it I look forward to using ARC but I guess I’ll be waiting for another 6 months or so, being a happy laggard.

A quick introduction

Reference counting approaches memory management indirectly, using concurrent ownership:

  • Take ownership of an object by retaining it
  • Relinquish ownership by releasing the object.
  • When all owners of an object have released it, the object is deallocated.

indirect : we don’t explicitly deallocate the object.
concurrent: several objects can simultaneously retain the same target.

The basic rules are covered in many places, like here and here and from the horse’s mouth, here.

Reference counting is efficient, error prone and occasionally awkward.

More efficient than garbage collection: objects get deallocated as soon as their reference count reaches zero, whereas GC is heuristic and may cause your program to slow down unexpectedly while it’s doing its thing.

Error prone – programmers need to pair release/retain statements (either directly or indirectly). Mismatched statements cause a program to leak or crash. Additionally reference counting is hackable; it is easy to traffic the sums (either accidentally or by design) and obtain a valid program that handles memory correctly, while violating reference counting rules.

Awkward, notably when we know beforehand that we would like to deallocate a well defined subset of the runtime graph. A typical example is when you start a kind of ’session’, allocate any number of objects in the course of the session and wish to deallocate all the objects at the end of the session. In such cases opting out may be somewhat short sighted yet remains attractive.

A design idea

There is a principle which I find rather productive: instead of thinking about whether an object should retain X or not, consider X then try to think about an object ‘up the runtime graph’ that should own X. Often there is an object Y such that, if Y deallocates, X should also deallocate. It could be the parent of X or maybe another object up the chain.

Now, if there is only one such object Y, then you don’t need to retain X anywhere else. You can even assert the retain count to ensure that X is unambiguously managed by Y.

Anti-patterns?

There are little recipes around (e.g. here and here) that you can use to ‘ease the pain of memory management’.  From the point of ownership these recipes work the same way GC does: easy way out of memory management issues, hard into functional bugs with all the enticing prospects of a muddle-through approach.

One point these approaches have in common is ‘if in doubt, retain’. I’m OK with that as long as I know (beyond reasonable doubt) that keeping the target alive won’t generate unwanted behavior. If the target is an observer that receives and processes notifications… …then if in doubt, don’t retain. A clean, happy crash will provide the decision point where you can say:

  • ‘Yea, this object should still be alive at this point’ (in which case maybe something else should have retained it) or…
  • ‘No, this object is dead and well dead, we should have sent a death note’

Additionally these approaches look incomplete. You need to use class extensions if you want to declare everything as a property without exposing all your ivars.

Weak references

An unretained field is a ‘weak reference’. At least in a first approach, the use of weak references is encouraged in a number of situations:

  • Backward references from a child to a parent
  • Listener sets. See a straightforward application here.
  • Same type objects cross-referencing each other.
  • Any situation where you feel unsure whether to claim ownership (retain) or not.

Implementation details

Maybe for historical reasons there are two approaches to enforcing reference counting in objective C:

  • The non intrusive approach revolves around tagging using properties and indirect access using self.x = . Although this approach looks theoretically better and safer there are practical details of how it is done in Objective C which I often find off-putting. For one I like to not declare properties until I want to expose public state, and I’m not used to class extensions, thus find myself unwilling to add class extensions to my .m files.
  • An older approach revolves around the [release] and [retain] statements. The advantage (easier reviewing/debugging) and inconvenience (intrusive approach leading to somewhat cluttered code) are the explicit way in which things are done. This leads to a weird situation because it makes it more likely that bugs are introduced while making the same bugs easier to fix.

Note about [autorelease]

[autorelease] is very convenient and helps avoid errors in many situations. Sadly enough when an error does occur and [autorelease] is the lucky guy that causes a target to deallocate, we get very little debugging information because [autorelease] doesn’t take effect until we exit the frame.

So I try to limit its usage to where it’s unavoidable.

What is covered elsewhere (or should be)

  • Cocoa collections (NSArray, NSSet, NSDictionary) retain all their elements. This can be a hindrance in some cases, but you can configure the underlying, toll-free bridged counterparts, as demonstrated here.
  • There are various approaches to notifying stakeholders when an object gets deallocated. I will try to write a quick article about an approach I find useful when implementing observer schemes.

I started getting my next app ready to release. I’m looking into small things – icons, launch images and the like. This article is mainly about compliance. It is meant as a quick reference if anything and may be little help if you have never released an app before. You can check references at the bottom of this article if you’re looking for comprehensive information.

Finally, keep in mind that this kind of information easily gets out of date. Even if you find this article useful please check every information using reliable sources.

Launch images

XCode 4.2 (for iOS5) will rename images using the following convention:

Default.png, Default@2x, Default-Portrait~iPad, Default-Landscape~iPad

Default-Landscape~iPad won’t work on my iPad running iOS 4.3.

Using these names instead: Default-Portrait, Default-Landscape (without the ~iPad extension) works and the images still appear in XCode.
However using this method, so far I only got Default-Landscape to be recognized (may need to refresh build completely)

Another way to fix the issue is to add keys in the info.plist:

UILaunchImageFile, UILaunchImageFile~ipad

There is a Q&A about that.

App icons summary

iPhone: 57×57 (Icon.png)
iPhone (retina): 114×114 (Icon@2x.png)
iPad: 72×72 (Icon-ipad.png)
iPad (spot): 50×50 (Icon-spot-ipad.png)

Icon-settings.png 29×29

iTunesArtwork.png: 512×512

Note 1: I am not sure whether names are needed depending on the plist configuration; however keeping names is also good to maintain backwards compatibility.

Note 2: In XCode 4.2, if you add icons to the summary view, XCode will duplicate and rename the icon file, even if the icon file is already added to the project and already uses the correct name. If the icon is correctly named and you don’t to keep the duplicates (for example because your project folder is organized in a different way), I think it’s okay to delete the duplicates (icons still appear in the summary view). Additionally XCode adds entries to the info.plist automatically. Apparently older entries may not be overridden so doing a little house keeping may be necessary.

Caveat: in iOS5, it seems that there is a new info.plist entry for icons and this may require adjusting the ‘gloss effect’; check
CFBundleIcons > CFBundlePrimaryIcon>UIPrerenderedIcon, which apparently overrides it’s namesake in the plist root.

Universal apps

In XCode 4.2 some work will be done automatically when you switch to universal app, e.g. copying MainWindow.xib. The UI will look so-so and require corrections. In some situations the same xib file can be used for both (if the UI is simple) – obviously designing a dedicated UI is the best.

Other than MainWindow-iPad.xib (wired from the info.plist), it is the developer’s responsibility to point at the correct xib files.

References

For launch images and icons, check this comprehensive article on the OOPS tech blog

Also check: iPhone Dev 101 – size of UI elements

This is a rough introduction to the Bullet physics engine.

I keep this article for reference. If you want a clean setup for building bullet as an iOS ready static library, please check this post.

You’re crying out for a physics engine. You wanna make one of these gimmicky, fashionable and ever profitable physics puzzlers, right?

If it’s a 2D engine you’re after, try Box 2D (<= links to a pocket gamer article!), it’s free, worth millions to some.

I sweated over my laptop 4 hours putting this together. It’s not so very difficult, but it’s summer and it’s HOT.

The bigger they come… (1.30 pm)

I decided to have a shot at building Bullet for a start.

Downloading the source isn’t a problem; the archive itself is… …varied. Lots of stuff at the root level, and a promising ’src’ folder.

I approached the “build issue” (with a pig) head on. I made a new project in XCode, added all files from the src folder, and started building.

Don’t do this (use => this article instead.)

I removed many things that stood in the way:

  • “imbsdk”/ folders
  • make files

Then the build started bumping on #include “foo/bar/file.h” style commands. Makes sense, because adding all the files the way I did puts all files ‘at the same level’, so there’s no need for a ‘foo/bar/’ unless you expect a collision. I didn’t expect a file-space collision, and I was right. Yea, I moronically search-killed all foo/bar/ sections from all files.

There’s another couple of libs I didn’t like. The multi-threaded library trashed the build and doesn’t seem that promising just yet. There’s also the mini-cl thing. I dunno what that is except it uses the multithreaded lib headers, so I unchecked a couple more files from that mini-cl thingy.

Yay. I built bullet, I haven’t read the docs or anything yet. I don’t even know if the build is any use to nothing since I trashed stuff on my way. But hey, it’s building, right?

Surgery time: ~35 minutes

Examples, any? (2.45 pm)

I searched for sample code in the archive. Maybe what I was looking for was a quick ‘falling ball world’ with stdout logs to explain what’s going on. I know it’s unpretty but it does away with the need to show things and I didn’t expect GL-ES ready code in the demos either.

Then I found:

  • The Bullet user manual [link now fixed]
  • Their hello world tutorial.
    (please have a look, the remainder of this article is about getting this example to compile and run in an Objective C environment).
  • This (although ‘it’ may be out of date).

They do have an article showing how to include Bullet in an MacOS-X project. It looks like it would take no more than 10 minutes. I skip-read that it causes a framework to be generated. I may be wrong, but I don’t think we can include any framework other than what ships directly with iOS devices. We need static libraries, right?

Clock ticking (3.45)

I did nothing impressive in the past hour. I pasted the example from that hello world tutorial (link, above) in a char testBullet() function. I put that in a *.cpp file, not just wishfully but because the includes won’t compile as C (well, it is C++ code – and by the way that didn’t work, see below… ).

Surely I made a sample project to contain this stuff. Any project template will do, just for a test. So I created a project, pasted the code in test_bullet.cpp which contained this char testIt() method (don’t google these names, follow the link to the tutorial instead).

Calling this cpp code from an objective C class caused a linkage error, leading to a shocking discovery.

Interlude

I like the hello balls or watchamacallit example A LOT. Because it has this line in it:

std::cout << “sphere height: “ << trans.getOrigin().getY() << std::endl;

For whatever obscure reason this great classic glitched my build. So I substituted a greater classic:

printf(“sphere height: %f\n”,trans.getOrigin().getY());

Overall the test didn’t go too well, expect it worked (ha!).

I muddled endlessly over the “btBulletDynamicsCommon.h” include. This includes this, this and that, and cutting and pasting the include folders into Build Settings > User Header Search Paths takes AGES (If you now a better way, absolutely please leave a comment after this post)

The shocking discovery

I started considering mournfully how I don’t really know how to bridge C++ and Objective C. Then I found a doc claiming that…

you can dump whatever C++ you want in an Objective C file as long as you substitute .mm to .m

Not believing it one bit, I renamed my .cpp file to .mm; wrapped my test code as a class function, like this:

#include “TestBullet.h”

#include <stdio.h>

#include “btBulletDynamicsCommon.h”

@implementation TestBullet

+(BOOL)test{

// Welcome to C++land.

// Paste here sample code found at the bottom of that page.

// …

// … what are you waiting for?

}

@end

Supernaturally, this compiles without twisting a nail.

Understanding is nothing (4.42pm)

The world is unfair. I picked bullet first because of all the hype surrounding it (July 2011).  I’m sure there are many decent physics engines out there, but that is that.

Other than producing a nasty project file that can build the library, I know nothing about Bullet physics. Feels good, in a kind of way.

Looking at the fine print below – a mantra much simpler than the sample code – there’s a couple of things we can infer:

  • There is a ball. Likely, a solid thing. That’s a bit cheated from the console output but let’s believe it.
  • There is gravity. Gravity’s good.
  • There is a ground abstraction. Ground is good.
  • No input file or likewise cheat. Everything is setup programatically.

Their sample code is 65 lines long. Didn’t expect anything better (sigh). For better and for worse, the tutorial explains this step by step. Maybe I’ll understand if I set a few hours aside to read it.

Attaching to process 2589.

sphere height: 49.997223
sphere height: 49.991669
sphere height: 49.983334
sphere height: 49.972221
sphere height: 49.958332
sphere height: 49.941666
sphere height: 49.922222
sphere height: 49.900002
sphere height: 49.875000
sphere height: 49.847221
sphere height: 49.816666
sphere height: 49.783333
sphere height: 49.747223
sphere height: 49.708336
sphere height: 49.666668
sphere height: 49.622223
sphere height: 49.575001
sphere height: 49.525002
sphere height: 49.472225
sphere height: 49.416668
sphere height: 49.358334
sphere height: 49.297222
sphere height: 49.233334
sphere height: 49.166668
sphere height: 49.097225
sphere height: 49.025002
sphere height: 48.950001
sphere height: 48.872223
sphere height: 48.791668
sphere height: 48.708336
sphere height: 48.622223
sphere height: 48.533333
sphere height: 48.441666
sphere height: 48.347221
sphere height: 48.250000
sphere height: 48.150002
sphere height: 48.047222
sphere height: 47.941666
sphere height: 47.833332
sphere height: 47.722221
sphere height: 47.608334
sphere height: 47.491669
sphere height: 47.372223
sphere height: 47.250000
sphere height: 47.125000
sphere height: 46.997223
sphere height: 46.866669
sphere height: 46.733334
sphere height: 46.597221
sphere height: 46.458332
sphere height: 46.316666
sphere height: 46.172222
sphere height: 46.025002
sphere height: 45.875000
sphere height: 45.722221
sphere height: 45.566666
sphere height: 45.408333
sphere height: 45.247223
sphere height: 45.083336
sphere height: 44.916668
sphere height: 44.747223
sphere height: 44.575001
sphere height: 44.400002
sphere height: 44.222225
sphere height: 44.041668
sphere height: 43.858334
sphere height: 43.672222
sphere height: 43.483334
sphere height: 43.291668
sphere height: 43.097225
sphere height: 42.900002
sphere height: 42.700001
sphere height: 42.497223
sphere height: 42.291668
sphere height: 42.083336
sphere height: 41.872223
sphere height: 41.658333
sphere height: 41.441666
sphere height: 41.222221
sphere height: 41.000000
sphere height: 40.775002
sphere height: 40.547222
sphere height: 40.316666
sphere height: 40.083332
sphere height: 39.847221
sphere height: 39.608334
sphere height: 39.366665
sphere height: 39.122219
sphere height: 38.874996
sphere height: 38.624996
sphere height: 38.372219
sphere height: 38.116665
sphere height: 37.858330
sphere height: 37.597218
sphere height: 37.333328
sphere height: 37.066662
sphere height: 36.797218
sphere height: 36.524998
sphere height: 36.249996
sphere height: 35.972218
sphere height: 35.691662
sphere height: 35.408329
sphere height: 35.122219
sphere height: 34.833328
sphere height: 34.541660
sphere height: 34.247215
sphere height: 33.949993
sphere height: 33.649994
sphere height: 33.347218
sphere height: 33.041660
sphere height: 32.733326
sphere height: 32.422215
sphere height: 32.108326
sphere height: 31.791658
sphere height: 31.472214
sphere height: 31.149992
sphere height: 30.824991
sphere height: 30.497213
sphere height: 30.166658
sphere height: 29.833324
sphere height: 29.497213
sphere height: 29.158325
sphere height: 28.816658
sphere height: 28.472214
sphere height: 28.124992
sphere height: 27.774992
sphere height: 27.422215
sphere height: 27.066660
sphere height: 26.708326
sphere height: 26.347216
sphere height: 25.983326
sphere height: 25.616659
sphere height: 25.247215
sphere height: 24.874992
sphere height: 24.499992
sphere height: 24.122215
sphere height: 23.741659
sphere height: 23.358326
sphere height: 22.972216
sphere height: 22.583326
sphere height: 22.191660
sphere height: 21.797216
sphere height: 21.399994
sphere height: 20.999994
sphere height: 20.597218
sphere height: 20.191662
sphere height: 19.783329
sphere height: 19.372219
sphere height: 18.958330
sphere height: 18.541664
sphere height: 18.122219
sphere height: 17.699997
sphere height: 17.274998
sphere height: 16.847219
sphere height: 16.416664
sphere height: 15.983332
sphere height: 15.547221
sphere height: 15.108333
sphere height: 14.666666
sphere height: 14.222222
sphere height: 13.775001
sphere height: 13.325001
sphere height: 12.872224
sphere height: 12.416669
sphere height: 11.958336
sphere height: 11.497225
sphere height: 11.033337
sphere height: 10.566670
sphere height: 10.097226
sphere height: 9.625005
sphere height: 9.150005
sphere height: 8.672228
sphere height: 8.191673
sphere height: 7.708341
sphere height: 7.222230
sphere height: 6.733342
sphere height: 6.241676
sphere height: 5.747232
sphere height: 5.250010
sphere height: 4.750011
sphere height: 4.247234
sphere height: 3.741679
sphere height: 3.233346
sphere height: 2.722236
sphere height: 2.208348
sphere height: 1.691682
sphere height: 1.172238
sphere height: 0.650017
sphere height: 0.720013
sphere height: 0.787232
sphere height: 0.851673
sphere height: 0.913337
sphere height: 0.972222
sphere height: 1.028330
sphere height: 1.081660
sphere height: 1.132212
sphere height: 1.179986
sphere height: 1.224983
sphere height: 1.267202
sphere height: 1.306643
sphere height: 1.343306
sphere height: 1.377192
sphere height: 1.408299
sphere height: 1.436629
sphere height: 1.462181
sphere height: 1.484956
sphere height: 1.504952
sphere height: 1.522171
sphere height: 1.536612
sphere height: 1.548276
sphere height: 1.557161
sphere height: 1.563269
sphere height: 1.566599
sphere height: 1.567151
sphere height: 1.564925
sphere height: 1.559922
sphere height: 1.552141
sphere height: 1.541582
sphere height: 1.528245
sphere height: 1.512130
sphere height: 1.493238
sphere height: 1.471568
sphere height: 1.447120
sphere height: 1.419895
sphere height: 1.389891
sphere height: 1.357110
sphere height: 1.321551
sphere height: 1.283214
sphere height: 1.242100
sphere height: 1.198208
sphere height: 1.151538
sphere height: 1.102090
sphere height: 1.049864
sphere height: 0.994861
sphere height: 0.995889
sphere height: 0.996711
sphere height: 0.997369
sphere height: 0.997895
sphere height: 0.998316
sphere height: 0.998653
sphere height: 0.998922
sphere height: 0.999138
sphere height: 0.999310
sphere height: 0.999448
sphere height: 0.999559
sphere height: 0.999647
sphere height: 0.999717
sphere height: 0.999774
sphere height: 0.999819
sphere height: 0.999855
sphere height: 0.999884
sphere height: 0.999907
sphere height: 0.999926
sphere height: 0.999941
sphere height: 0.999953
sphere height: 0.999962
sphere height: 0.999970
sphere height: 0.999976
sphere height: 0.999981
sphere height: 0.999984
sphere height: 0.999988
sphere height: 0.999990
sphere height: 0.999992
sphere height: 0.999994
sphere height: 0.999995
sphere height: 0.999996
sphere height: 0.999997
sphere height: 0.999997
sphere height: 0.999998
sphere height: 0.999998
sphere height: 0.999999
sphere height: 0.999999
sphere height: 0.999999
sphere height: 0.999999
sphere height: 0.999999
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000
sphere height: 1.000000

This is a quick introduction to unit testing with XCode. This article does not provide a conceptual overview to unit testing.

As a first step. I did the following:

  1. Go to the project browser and select [ add > new file ]
  2. Select ‘objective c test case class’
  3. The file that opens immediately seems to contain a couple of tests. That, and a link to an overview document graciously provided by Apple.
  4. So I click, and read everything patiently (well, I’m planning to. I can display a lot of patience at times) (1).

One thing worth mentioning is that, up to stage 4 and notwithstanding footnote (1), this is a perfect introduction to unit testing, and a perfect approach to documentation. The IDE provides the way to get us started with what we want to do. The code hyperlinks the documentation.

Setting up a target for unit testing

Now to the point, what we want is write a test suite and, minimally (assuming we don’t have continuous integration, yet) wire it to the main project, so the test suite runs whenever we build.

  1. We need a target to run the test suite. Go to [ project > New Target > Unit Test Bundle ].
  2. Make a group to hold your test classes (Optional. We might as well dump everything, everywhere).
  3. At this point I deleted my first test class and re-created it. That’s because we need to add the test class to the test target (NOT to the main target, so uncheck that when going through the wizard) and the easy-clicky way is via the wizard, when we create a new test class.
  4. Switch the active target to Test (or whatever your test target is named)  and target the simulator (otherwise tests will skip).
  5. Press build.
  6. Press [Build]. If you haven’t modified the sample test class, this should run OK.
  7. Now modify the test class to fail a test, and press ‘Build’. This should then fail the build. If you check build errors and keep unfolding, you’ll eventually find a reference to your failed test, along with whatever you set the assert to output when the test fails.

OK, this didn’t work for me at first. In the sample test class, reassign USE_APPLICATION_UNIT_TEST to zero. USE_APPLICATION_UNIT_TEST doesn’t seem to be for unit tests; this is for tests that require your application (or some other GUI, not sure… ) to be running while you test.

NOTE: I have somehow gotten into the habit of stripping #import <Foundation/Foundation.h> off my .h files. Well. If you’re doing this, you’ll get errors when trying to compile your project classes to the test target. You need to add the project’s precompiled header (*.pch) to the build configuration for the test target (see below).

Running tests every time you build the main project

Now, this is trivial and elegant at once. To ensure we pass the tests before even thinking about running our app, all we need to do is drag the test target inside the main target.

Next time we build (targeting the simulator) test classes compile and run before actually running our app. If the tests fail, nothing runs until we fix the tests :)

Troubleshooting

There are three practical issues that tend to occur when trying to put legacy code under unit test with XCode. In whatever case this results in stupidly broken builds.

  1. Most of your existing source files are missing from the Test target.
    => expand the main target for your project; expand the test target; now select Compile Sources in your main target. select all files in the Compile Sources group (do it from the top right panel) and drag them into Compile Sources in the test target.
  2. Frameworks in use  are missing from the test target.
    => use the same approach as in (1). This time, duplicate content from Link Binary with Libraries.
  3. The precompiled header (.pch file) isn’t applied to the test target.
    1. Right click on the main target and choose ‘get info’.
    2. Select the build tab.
    3. Under Configuration: (top left) pick All Configurations
    4. Scroll down until you find the ‘Prefix header’ entry in the ‘GCC 2.2 – Language’ section. Copy the pch path/name and duplicate it to your Test target settings.

(1) At this stage, not everything being as perfect as it ought to be, I bothered popping a mail window and sending the link to myself. I wished I had an iPad icon on my desktop and could just drag the safari window to it – or the link. Yea. Kiss the future.

There are many ways to waste a decent Sunday. Today I’ve decided to figure how to make and use ad-hoc distributions.

Overview

If your testers are local enough, borrowing their devices overnight and loading your app on their phone yourself is a good option. If your testers aren’t local, you won’t be there to help them, and they won’t be using XCode. Instead, we create a special provisioning profile for your testers’ devices and email this along with a copy of our app built against that profile.

Creating an ad-hoc distro for testers is pretty much the same as creating a developer build. Here are the differences:

  • You need a distribution provisioning profile, NOT a developer provisioning profile.
  • Like devs, testers need to install the provisioning profile onto their device before the device can run. This step is not entirely intuitive (well… release builds don’t require this, right?), however many articles explaining how to make ad-hoc distros skip on this.
  • Like devs, testers need to install a build matching the provisioning profile the app was built with.
  • Unlike devs, testers use iTunes, not XCode. Steps to install provisioning profiles and apps from iTunes aren’t quite the same on OS-X and windows (see ‘installation’ below).

Creating a provisioning profile for testing.

I am assuming you have already completed the steps required to make a build work on your own device(s) and are moderately familiar with the provisioning portal.

  1. First off, you need your beta testers to provide their device IDs. A simple way to collect device IDs is to get your testers to download one of the many free iPhone apps that ease this process, such as UDID+. Simply put, the tester runs the app, then they press ’send email’ and their device ID appears in the body of the email they’re sending you.
  2. Log into the iphone dev connection website and navigate to the provisioning portal.
  3. Go the ‘Devices‘ tab and add your tester(s) devices.
  4. You need to create a provisioning profile for ad-hoc distribution. This profile will include the devices that the test build can run with.
    (a) select the ‘provisioning’ tab.
    (b) select the ‘Distribution’ sub-tab and select ‘new’ to make a new profile.
    (c) In ‘distribution method’ check ‘Ad hoc’. Choose a name (e.g “MyApp Beta”) and pick your app ID from the list.
    (d) check the box(es) to include your tester(s) device(s) and press submit.
  5. After a couple of minutes, refresh the page (profiles aren’t immediately made available for download). Then download the new provisioning profile and drop it in a folder named ‘beta’. Later you need to email the provisioning profile to your testers so they can add it to iTunes.
  6. Don’t forget to add the new provisioning profile to XCode as well.

Creating a test build

  1. In XCode, switch to a device build. Debug or Release is OK. If you choose debug, it makes it easier to interpret crash logs later.
  2. In the XCode project browser, right click on Targets > YourGameName and select ‘get info’.
  3. Go to the build tab and have a look at the ‘Code signing’ section. If you didn’t forget to add the new provisioning profile to xcode, you can select it in the drop down menu near ‘Code Signing Identity’ and ‘Any iPhone OS Device’. (I just set both fields to the testing profile, but I think the idea is that we can associate profiles on a per device type basis)
  4. Select Build & and Archive in the build menu.
  5. You can find archived apps (and profiles previously added to XCode) in the XCode organizer. To find your build, right click/shift-click the date associated with the archived version you want and select ‘reveal in finder’.

Sending your app to testers – installing an ad-hoc distribution.

Testers need the following:

  1. Copy of the provisioning profile (the *.mobileprovision file we have created)
  2. Your ‘archived app’. I enclose this in quotes because although this is an ‘archive’ on a windows machine it would really look just like a folder with the *.app extension,
  3. A computer (Mac or PC OK)
  4. iTunes should be installed on their computer.

Installation – PC

  1. Open iTunes
  2. Go to ‘add file to library’ and add the *.mobileprovision file. Alternatively, drag and drop this file into the iTunes window (in iTunes 10, seems to work better if we drag into LIBRARY section on the top left).
  3. Drag and drop the *.app folder into iTunes. We can’t use ‘add file to library’ because windows doesn’t recognize *.app folders as ‘files’.
  4. Sync the device (you may need to include the app into the list of apps added to this device first)

IMPORTANT – If the app is added first, the above may not work until iTunes is restarted.

Installation – OSX

  1. Open iTunes
  2. Drag and drop the *.mobileprovision file onto the iTunes icon (or use ‘add file to library’)
  3. Drag and drop the *.app file onto the iTunes icons (or use ‘add file to library’)
  4. Sync the device (you may need to include the app into the list of apps added to this device first)

IMPORTANT – If the app is added first, the above may not work until iTunes is restarted.

References

I’ve been poking around to get this information; then I tested everything step by step until I got it to work.
You could check the original document about ad-hoc distributions for testers (from the Apple site).

Hairlock - dev picUpdate: Antistar 3D: Rising is now available on the app store!

Why is a 13 year old dreaming of metal cities?
What lies in the dark forest beyond Klinnburg?

Anticipating the success of the Twin Star Saga,
Antistar 3D offers stylish anime action and adventure.

>> Watch the video
>> More screenshots

Join the buzz or check discussions on Touch-Arcade forums.

With an exciting title putting experienced and new players on fair ground, we’ve just proven that mobile entertainment owes nothing to game-boxes:

Hairlock - dev pic

  • Realtime, fullscreen interactive 3D
  • Unique mix of adventure and arcade
  • Unexpected allies and opponents
  • innovative ‘no grind’ gameplay
  • An original cast of haunting, magic creatures.

From the quaint emptiness of a marooned village to a mice gang’s lair, become a child without memories,
armed with only courage and a forward attitude to solving life’s little annoyances – not having a clue what’s going on, not having a chance against oversize wildlife and getting captured by really bad guys.

With procedural landscapes, three dimensional growth and beautifully detailed models,
Antistar 3D: Rising pushes the limits of 3D on mobile platforms and will seamlessly adapt to your device’s capabilities.

Main Contributors: T.E.A de Souza, Chan Zhang, Karen Xu; Music: Matt Hansen (Calpomatt), Justin R. Durban (Edgen), Mark. SFX: Mark E Buckland, Robert Gacek (FXProSound), Joel Carli, Sith Master, Starmanltd, The_lone1, T$_Technologies.

Antistar 3D: Rising will be distributed as a universal app taking advantage of all device’s capabilities:

  • Basic rendering optimized to run smoothly on iTouch
  • Antialiasing (iPhone 3GS)
  • Retina Display (x1.5 iTouch definition 3D view)
  • 1004×768 full-screen on iPad

Visit the product homepage for a quick description.

On a mobile platform, memory is to be considered seriously. Unlike a desktop PC where we have 2, 4 (8?) GB to live on, the general feeling about the earlier iPhone and iTouch is that we have around 20MB to play with. Tiny sandbox.

The bottom line

If you start with one of the iPhone OS templates/examples, you likely have a view controller with an empty method like this:

- (void)didReceiveMemoryWarning {}

The bottom line is that it seems safer to arrange that your app does not trigger a memory warning under normal usage conditions. I haven’t really seen this written anywhere, just commonsense, where normal conditions would mean:

  • You haven’t just rebooted the device. If you’ve just rebooted, you are in ‘perfect conditions’. At the moment I tested my app and it triggers the memory warning 12 times or so. If I reboot and perform the same test, the warning never gets called.
  • You are not testing right after another app has crashed. Maybe this makes no difference, but it feels like abnormal conditions.
  • Your test involves normal gameplay, and lasts for the maximum expected duration for a play session.
  • You are testing on the tightest configuration possible (e.g. iTouch 2nd gen, 8GB, running OS4)

You can ‘recover’ from a memory warning – maybe you just need to free enough memory, and since my app did not crash after receiving 12 memory warnings, you might even think it’s OK. Now, do you really want to be running on the edge of disaster? I don’t think so.

What Instruments say

When I get a memory warning, instruments are displaying memory as follows:

  • 30 MB (process allocation) in Activity Monitor
  • 20 MB (live bytes) used by my process in ObjectAlloc

These values are consistent with the rumored 20MB, and also consistent with repeated complaints that different instruments provide different values. ObjectAlloc measures  live bytes – memory used by an app; activity monitor measures (a variable amount of) memory allocated to a process. I tend to give more consideration to what ObjectAlloc says, because this is easier to understand, easier to predict and easier to control. There are additional conditions that will cause a process to use more memory:

  • If we keep allocating / deallocating blocks of various sizes, we fragment memory and promote semi-transient waste.
  • It may be nearly impossible not to leak any memory over time (especially if we need a system library that leaks memory). Leaked memory is lost forever, and won’t show in ObjectAlloc.

So what do we need to do?

I am targeting 15MB max as peak allocation in ObjectAlloc. I think it should be possible to play my game end to end without exceeding this value and use this as ‘maximum expected play session duration’. I have fixed all known and known to be fixable memory leaks in my product; I want to have a go and try to find out if I can work around leaks in system libraries. I don’t expect to be able to fix all of them.

I have implemented didReceiveMemoryWarning – so I have a mechanism to release unused resources. Once we’ve done that, we want to release resources more often, so we stay under the maximum we choose (in my case 15MB). If we’re really tight, we might want to arrange assets to be lighter (e.g. use models with a lower poly count if we’re talking 3D apps)

A quick case study

My game is a 3D game. the bundle is about 17MB worth of data, including 1MB worth of code. I’m not using textures; I’m loading models on the fly, so I have no loading times.

I have two problems:

  • Except procedurally generated geometry, my allocations never expire unless a warning triggers the release mechanism
  • Most resources reload almost immediately. Why? because I test bounds for visibility (and other things). However bounds are not stored in separate files. In fact bounds are evaluated when an object loads. While the processing overhead is negligible, bounding boxes are released along with geometry.

If it was to do all over again, I might just store bounds separately. This might help deferring loading an object, so my ‘loading time’ for a stage would drop from about 1 second to nearly nothing – or maybe not – at the moment it doesn’t even seem asset loading is the main cost in scene setup.

As it stands, I am not doing it all over again; instead I want to retain bounds when I release assets, and release assets in a timely manner. While I’m doing this I also want to never release geometry that needs be displayed at the next frame. My resource release mechanism doesn’t know about that.

How to know when a resource is ready to be released?

In my rendering loop, there is a procedure that checks whether objects are likely to enter the viewing range. This is a quick and dirty way to skim the complete list of objects in the 3D scene. This procedure gets called less often than a regular visibility check – so the renderer needn’t check all the scene all the time (there are significantly better ways to code this).

So my first idea is, use a skip count. If an object hasn’t entered the near range for a while, we’re OK to release. I wouldn’t set the skip count too low – no need to release resources to often, as whenever we reallocate them, we actually incur memory (fragmentation) and performance (loading) overheads.

It looks good enough, nothing super-clever but OK. But… there is a catch.

Surely geometry is shared – in my implementation, Element is just a token representing an instance of an Object3D – shared geometry reused over and over. That’s where reference count comes in play, right? Whenever an Element instance determines that it doesn’t need its geometry, it releases its instance of Object3D and when the reference count reaches zero, Object3D gets deallocated, correct?

geometry is also mapped from file paths. So when a new element is created, we get the model from the map. Needless to say the map is also retaining each object once. As it is, all elements may release their instance of a geometry object, the map won’t know about it and we still haven’t got the geometry to deallocate.

There are ways around this problem, but we want to do things without wasting either time or too much memory, or changing the existing structures. Here’s the plan:

  1. Each geometry node will have used flag. Not a counter, just a boolean.
  2. Initially the used flag is clear (false).
  3. Whenever we update the display list, every object that’s nearby sets the used flag.
  4. From time to time (every 1 to 5 minutes, say), we iterate the list of values in the map, then…
  5. We release all models for which the used flag is clear – these models haven’t been used in a while, likely we won’t need them soon.
  6. We clear the flag for all remaining models.

I can generalize this a little bit checking accesses from Element3D.

    Implementation?

    I tried to implement the above quickly. Maybe a little too quickly. Ghosting bounds (retaining the bounds after geometry has been unloaded) went fine. Trying to automate memory release (based on the used flag) looked good in theory; in practice, it didn’t really work this time.

    So I did the simple thing. Force release (using the existing mechanism for handling memory warnings) manually when reaching a new stage in the game or performing a key action. The results are displayed below.

    Test Results

    I tested on an iPhone 3GS, mainly to save time. I use more memory on the 3GS because the rendering surface is bigger than the display (so I can antialias). The test glitched a little because I’d introduced a bug that failed the release mechanism between stage 3 and 4 in my game.

    • Startup: 0.6MB
    • Stage 1: 3.8-4.3MB
    • Force release as much as possible: 1.76MB
    • Stage 2: 4.67-10.06 (until Klinnburg village); 5.5 after picking the bread; climb to 12-13 MB
    • Stage 3: 13 – 20.6 (but fails to show chapter 3 notice and release memory when starting)
    • After releasing resources: 5.0mb
    • Stage 4: 12.18-16MB

    Conclusion

    The results of the test suggest that the resource release mechanism is somewhat inefficient. It looks like, if I had just 6 stages like the ones above, I’d hit the 20MB limit.

    Meanwhile, I don’t expect running into problems for this release. I don’t think my app leaked about 20MB in 40 minutes. I’ve done several passes to eliminate all leaks in the app code. One of the latest steps before submitting the app will be checking for leaks again, and looking into leaks generated by system libraries.

    Here’s what you need:

    • Audacity, maybe with the Lame MP3 Encoder. Audacity can open and edit / filter
    • iCaf – a beautifully small and efficient utility to convert mp3/wav to iPhone’s CAF format.

    Scouring royalty free sound sites for stuff takes a long time. Checking usage rights with artists takes roughly the time it takes to find songs in the first place (especially on low bandwidth). So what’s a long time? I’ve spent 2 or 3 days finding less than 20 samples. The music and effects are definitely better than what I would have come up with. More often than not, I find that I need to edit the sound (fade-in/out and level tuning), so I needed something like Audacity.

    On the cool side, I found that artists I contacted (when they reply) are most friendly and approachable, so maybe checking free sites for stuff you can use is a good step towards the better way into sound and music: work with an artist you already know.

    I also got slightly shocked finding that some of these guys drop a couple of sounds on a free site, then move on their merry way and become known for what they do, sometimes even signing up trailers and music for blockbusters. One thing about the internet is that it’s a huge collective memory, where the early experiments of gifted talents are beautifully preserved.

    Hey. I’m way out of it. Next time I’ll explain two or three classes, no more, that can help you integrate sound and background loops into your iPhone game.

    After…

    • A super-long week-end (just 3 days really)
    • Adding an app icon (57×57 png, add to your project, then list in your something-Info.plist file)
    • Adding help, pause, a splash screen and a loading screen

    I got a few friends to try my game. I was actually deluding myself into believing this thing is playable. Well just about. Most of my friends are non players and non iPhone users. Realtime 3D or whatever I put into it to make my game exciting, attractive, and worth giving a go, means nothing to them – gotta remember they’ve just seen Avatar in an IMax cinema, right?

    Usability

    After Doodle Jump’s super-massive international success, I like to kid myself into believing that every iPhone gamer can tilt their phone (also a good way to keep your screen clean). Before I get back to my fairy world, maybe I should list some of the many usability issues that seem to plague my game.

    1. Tilt. My tilt navigation isn’t super sensitive, and it’s pretty easy to stop moving also. Since there had to be a way to go pick the phone while stirring your veggies, in other words get your both hands free, I only use touch for action buttons and pausing the game.
      I love it, and would contend this is ideal for an adventure game with light action, but I’m really worried after seeing how quickly this gets the non-initiated frustrated with my baby app. I’m currently considering drawing a pad on the screen. Now that’s gonna bore me to bits.
      It’s not just because I don’t want to get into GL picking this round. Many games seem to provide touch and a joypad emulator, and some testers seem to favor the latter.
    2. Not seeing their character. That’s the downside of having a fairly complex game stage and automating camera management. Making sure the camera is always well placed isn’t so easy, and i’m still working on it.
    3. Getting blocked. I’ve more or less given up on having the PC fall down cliffs in my game. Everywhere is cliffy and it’s not meant to be Super Monkey Ball. My trial users like to run into walls, and feel stuck.
    4. Getting kinda stuck. Because my terrain is a little complex, I already put a lot of work into avoiding getting the PC completely stuck between rocks or other things. I half believe having easier controls is more than half of the problem – I see my mock players getting stuck in places they really didn’t intend to go… but…
    5. Talkback management. When my game pauses, I display a little on-screen explanation showing how to play the game. This starts with the Avatar talking to you and it’s really cute. Problem is, when touching the screen again, the talkback doesn’t disappear right away. So I had a friend pressing again, which pauses the game again, doesn’t make the talkback disappear (that one’s got a timer) either. Then they press again. And again. And again…
    6. Where are the buttons. I don’t really want buttons to cover half of my 3D view. I made them reasonably sized (fingertip sized?) and translucent. Maybe a little too translucent…

    The one true player that really enjoyed my game so far is an 18 months old. Pity demographic transitions and the baby crash.

    Gameplay

    I still hope my gameplay is better than my UI…
    • Getting into them damn houses… I wanted to represent a village, so I made houses with pretty red doors. Everybody can see the red doors. Everybody wants to get in. Pain…
    • Picking up the pretty items. Anything small enough and lying on the ground is considered an item. Good to know. It’s not enough that a caption pops to qualify a non pickable item as a story item. Clearly if the player is trying to pick something they can’t, I’ll have to display a message telling them why. Is it gameplay or usability, I’m not sure…
    • Skipping around… Maybe this tilt thing again. When I display captions, I don’t hold the game and you can continue skipping around. Encountering new bits of story doesn’t matter as talkback gets queued. Problem is, nobody reads popups. My talkback is simple and non-intrusive. This way it looks like it’s not really part of the story, so if a player actually manages getting around, after 3 minutes they should know what’s going on, and they don’t. They should know what to do, and they ask me instead. They should enjoy the game and…
      …since I hate these games where you end up bumping into every other thing again and again and having to skip dialogues I’ve read already, here’s the deal…

      • Stop action the first time encountering a story item or dialogue.
      • Let talkback play again when encountering a story item the second time (in case somebody wants to read it again.
      • Don’t queue talkback. A new item cancels the previous one immediately.
    • Give challenges. At the moment, I would contend that I give enough information for even a reasonably casual player to progress through the demo stage. But then, I’m not so sure. I feel it’s less about giving information, and more about how the information is presented. If I can give challenges to my players, they’ll feel more involved and motivated (and more willing to solve little narrative puzzles).

    Right. All that stuff makes me feel a little sad after the groove of feeling ready to show off stuff. Good news is, my next target is putting together preview pics.