While Cocos2D is compatible with ARC, simply enabling ARC in the project’s Build Setting will throw several hundreds of errors in your face. Cocos2D doesn’t provide ARC-enabled project templates. Thus this tutorial about how to enable ARC in a newly created Cocos2D Xcode Project.
While none of these steps are overly difficult, you’ll notice there’s plenty of steps to perform. Unavoidably, and on the off chance you don’t already know, I’d like to recommend Kobold2D to you if you want to write ARC enabled Cocos2D apps. Because none of the steps below, really zero, zilch, nada, niente, keine are necessary to enable ARC in Kobold2D. That’s because it ships with 15 template projects all of which have ARC enabled out of the box. And Kobold2D 2.0 with cocos2d-iphone 2.0 is just around the corner.
Self-advertisment aside, these steps are tested with cocos2d-iphone v2.0 but should also work with cocos2d-iphone v1.1 – but admittedly I haven’t tested the process with the v1.1 version. If you find anything that’s not quite working with v1.1 please leave a comment. Preferably with the solution, that’ll be awesome!
UPDATE: I released a video version of this tutorial:
Install Xcode, Cocos2D, and the Cocos2D Xcode Templates
Let’s first check that you have all the prerequisites. With iOS devices selling like Playboys in the 70s these days, there’s got to be those who haven’t gotten to install Xcode or download Cocos2D yet. And for everyone else this is a version-check and a reminder to upgrade their tools and cocos2d frequently. The latter being particularly simple if you’d been using Kobold2D. Just saying.
- Download and Install Xcode 4. Now might be a good time to upgrade if you’re not on Xcode 4.2 – because there’s no ARC for you without at least Xcode 4.2.
- Download Cocos2D and extract the cocos2d-iphone-****.tar file by double-clicking it. The filename varies depending on the cocos2d version.
- Open Terminal.app and enter:
./path-to-cocos2d-iphone/install-templates.sh -f
Note: The path-to-cocos2d-iphone needs to be replaced with the actual path to the cocos2d directory. For example, if you are using Safari and extracted the file cocos2d-iphone-2.0-rc0a.tar where Safari downloaded it, then this command should work for you: ./Downloads/cocos2d-iphone-2.0-rc0a/install-templates.sh -f.
Note that the leading dot is essential, without it you’ll most likely get a “No such file or directory” error.The install-templates.sh script will install the cocos2d-iphone Xcode templates. You have to run this script each time you download a new Cocos2D version to make sure that newly created cocos2d projects use the latest cocos2d version.
The template files are copied to the user’s Developer directory which is ~/Library/Developer/Xcode/Templates. This is the directory you want to browse to in Finder if you ever wanted to delete the cocos2d Xcode templates. Perhaps to remove older version files or in case the install script fails with a permission issue.
The -f switch forces the script to replace any existing cocos2d template files, so that you don’t get any errors should you have previously installed the cocos2d Xcode templates.
ARC-ifying the Cocos2D code of the Template Projects
First we are refactoring the Cocos2D code away from your project and into a static library, so that your ARC-enabled code and the non-ARC cocos2d code can work happily together. If you were to enable ARC without separating the cocos2d source code the compiler would not be very happy. The Cocos2D codebase may be compatible but it’s not compliant with ARC, meaning Cocos2D itself is not using ARC and must be compiled with ARC disabled.
The following steps are the same for all Cocos2D Xcode Project Templates. I chose the Box2D template but you can apply the same steps to any of the other templates as well.
- Open Xcode (duh!)
- Create a new project, for example by selecting from the menu: File -> New -> Project…
- Select the desired cocos2d Xcode Template: Box2D, Chipmunk or no physics for either iOS or Mac OS X.

- Click Next and give the new project an appropriate name and save it anywhere (but remember where).

- Build & Run the project to verify that it’s working. You never know.
- Delete the libs group in Xcode. Make sure to select Remove References in the confirmation dialog because you’ll still be needing the files later on, so don’t trash them.

- Select the Project itself in the Project Navigator. It’s the first entry with the blue document icon in the treeview pane on the left side of the Xcode window. Then click the Add Target button at the bottom, just below the Project/Targets list.

- In the Add Target template dialog navigate to the Framework & Library group and select Cocoa Touch Static Library respectively Cocoa Library if you develop a Mac application. Then click Next.

