Xcode 4.3 on Lion with 10.4 sdk and gcc 4.0

February 19th, 2012

So, you get the latest generation of Mac which only support Lion and above, which only runs Xcode 4 or later, which is great. You have few old projects that use 10.4 sdk, which only compatible with gcc 4.0. You don’t want touch those project but want to be able to build them just as before. Here we are, copy few files and folders from your earlier Xcode instation into the /Applications/Xcode.app, you can build them as before.

1. Copy
/Developer/SDKs/MacOSX10.4u.sdk
into
/Applications/Xcode/contents/Developer/Platforms/MacOSX.platform/Developer/SDKs

2. Copy
/Developer/usr/lib/gcc
to
/Applications/Xcode/contents/Developer/usr/lib/gcc (create the lib directory)

3. Copy
/Developer/usr/libexec/gcc
to
/Applications/Xcode/contents/Developer/usr/libexec/gcc

4. Copy
/Developer/usr/bin/*4.0* (any file name contains 4.0, about 9 of them)
to
/Applications/Xcode/contents/Developer/usr/bin/

5. Copy
/Developer/Library/Xcode/Plug-ins/GCC 4.0.xcplugin
to
/Applications/Xcode/contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins/

Sort files on iOS

December 4th, 2011

code snippet to sort files on the iOS

	NSFileManager *fileMgr = [NSFileManager defaultManager];
	
	NSArray *fileArray = [fileMgr contentsOfDirectoryAtURL:folderUrl
						includingPropertiesForKeys:[NSArray arrayWithObject:NSURLCreationDateKey]
										   options:NSDirectoryEnumerationSkipsHiddenFiles
											 error:nil];
	
	NSArray *sortedFiles = [fileArray sortedArrayUsingComparator:^(NSURL *url1, NSURL *url2) {
		NSDate *date1, *date2;
		
		// This works on iOS 5.
		[url1 getResourceValue:&date1 forKey:NSURLCreationDateKey error:nil];
		[url2 getResourceValue:&date2 forKey:NSURLCreationDateKey error:nil];
		if (date1 != nil && date2 != nil) {
			return [date2 compare:date1];
		}
		
		// On iOS 4 or earlier, the above getResourceValue won't work.
		date1 = [[fileMgr attributesOfItemAtPath:url1.path error:nil]
				 objectForKey:NSFileCreationDate];
		date2 = [[fileMgr attributesOfItemAtPath:url2.path error:nil]
				 objectForKey:NSFileCreationDate];
		return [date2 compare:date1];
	}];


Add facebook and twitter integration with ShareKit

October 1st, 2011

To register your iOS app with twitter:

1. Get twitter account if you don’t have one already.
2. Login to your twitter account, and go to https://dev.twitter.com/apps
3. Click on the “Create a new application” button.
4. Fill out the form.
Make sure for Access, select “Read and Write”.
The callback URL doesn’t have to be an actual existing url, but needs to match the one in the code, for example, put “http://forum.tufat.com/WikiAnimals” here and the same string in SHKConfig.h.
5. After submit the form, it will tell you the application’s “Consumer key” and “Consumer secret”.
6. Use those values to replace the current values in the SHKConfig.h, look for lines start with

#define SHKTwitterConsumerKey
#define SHKTwitterSecret
#define SHKTwitterCallbackUrl

To register your iOS app with facebook:

1. Get a facebook account if you don’t have one already.
2. Login and go to https://developers.facebook.com/apps
3. Click on the “Create New App” button
4. Fill out the form.
App Namespace, App Domain, Category are optional, you may leave them empty. Make sure “Native iOS App” is checked in the last section.
5. After save the settings, it will show the “App ID” and “App Secret”.
6. Use those values to replace the current values in the SHKConfig.h, look for lines start with

#define SHKFacebookKey
#define SHKFacebookSecret

Xcode 4 and Git for newbies

April 25th, 2011

A step by step test drive of the Xcode 4 ‘s Git integration feature.

1. Make sure have ssh access to github (http://help.github.com/mac-set-up-git/), then create am empty repository for testing. Here is my test repository’s URL:

git@github.com:cloudcoder/Xcode4Test.git

2. ‘Clone’ the repository use Xcode.

- Open the Organizer window in Xcode.

- Press on the ‘+’ button at the bottom-left corner, and select ‘Checkout or Clone Repository’.

- Paste you git repository’s URL in the Location field, then click Next.

- Type exactly the word ‘origin‘ (without quote) in Name field. Don’t use any other name before you become a advanced user.

- Click Clone, Xcode will prompt you to select a local directory (I named the local folder Xcode4Test in this example). Select wherever you want.

- Now you may see this:

- That’s OK, many people reported this operation often fails the first time. Just lick Previous and click Clone again. Select the same location and choose Replace (replace the one left by the last failed operation).

- Now, you should see this:

– Xcode automatically created a local git repository, now you have a local folder looks empty but actually contains a hidden folder ‘.git’ (just like .svn for Subversion).

3. Tell git to ignore those files such as .DS_Store file and Xcode build directory.

- So, before anything else, put a file name “.gitignore” in the newly created folder. Here’s the content of my .gitignore

# files created by Xcode 3 or older
*.pbxuser
*.mode1
*.mode1v3
*.mode2v3
*.perspectivev3
*.xcclassmodel/
# files created by Xcode 4
xcuserdata/
# build products
*.build/
build/
DerivedData/
# Misc
.svn
.DS_Store

3. Now let’s put a project in the repository.

- You may create new project from Xcode, or copy-n-pasted your existing project into the newly created folder. In this example, I copied a folder named “Hello Git” into this folder.

- Once you have the files in the folder, launch Terminal, ‘cd’ to the directory and give the command ‘git add –all’. The ‘commit’ means commit changes to the local repository. To push changes to the remote repository, you type ‘git push –all’ from the command line.

 

4. Work with Xcode

- At this time, it looks like I can only do ‘commit’ in the Organizer window and ‘push’ through the File->Source Control->Push….

Build and use dylib on iOS

October 1st, 2010

Xcode does not allow you to build dylib for iOS. App will be rejected if it’s not single binary. But I have an application that has plug-in architecture to load optional modules. I just want a quick prototype to prove concept before fully port it to iOS. It’s faster to do if dylib could simply work. So, this post shows how to build and use dylib but be aware it won’t be approved to App Store. (Tested with Xcode 3.2.4 on 10.6.4)

1. Open these files in the Property List Editor: “/Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Specifications/MacOSX Product Types.xcspec” and “/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications/iPhone Simulator ProductTypes.xcspec”

2. Locate the item in the “MacOSX Product Types.xcspec” that has the product type “com.apple.product-type.library.dynamic” and drag it to the “iPhone Simulator ProductTypes.xcspec”.

3. Open “MacOSX Package Types.xcspec” and “iPhone Simulator PackageTypes.xcspec” found at the same places.

4. Locate the item in the “MacOSX Product Types.xcspec” that has the package type “com.apple.package-type.mach-o-dylib” and drag it to the “iPhone Simulator PackageTypes.xcspec”.

5. Repeat the steps for the “iPhoneOS.platform” and relaunch Xcode if it was running.

Now, lets build a dylib. Start out with the “Cocoa Touch Static Library” Templete. That should included the Foundation.framework in the project. Here are the changes I made on top of the templete to build dylib.

1. Open the file “project.pbxproj” (found inside the Xcode project file bundle) in a Text Editor. Search for string “producttype”, change it’s value to “com.apple.product-type.library.dynamic”;

Now, open the project with Xcode, go to Project->Edit Project Settings

2. “Installation Directory” set to @executable_path/ because I plan to put the dylib in the same directory as the app’s executable.

2. “Mach-O Type” set to Dynamic Library

3. “Executable Extension” set to dylib

4. “Executable Prefix” set to empty

5. Add one or two simple methods to the library and build it.

Now, create an app to test it. This time, I choose the “View-based Application”. Hook up a UIButton and a UILable to call the lib and showing return message. You can download the complete project TestApp and play with it.

Use the MySQL client library in iOS project

July 9th, 2010

A code snippet shows the MySQL client library used in an iPhone project. You may see how the library was built in my last post.

MySQL C API Documentation

#import "mysql.h"

- (void)viewDidLoad {
    [super viewDidLoad];

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

	rows = [[NSMutableArray alloc] initWithCapacity:0];

	MYSQL *sql = mysql_init( NULL );
	mysql_options(sql, MYSQL_READ_DEFAULT_GROUP, "LibMySQL");
	sql = mysql_real_connect(sql, "www.iosplace.com", "iospla5_db2gt", "*", "iospla5_db2", 3306, NULL, 0);
	if (sql != NULL) {
		int level = self.navigationController.viewControllers.count;
		if (level == 1) {
			self.title = @"Movies";
			mysql_query(sql, "select Name from Movie");
		}
		else if (level == 2) {
			char queryStr[1024];
			strcpy(queryStr, "select Material.Name, Url from Material \
				   join Movie on (Movie.id=Material.Movie_id) \
				   where Movie.Name=\"");
			strcat(queryStr, [self.title UTF8String]);
			strcat(queryStr, "\"");
			mysql_query(sql, queryStr);
		}

		MYSQL_RES *qResult = mysql_store_result(sql);
		if (qResult != NULL) {
			MYSQL_ROW row;
			while (row = mysql_fetch_row(qResult)) {
				if (level == 1) {
					[rows addObject:[NSArray arrayWithObjects:
									 [NSString stringWithCString:row[0] encoding:NSISOLatin1StringEncoding],
									 nil]];
				}
				else if (level == 2) {
					[rows addObject:[NSArray arrayWithObjects:
									 [NSString stringWithCString:row[0] encoding:NSISOLatin1StringEncoding],
									 [NSString stringWithCString:row[1] encoding:NSISOLatin1StringEncoding],
									 nil]];
				}
			}
			mysql_free_result(qResult);
		}
		mysql_close(sql);
		mysql_server_end();
	}
}

Build MySql client library for iPhone/iPad

June 26th, 2010

The goal is to build a fat library that contains architectures for both the device (armv6 armv7) and the simulator (i386) for debug build.

Build on 10.6 with Xcode 3.2.2

  1. Download the source ofConnector/C(libmysql), select Source Code and click the Download button. (current version is mysql-connector-c-6.0.2.tar.gz)
  2. Download and install CMake for Mac OS X Universal.
  3. Generate Xcode project with CMake. In Terminal, issue command:
    cd path/to/mysql-connector-c-6.0.2
    cmake -G Xcode

    The libmysql.xcodeproj should be generated.

  4. Tweak in few places
    In “my_net.h”, comment out line 47 and 49

    //#include <netinet/in_systm.h>
    #include <netinet/in.h>
    //#include <netinet/ip.h>
    

    In “my_global.h”, change the line 129 to

    #  if defined(__i386__) || defined(__ppc__) || defined(__arm__)
    

    In “my_config.h”, undef HAVE_FDATASYNC at line 63

    /* #define HAVE_FDATASYNC 1 */
    
  5. Build with the xcodebuild command, build the architectures for both iPhone/iPad device and simulator separately and combine them into one binary.
    xcodebuild -project libmysql.xcodeproj -target mysqlclient -configuration Release -sdk iphonesimulator3.1.3 ONLY_ACTIVE_ARCH=NO ARCHS=i386 PRODUCT_NAME=mysqlclient_simulator
    
    xcodebuild -project libmysql.xcodeproj -target mysqlclient -configuration Release -sdk iphoneos3.1.3 ONLY_ACTIVE_ARCH=NO ARCHS="armv6 armv7" PRODUCT_NAME=mysqlclient_device
    
    lipo ./libmysql/Release/libmysqlclient_simulator.a ./libmysql/Release/libmysqlclient_device.a -create -output ./libmysql/Release/libmysqlclient.a
    

