Fork me on GitHub

While developing SoqlXplorer and SF3 it quickly became clear that Cocoa developers needed a quick and easy way to access the Salesforce.com SOAP API, zkSforce is the result. zkSforce is released under the uber liberal open source MIT license, and although not required, if you use zkSforce, it'd be nice to get a mention in your app's about dialog box. (this seems to be fairly standard policy for Mac apps). The latest version supports both OSX 10.9 and up, and iOS 9.0 and up

I originally planned to release zkSforce as a framework you embed into your application, however reading Wil Shipley's excellent blog post on frameworks - Frameworks are Teh Suck, Err convinced me otherwise. (BTW, if you've never read Wil's blog, its a great way to loose a weekend, regardless of if you're a Mac developer or not.) So in the zip file you'll find a bunch of classes just add these to your app and off you go. If you're remotely familiar with the Salesforce.com API then a glance at zkSforceClient.h will tell you everything you need to know.

What's with the ZK prefix? convention suggests that classes use a prefix to help reduce naming classes. I would of preferred SF, but Apple already snagged that one, so its ZK, which is short for Zak, my middle name (and nickname of Derby County's Kevin Hector)

What's supported?, zkSforce uses the v45.0 partner API, and can be used to access any Saleforce.com account that includes API access (such as Developer Edition, Enterprise Edition and Unlimited Edition logins). All of the Partner API is supported, including the various soap headers.

In general the client acts just like the API, however in a few places it has some smarts to make your life easier.

Usage is really straight forward, create an instance of the ZKSforceClient class, login, then call the other operations as needed, e.g.

ZKSforceClient *sforce = [[ZKSforceClient alloc] init];
[sforce login:username password:password
	failBlock:^(NSError *err) {
		[[NSAlert alertWithError:err] runModal];
	CompleteBlock:^(ZKLoginResult *result) {
		NSLog(@"Hello %@", result.userInfo.userFullName);
		[sforce describeSObject:@"Task"
			failBlock:^(NSError *err) {
				[[NSAlert alertWithError:err] runModal];
			CompleteBlock:^(ZKDescribeSObject *result) {
				NSLog(@"url for the new Task page is %@", [result urlNew]);	
ZKSObject *contact = [ZKSObject withType:@"Contact"];
[contact setFieldValue:@"Fell" field:@"LastName"];
[contact setFieldValue:@"Simon" field:@"FirstName"];
[sforce create:@[contact]
		failBlock:^(NSError *err) {
			[[NSAlert alertWithError:err] runModal];
		CompleteBlock:^(NSArray *result) {
	        ZKSaveResult *sr = result[0];
			if ([sr success])
				NSLog(@"new contact id %@", [sr id]);
				NSLog(@"error creating contact %@ %@", [sr statusCode], [sr message]);
As you can see, methods that call the Salesforce API endpoints are asynchronous with block based callbacks. By default callbacks are on the main thread/queue.

ZKSforceClient.h documents the core features of the client, in addition many of the API calls are contained in ZKSforceBaseClient+Operations.h

If you're not familiar with the web services API, you should start by reading the web services API documentation. If you're not familiar with Objective-C and/or Cocoa, then I'd recommend the Aaron Hillegass book Cocoa Programming for Mac OSX. There are also examples of using ZKSforce in the open source projects maildrop, sf3 & SoqlX.


You can now download the source code from its new home on GitGub.

Project setup

In order to support usage on both OSX & iPhone OS (so iPhone, iPod Touch, iPad), the library now uses libxml as its XML parser rather than NSXML, which isn't fully implemented on iOS. Once you've added all the .h & .m files to your project, you'll need to goto the build settings and add /usr/include/libxml2 to the Header Search Paths, and add libxml2.dylib to the linked frameworks section, and then you should be good to go. Also on OSX you'll need to add the Security.Framework to the list of frameworks to link against.

Alternatively you can use Cocoapods to automatically set this up for you.