- Name the library appropriately, for example cocos2d-library. Be sure to deselect both Include Unit Tests and Use Automatic Reference Counting
.
Warning: Some recommend to use the -fno-objc-arc Compiler Flag to disable ARC on a per-source-file basis. This is only helpful if you have very few source code files which require this flag where an extra static library target would be overkill. Since you’ll have to add the flag to each cocos2d source code file individually – one-by-one – and there being anywhere between 100 and 150 source files, I strongly discourage going down this road. Plus it will be a maintenance nightmare whenever you upgrade cocos2d.
- Once created, the cocos2d-library target is selected and the Build Settings pane is shown. You need to navigate the Build Settings to make two changes to the Search Paths section. The easiest way to find these settings is by entering “search” to the search filter textbox in the upper right corner of the Build Settings pane.
Set the Always Search User Paths setting to Yes and set the User Header Search Paths to the somewhat cryptic ./** string.

Note: You can edit the User Header Search Paths setting in two ways, one by clicking it twice with a delay between the clicks – this allows you to enter the text directly. Alternatively you can double-click the field which brings up an additional dialog with a checkbox in it. In that case, either enter just a dot and click the checkbox, or enter the full string ./** but do not check the checkbox. Otherwise you might end up with the string ./**/** which will cause compiler errors. Be sure to verify the string is correct after the edit dialog closes, since Xcode might change the string depending on whether the checkbox is checked.
Warning: The search path ./** is a quick & dirty short-hand for “search the project’s folder and all of its subfolders recursively”. This works fine as long as any header file you create or add to your project does not have the same name as a header file in the libs folder. For example, you must not add a header file named CCNode.h to your project, because the compiler will be confused which CCNode.h to use – the one from your project or the one provided by cocos2d-iphone. This applies to all files in the path, including those that aren’t referenced by the Xcode project.
- Select the original target of the project. That means the one that was already there, the one that’s building your app, not the cocos2d-library target you just added. Select the Build Phases tab and expand the Link Binary With Libraries list.

- Click on the + button at the bottom of the list, select the libcocos2d-library.a file and click the Add button. This will link the cocos2d library code to your project’s target.

- Now it’s time to re-add the cocos2d files. Use File -> Add Files to “name-of-project”… to bring up the file dialog. Navigate to and select the libs folder. Make sure the Destination checkbox is unchecked and the Create groups for any added folders radio button is selected. Finally verify that the cocos2d-library target is the only target whose checkbox is checked before clicking the Add button.

- Build and run to make sure everything works now that the cocos2d code was separated into a static library.
Enabling ARC in your project
Now that the cocos2d code is separated from your project’s code, you can use the built-in Xcode ARC conversion tool to update the project template code to use ARC. This will also enable the appropriate Build Settings.
- From the Xcode menu choose Edit -> Refactor -> Convert to Objective-C ARC…. This brings up a dialog where you can select the targets to convert. Select only your app’s target but not the cocos2d-library target. Then click on Check.

- Xcode will build your code with ARC enabled and then present you with a wizard that helps you convert the project’s code to ARC. Read the text and click Next.

- Xcode will show a dialog that allows you to review the changes it is about to make. You can safely accept all of these changes.

- Build, run and rejoice: Your project’s code is now ARC-enabled!
Cleaning up (optional)
When you created the cocos2d-library target it also added three source code files to the project that you don’t need. You can safely delete (trash) the cocos2d-library group and all the files in it.
You only need to make a small change to the Build Settings of the cocos2d-library target. Locate the Prefix Header Build Setting, select it and press the Delete key so that the Prefix Header setting is empty. Alternatively just keep the prefix header file and only delete the two other files (cocos2d-library.h and .m).
Enjoy your ARC, WOOF, WOOF, GRRRRRR!
This should make it straightforwd for everyone to enable ARC in a Cocos2D project. Of course you can always just get Kobold2D and not concern yourself with these nasty technical things at all.
I hope you enjoyed this tutorial. Please leave a comment if you found any discrepancies, specifically since newer cocos2d or Xcode versions might behave slightly different. I’d also appreciate it if you’d tweet, like or plus-one this article if you liked it. Thank you!
| Follow @gaminghorror | Follow @kobold2d |
|









Hi Steffen,
I have a problem at step 12 – the step to add the Binary Library. The cocos2d-library.a file is not displayed in the list to choose from. How do I build this library first??
Thank you for providing the detailed tutorial.
Some suggestions:
- if you did not name the static library target “cocos2d-library” but something else, pick the “lib.a” instead
- if no such lib appears in the list, I would assume that the static library target isn’t in the project. Go back to step 7 and re-do these steps. Perhaps you selected the wrong template?
- if all fails, you might want to start over from step one, maybe you missed a step?
Btw, you don’t need to build the library. It will be selectable as soon as the static library target has been added to the project.
Thanks Steffen for such a quick reply. I followed the steps all over and this time, I saw the .a file to add!
Hi, first of all, thanks for your excellent article on this subject.
I am having a problem, however. When I try to convert to ARC I get an error on the below line, I commented it out and the conversion succeeded but uncommenting the line causes the build to fail.
bodyDef.userData = sprite; //- Error: Assigning to ‘void *’ from incompatible type ‘CCSprite *__strong’
I used the Box2D template and this was code that was included so it should be easy to replicate, the line of code is in the “HelloWorldLayer.mm” file in the “-(void) addNewSpriteWithCoords:(CGPoint)p” function. I’m not really versed in Objective C as I am from a Java/C# background. Any help would be appreciated.
Hmmm, I also used the Box2D template. This should have been converted by Xcode. Are you using the latest Xcode 4.3.2?
Anyhow, the fix to this:
bodyDef.userData = sprite;
Will most likely be to bridge-cast the sprite like so:
bodyDef.userData = (__bridge void*)sprite;
This tells ARC that it’s ok to re-cast the sprite as a void* pointer. Of course, should ARC decide to release the sprite the pointer would become invalid. But since the body’s lifetime is that of the sprite it will be fine.
I’m on Xcode 4.2 (trying to avoid upgrading to Lion, I’m not sure my Mac Mini would take it).
That builds great now though, will have to look more into that void* pointer business, I’m under the impression that ARC will make my life easier, I would hate to think things started to go wrong because of it.
Thank you for your help though.
Before asking, Thanks for your article.
But do not work my project,,,
Error msg is
Cannot Convert to Objective-C ARC
Xcode found 28 issues that prevent conversion from proceeding. Fix all ARC readiness issues and try again.
To see all ARC readiness issues, enable “Continue building after errors” in the General preferences pane.
what shoud i do?
I assume it’s not a cocos2d template project but one where you’ve already worked with, wrote some code, etc.
In that case you will have to fix these “ARC readiness issues”. Do as it says, ie enable “continue building” and try again. Then go through each error. For some (hopefully most) Xcode may already suggest a fix. Other solutions you can usually find via google. If you’re using either Chipmunk or Box2d, or other C/C++ code, chances are most of the issues can be solved with a simple __bridge cast.
For example something like this is very common in Box2D/Chipmunk code:
body.userdata = (__bridge void*)sprite;
[...] | 参考1 [...]
[...] Enabling ARC in a Cocos2D project isn’t as straightforward as it should be. I already explained all the necessary steps and precautions in the Enable ARC in a Cocos2D Project guide. [...]
Hi,
I have a question about enabling ARC in a cocos2d. In my project, I need to embed a cocos2d view into a Cocoa Touch app. In this case, I need to adapt what you described on this page, but am not sure how. Can you help me resolve this issue?
Thanks so much!
You will want to follow the same steps of creating a cocos2d static library project. But instead of adding the static library to the cocos2d template project, you should add it to your Cocoa Touch project instead.
You may want to move the libs folder containing all the cocos2d files over to the Cocoa Touch project, just to make sure the files are all in the same folder.
I did what you suggested, but it did not work. I created a Cocoa Touch project with ARC and copied the entire lib folder from a Cocos2d-Box2d template project. Then, I followed the directions, but I got linker errors when I tried to build the project.
ld: library not found for -lcocos2d-library
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Any ideas how to fix the problem?
Thanks in advance.
Sounds like either the cocos2d lib target wasn’t built because Xcode thinks it’s not needed (add it also to Target Dependencies as well as Link Binary with Libraries list).
There’s also the possibility that you’re using the legacy Build Location setting in Xcode Preferences. This may cause Xcode to not being able to find the compiled library.
I think it’s time that the Cocos2D library project included a target for building a static framework. I’ve been using static frameworks in a lot of my work, and they can be very useful. They use the file structure familiar from dynamic Cocoa frameworks, including the headers. The only wrinkle is that Xcode doesn’t know to copy framework resources.
You can build an embeddedframework as a kind of bundle that includes the framework bundle and a symlink to the resources folder as a means of accessing the resources, though it’s not a perfect solution.
Another, similar approach, which might suit Cocoa2D better, is to build a library, as described, and a separate bundle containing the resource files. Then you drop the two files into Xcode and it knows what to do with them.
Useful links and examples:
https://github.com/kstenerud/iOS-Universal-Framework (templates!)
https://github.com/nulayer/nuleveldb (example of project using static framework)
https://github.com/klazuka/Kal (static lib; uses a bundle for resources)
AFAIK the framework approach is somewhat of a hack. It’s not officially supported or endorsed by Apple. Still, it’s great if you can bundle both code and resources in one file.
Static Libraries for cocos2d work well enough as in Kobold2D. Resource files need to be copied, but in most cases they’re not substantial.
Don’t know why, but when i try this with Cocos2d ver1.1 b2 with Box2d I get an error when refactoring to ARC. The conversion will not start as I get an error message “Cannot convert to Objective-C ARC – XCode found 2 issues that prevent conversion from proceeding. Fix all ARC readiness issues and try again”.
I get the error in the files:
HelloWorldLayer.mm
ccCArray.h
I haven’t tried v1.1 but it may not be as compatible with ARC as needed. An error in ccCArray.h should most certainly not happen and needs to be fixed in the engine. I suggest reporting this issue here: http://code.google.com/p/cocos2d-iphone/issues/list
Hi, nice guide, I tested this with cocos2d v1.1 and it’s working well, but I got several warnings in ccCArray.h and CCParticleSystemQuad.h
great guide – but I can’t get it to work.
when I do teh enabling Arc step, I get 55 errors and 14 warnings.
Example errors are:
In ccCArray.h, in Support in cocos2d in libs
in the line
id *arr;
the error is Pointer to a non-const type ‘Id’ with no explicit ownership
This was with a newly installed cocos2d 2.0 rc1 and a new project (following your steps exactly)
I even did it twice in case I made a mistake.
I’d be using Kobold2d but the use of Lua is confusing me!
Check the cocos2d.m file to verify the project is really using cocos2d 2.0 rc0-post (same as rc1). The guide definitely works with rc1 projects.
I have a hunch that you’re not on the latest version because cocos2d changed all occurances of id* in ccCArray to use the CCARRAY_ID macro.
Btw, what is so confusing about Lua?
[...] might sound lazy but I am slightly confused on how to proceed on this subject. I have followed this guide which is very well [...]
[...] is deemed compatible with ARC it does not provide ARC-enabled template projects. That’s where tutorials will help you out. Or in general the development [...]
Thanks for the tutorial! i have a simple answer, if i follow the tutorial for enabling ARC, then i can use ARC also the in cocos2d classed?…i mean for example for my MainMenuLayer.h and .m or MainMenuScene that use cocos2d library i can use ARC? right?
Yes, that’s the whole point of enabling ARC, being able to write your code with ARC even that which uses cocos2d methods and classes.
[...] ARC project. Pretty awesome.When I wrote the tutorial how to enable ARC for a cocos2d project, I neglected to include an actual working project. I mean why read and follow a long tutorial if [...]
Hello,
Great Tutorial, works like a charm.
Thanks.
[...] platform, including for iOS “cocos2d for iPhone”. In the past it used to be quite an hassle to enable ARC into your cocos2d projects. However, the following guidelines describes how to enable [...]
Fab guide, worked first time. Thank you
Hi,
I recently updated to xcode 4.5 and I tried these steps. When i try to compile (at step 14) using the 5.1 simulator, I get a EXC_BREAKPOINT error.
dyld: lazy symbol binding failed: Symbol not found: _objc_setProperty_nonatomic
Referenced from: /Users/{MY_NAME}/Library/Application Support/iPhone Simulator/5.1/Applications/242E3891-8DA8-4AA6-BD00-7B79F6E8A8AC/qwe234.app/qwe234
Expected in: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/System/Library/Frameworks/Foundation.framework/Foundation
Any idea why this is happening?
Thanks
Hmmm, not sure. I was thinking that for 5.1 support in Xcode you’ll have to install the compatibility update. But if you haven’t you shouldn’t even get to choose to run on iOS 5.x Simulator, only iOS 6. Because the error kind of looks like there’s something missing in the Foundation framework.
Maybe check if this also happens with a vanilla cocos2d project. Be sure to use cocos2d 2.0 stable and not a beta version or v1.x (should work but just to be sure, 2.0 is what I tested it with).
thanks for the response.
The issue was that the iOS deployment Target for the static cocos2d-library was set to iOS 6.0. I changed it to 5.0 and it worked!
Thank you! Was having the same problem and changing the deployment target for the library fixed it.
Thanks for the very clear guide Steffen.
I’m using Cocos2d v 1.0.1 with xCode 4.5 Lion
After placing the Cocos2d Libs in the static library, the refactoring still wants to target the Cocos2d-Library. I made sure that it was not checked in the refactoring. I have attempted this many times with several new projects and always the same results. Is there a different approach to this with xCode 4.5?
Thanks for all you do Steffen. I enjoy your books, blogs and twitter posts.
Alan
It should work the same way. Can you try with cocos2d 1.1 or 2.0/2.1? I’m not really sure how compatible cocos2d 1.0.1 is with ARC, if I remember correctly some crucial fixes weren’t applied until v1.1.
[...] platform, including for iOS “cocos2d for iPhone”. In the past it used to be quite an hassle to enable ARC into your cocos2d projects. However, the following guidelines describes how to enable [...]