Related Posts Plugin for WordPress, Blogger...
This form does not yet contain any fields.

    Follow Me on Pinterest

    Our products are on iTunes!

     Nanaimo Studio

    Find us on Google+ 

     

    We are listed on: Dmegs Link Directory

    Blog Index
    404 page

    Entries in iOS (8)

    Thursday
    Oct062011

    Dissecting Cocos2D - CCDirector

    Cocos2D is a great open source game framework created by Ricardo Quesada with contributions from its community.  Not only does it save you time in creating 2D-based games for the iOS, a careful reading of the code will make you a better game developer and an iOS coder.

    In this series, we will dissect Cocos2D a little bit at a time, pick up valuable coding techniques and examine design patterns and decisions utilized by Cocos2D along the way.

    We will start off by looking at the entry point, the heart of Cocos2D - the CCDirector class.  CCDirector is a singleton class that manages and coordinates the overall operation of your game.  Another common name for this in a game framework is a Game Manager.  Most of the time there is only one game manager managing an entire game, that's why CCDirector is a singleton class.

    Let's look at some code snippets in CCDirector and see what we can learn from it:

    static CCDirector *_sharedDirector = nil;
    
    + (CCDirector *)sharedDirector
    {
    	if (!_sharedDirector) {
    
    		//
    		// Default Director is TimerDirector
    		// 
    		if( [ [CCDirector class] isEqual:[self class]] )
    			_sharedDirector = [[CC_DIRECTOR_DEFAULT alloc] init];
    		else
    			_sharedDirector = [[self alloc] init];
    	}
    		
    	return _sharedDirector;
    }
    
    +(id)alloc
    {
    	NSAssert(_sharedDirector == nil, @"Attempted to allocate a second instance of a singleton.");
    	return [super alloc];
    }
    
    

    The above code snippet implements a singleton. The static keyword appearing in the class scope has different semantic than had it appear in a method/function scope. In class scope, the static keyword means your variable is internally linked only and therefore not visible outside of this class. In method/function scope, a static variable persists its value across multiple calls to the method, which makes it behaves like a member variable but visible to your method only.

    The alloc method makes it so if you attempt to instantiate CCDirector directly (via the regular two-staged creation of alloc-init), your code will fail the assertion.

    The code snippet above is typically how you would implement singleton for your class.

    Notice the class check inside the init method, which isn't always present in typical singleton implementation. What does this do?
    [ [CCDirector class] isEqual:[self class]]

    This tests to see if the instantiation is on the abstract base class or from one of its derived concrete classes. If it is from the base class, instantiate the default derived class via the macro CC_DIRECTOR_DEFAULT. Currently there are four types of CCDirector-derived classes for iOS (implemented in CCDirectorIOS.m class) and one type for Mac (CCDirectorMac.m class).
    For CCDirectorIOS, they are briefly: CCDirectoryTypeNSTimer, CCDirectorTypeMainLoop, CCDirectorTypeThreadMainLoop, and CCDirectorTypeDisplayLink. We will look at these in more details in a later series.

    Since we mention CCDirectorIOS, we will digress a little and look at one code snippet in CCDirectorIOS class:

    @interface CCDirector ()
    -(void) setNextScene;
    -(void) showFPS;
    -(void) calculateDeltaTime;
    @end
    
    

    This is a category method for CCDirector. Why does it appear inside CCDirectorIOS? Actually with this technique, you are able to implement CCDirector's private method setNextScene from within CCDirectorIOS that you wouldn't otherwise able to. This is the same technique developers use to override Apple's private API's implementation. The downside to using category method technique to extend/change the behavior of a base class's method is that you can't call the base class's method like you can via inheritance using the super keyword.

    That's all for this series. In the next series, we will look at CCDirector in more details and learn a few tricks along the way.

    Sunday
    Apr172011

    Xcode Build and Archive Sharing Problem (and Solution)

    In our last post regarding Xcode, we gave you 10 simple steps to rename your Xcode project. In this post I assume that you know how to create an ipa file from Xcode.  For info on how to do that, check this article out: http://support.testflightapp.com/kb/tutorials/how-to-create-an-ipa-xcode-3

    Recently I ran into an annoying issue while trying to create an ipa file using Build and Archive.  Xcode would compile and verify the app fine, but when I tried to share the archive application (via Organizer->Archived Applications->Share), a spnner would appear and go away and the usual Save ipa file dialog would not appear.

    It's apparent (or maybe not) that something is causing Xcode to bail out of the process.  The next step is to figure out how we can get more info that tells us why Xcode is not behaving the way it normally does.

    To achieve that, let's eliminate Xcode out of the picture and get our hands dirty by building the app from the good old terminal and hopefully that will allow us a better picture on what went wrong.

    1. Build the project to .app file 

    xcodebuild -target "${PROJECT_NAME}" -sdk "${TARGET_SDK}" -configuration Release

    In our case, the command is

    xcodebuild -target "Word Tracer" -sdk "iOS 4.2" -configuration "Ad Hoc"

    Note: You can skip this step by building in Xcode. 

    2.  package .app file into an .ipa file

    /usr/bin/xcrun -sdk iphoneos PackageApplication -v"${RELEASE_BUILDDIR}/${APPLICATION_NAME}.app" -o"${BUILD_HISTORY_DIR}/${APPLICATION_NAME}.ipa" --sign "${DEVELOPER_NAME}" --embed "${PROVISONING_PROFILE}”

    In our case, the command is 

    /usr/bin/xcrun -sdk iphoneos PackageApplication -v build/Ad\ Hoc-iphoneos/WordTracer.app -o WordTracer.ipa --sign "test name" --embed "/Projects/WordTracer/test.mobileprovision"

    Sure enough, I got the error below after running the command.

    + /usr/bin/codesign --verify -vvvv -R=anchor apple generic and (certificate 1[field.1.2.840.113635.100.6.2.1] exists and (certificate leaf[field.1.2.840.113635.100.6.1.2] exists or certificate leaf[field.1.2.840.113635.100.6.1.4] exists)) /tmp/r3kFZTMcqd/Payload/WordTracer.app

    Program /usr/bin/codesign returned 1 : [/tmp/r3kFZTMcqd/Payload/WordTracer.app: a sealed resource is missing or invalid

    /tmp/r3kFZTMcqd/Payload/WordTracer.app/letter_data/hei_计.plist: resource added

    /tmp/r3kFZTMcqd/Payload/WordTracer.app/letter_data/hei_计.plist: resource missing

    ]

    Great, now we got more info that we did in Organizer.  Armed with this piece of info we can begin to investigate what halted the build process. It looks like hei_计.plist is the culprit. I double checked the file name in terminal. It turned out that there is a character \036 in it which won't appear in Finder (another reason why you should always rely on Terminal for things like this).  A quick conversion from \036 (octal) to hex gives us 0x1E.  It looks like this is a control character of some sort (http://www.fileformat.info/info/unicode/char/1e/index.htm) and this is what was causing a hiccup in the ipa packaging process.

    I proceeded to remove the character \036 from the filename, rebuilt the app and this time Organizer allowed me to save the ipa file like it normally does.

     

    Monday
    Feb282011

    Binary file names cannot contain a space

    If you try to submit an app with a blank space in the app name, you may run into this error at the validation phase: "Binary file names cannot contain a space"

    To fix this, follow the steps below:

    Step 1) Right click on the app that you just "Build and Archive" on. Select Show in Finder.


    Step 2) Proceed to remove the blank name out of the .app file and .dSYM file. Double click ArchiveInfo.plist to edit it in Property List Editor.


    Step 3) Update the entries in ArchiveInfo.plist by removing the blank space from the XCApplicationName and XCApplicationFilename and save the file.

    Resubmit the app and it should go through without a hitch. Hopefully this will be fixed in future version of Xcode.

    Page 1 2