The build result should be at libmysql/Release/libmysqlclient.a

Similarly, build a dylib to target 10.5. The mmacosx-version-min is required, otherwise, you’ll get unknow load command on 10.5. Don’t forget set the @executable_path

xcodebuild -project libmysql.xcodeproj -target libmysql -configuration Release -sdk macosx10.5 -mmacosx-version-min=10.5 ONLY_ACTIVE_ARCH=NO ARCHS="ppc i386 x86_64"

Subversion repository on shared hosting and connect to it from Xcode

June 23rd, 2010
Setup SSH access
  1. Go to the cPanel “Manage SSH Keys”, click the “Generate Key” button to generate a pair of keys.
  2. Go back in the “Manage SSH Keys”, Authorization the public key you just generated and download the private key to your local machine.
  3. Let’s say, we want to name the private key file “.id_rsa”. So, copy the download file to “~/.ssh/.id_rsa” and set correct permission on it.
    chmod 400 ~/.ssh/.id_rsa
  4. Connect from the Terminal to verify it works.
    ssh username@www.iosplace.com -i .ssh/.id_rsa

Install subversion on the server

I’m using InMotionHosting. Their business hosting plan on edge server has subversion installed. Another so called “developer friendly” hosting company that I know is A2 hosting. BlueHost, MonsterHost and GoDaddy are few that I know people have success installed subversion on them.

Create subversion repositories

Suppose I want to layout my repositories like this: ~/svn/repo1/project1, ~/svn/repo1/project2, ~/svn/repo2/project3, …, This is what I do after ssh logon to my server in Terminal:

mkdir svn
svnadmin create svn/repo1

Setup Xcode

  1. Select SCM->Configure SCM Repositories…, go to the SSH tab. You should see the private key file is listed there. If it’s not authorized, type the passphase (the one you typed when generate the key pair) to authorize it.
  2. In the Repositories tab, you should configure it similar to this:
  3. If you’re not sure about the path, type pwd in the Terminal which should print out your path.
  4. Select SCM->Repositories, and select the repository you just configured, the ‘project1′ directory should be listed there. Now you can import your source files into the repository.
  5. To obtain a working copy, select Checkout in the above Repositories dialog.
  6. Now open the Xcode project file you’ve checked out. If it’s SCM not configured, select menu Project->Edit Project Settings…, in the General tab, click “Configure Roots & SCM…”.