In honor of Objective-C becoming a top-ten language, I’ve decided to share a library of source code I created to access MySQL.
Update: A newer post has a version of this library that works on the iPhone as well.
Over the past 2 years I’ve worked on a small bit of glue to make selects, updates, inserts and deletes work easily from Objective-C. This includes support for converting MySQL types to Cocoa types, working correctly with garbage collection, and support for reading and writing large blobs.
It is possible to do all these things with the generic MySQL C connector, and if your needs are simple that can be a quick way to access a MySQL databases, since all C libraries can easily be called from Objective-C. However, once you start dealing with more advanced topics, the C connector can become burdensome.
If you are working on intel platforms only, you should grab the intel only version. This supports both 32 and 64 bit intel platforms, using version 6.0.2 of the MySQL C Connector.
ObjC_mysql_intel.zip 5.5 MB – 32/64 bit
I still have some client programs running on PPC boxes, but MySQL has dropped support for PPC based OSX in the most recent versions of the mysql_connector. So I have an older version that I occasionally update, although not as often as the intel only version. This version uses an older version (5.0.51a) of the MySQL C connector, and supports both 32 bit PPC and Intel platforms.
ObjC_mysql_ppc.zip 2.3 MB – 32 bit intel and PPC.
Both versions use an identical syntax and are for the most part interchangeable.
Both require that garbage collection be enabled in your application. This means this version won’t support versions of iPhone OS that don’t include garbage collection. Which is pretty much all of them, as of the writing of this post.
Both include the headers and a static library for the MySQL C connector.
While I have used these libraries to process well over half a billion rows of MySQL data, they are not by any means guaranteed to be free of bugs. The most recent fix was a leak in MysqlUpdate. If you are interested in getting updates, subscribe to the MySQL Category Feed, or email me for access to the subversion repository for the project.
Adding to Your Project
Once you have extracted the zip, add everything inside to your project. The static mysql library will be linked into your application, and the headers and all the necessary bits to compile should just fall into place.
Forming the connection
You connect by creating an instance of MysqlConnection. The best method for starting is
+ (MysqlConnection *)connectToHost:(NSString *)host
user:(NSString *)user
password:(NSString *)password
schema:(NSString *)schema
flags:(unsigned long)flags;
The best option for flags is MYSQL_DEFAULT_CONNECTION_FLAGS
If you are connecting to a MySQL server that will kick you if inactive, call the method
-[MysqlConnection startIdle]
to start a low impact periodic select that will run once every 60 seconds. Four additional methods add support for transactions
Performing Selects
Selects are pretty straight forward. Use MysqlFetch, and pass a SQL select command. You can then look at the results property to get an array of dictionaries. Each dictionary represents a single row. They key will be the name of each column, and the value will be the Objective-C type that matches the column. If you aren’t sure of the names of the fields, you can look at the fields an fieldNames properties for more details.
Example:
MysqlConnection *connection = [MysqlConnection connectToHost:@"serverName"
user:@"aUserName"
password:@"aPassword"
schema:@"myForumName"
flags:MYSQL_DEFAULT_CONNECTION_FLAGS];
MysqlFetch *userFetch = [MysqlFetch fetchWithCommand:@"select U_Number,U_Username from w3t_Users"
onConnection:connection];
QLog(@"There are %d members",[userFetch.results count]);
for (NSDictionary *userRow in userFetch.results) {
NSNumber *userNumber = [userRow objectForKey:@"U_Number"];
NSString *userName = [userRow objectForKey:U_Username"];
NSLog("%@ %@",userNumber,userName);
}
Performing Deletes
Deletes, inserts, and updates are very similar. To perform a delete:
MysqlDelete *deleteCommand = [MysqlDelete deleteWithConnection:connection]; delete.tableName=@"w3t_Users"; delete.qualifier=[NSDictionary dictionaryWithObject:@"3" andKey:@"U_Number"]; [deleteCommand execute];
You can then look at the affectedRows property to find out how many rows were deleted.
Performing Inserts
Inserts allow you to insert NSString, NSNumber, NSData, and NSNull. All other classes are converted using their -description method. The insert code uses bindings instead of composing a SQL string, so you don’t need to worry about escaping special characters, or filtering user input.
MysqlInsert *insertCommand = [MysqlInsert insertWithConnection:connection];
insertCommand.table =@"w3t_Users";
NSData *picture = [NSData dataWithContentsOfFile:@"sample.png"];
NSString *password=@";'!#";
insertCommand.rowData=[NSDictionary dictionaryWithObjectsAndKeys:@"Karl Kraft",@"U_Username",
picture,@"U_UserImage"
password,@"UserPassword"
nil];
[insertCommand execute];
After the insert, you can get the auto increment rowid by using the rowid property on your MysqlInsert instance.
Performing Updates
Once you have mastered delete and insert, updates are a simple cross of the two. Specify a qualifier, like you would for deletion, but rowData like you would use for an insert. Only the specified fields in the rowData are modified. Again you can pass NSString, NSNumber, NSData, and NSNull, and the values are inserted using bindings so that you don’t need to provide odd escapes.
MysqlUpdate *updateCommand = [MysqlInsert insertWithConnection:connection];
updateCommand.table =@"w3t_Users";
updateCommand.qualifier=[NSDictionary dictionaryWithObject:@"3" andKey:@"U_Number"];
NSData *picture = [NSData dataWithContentsOfFile:@"sample.png"];
NSString *password=@";'!#";
updateCommand.rowData=[NSDictionary dictionaryWithObjectsAndKeys:@"Karl Kraft",@"U_Username",
picture,@"U_UserImage"
password,@"UserPassword"
nil];
[updateCommand execute];
Like delete you can query the affectedRows property to find out how many records were updated.
Catching exceptions
Any exceptions while performing the mysql commands are thrown as MysqlException or a subclass of MysqlException. Common reasons for exceptions being throw are:
- Unable to connect to the database, or wrong username / password
- Commit or rollback fails
- Unsupported field type in a MysqlFetch
- Unqualified delete or update commands
- Any underlying mysql error
MYSQL_LOGGING
As a final useful trick you can define MYSQL_LOGGING in the CFLAGS of your project, or in a common header file, and useful debugging information will be generated.

One Comment
Nice work.
You have a typo in the insert code:
[NSDate dataWithContentsOfFile:@"sample.png"];
Should be NSData…
[Karl - Thanks I do that in real life as well]