Getting started

This guide will walk you through creating an application that uses Thrift with a Java server and a client written in Objective-C. It is assumed that you will have a basic knowledge of Objective-C and Xcode to complete this tutorial.

Requirements

Make sure that your system meets the requirements as noted in ThriftRequirements

The following are required for the Java server; but, not the Objective-C client.

Building Thrift cocoa as a framework

It is relatively straight forward to build the thrift cocoa library sources as a framework. As of Thrift 0.2.0 this is not done automatically. Hopefully it will in future releases.

  1. Download Thrift 0.2.0 and install. Follow the instructions at ThriftInstallationMacOSX to install on Mac OS X. 2. Download the Thrift.framework project for XCode ThriftFramework.zip 3. Open the Xcode project file and compile.

Creating the Thrift file

We will use the sample thrift file described on the main page of the Thrift project.

struct UserProfile {
  1: i32 uid,
  2: string name,
  3: string blurb
}
service UserStorage {
  void store(1: UserProfile user),
  UserProfile retrieve(1: i32 uid)
}
thrift --gen java profile.thrift
thrift --gen cocoa profile.thrift

Creating the Java Server

import org.apache.thrift.TException;
import java.util.HashMap;

class UserStorageImpl implements UserStorage.Iface {
    private HashMap<Integer, UserProfile> profiles;

   public UserStorageImpl() {
       profiles = new HashMap<Integer, UserProfile>();
   }

   @Override
   public void store(UserProfile user) throws TException {
       long time = System.currentTimeMillis();
       System.out.println("store() called: " + time);
       System.out.println("UID: " + user.uid);
       System.out.println("Name: " + user.name);
       System.out.println("Blurb: " + user.blurb);
       profiles.put(new Integer(user.uid), user);
    }

    @Override
    public UserProfile retrieve(int uid) throws TException {
        return profiles.get(new Integer(uid));
    }
}
import java.io.IOException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TBinaryProtocol.Factory;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;

public class Server {

    private void start() {
        try {
            TServerSocket serverTransport = new TServerSocket(7911);
            UserStorage.Processor processor = new UserStorage.Processor(new UserStorageImpl());
            Factory protFactory = new TBinaryProtocol.Factory(true, true);

            TServer server = new TThreadPoolServer(processor, serverTransport, protFactory);

            System.out.println("Starting server on port 7911 ...");
            server.serve();
        } catch (TTransportException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String args[]) {
        Server srv = new Server();
        srv.start();
    }
}
javac *.java
java Server

Create the Objective-C client

The objective-c client is a simple cocoa application that allows the user to fill out the values of a UserProfiel structure and store/retrieve them from the server.

#import <TProtocol.h>
#import <TApplicationException.h>
#import <TProtocolUtil.h>
#import <TProcessor.h>

to

#import <Thrift/TProtocol.h>
#import <Thrift/TApplicationException.h>
#import <Thrift/TProtocolUtil.h>
#import <Thrift/TProcessor.h>
#import <Cocoa/Cocoa.h>

#import <Thrift/TSocketClient.h>
#import <Thrift/TBinaryProtocol.h>

#import "profile.h"

@interface ThriftCocoaAppDelegate : NSObject <NSApplicationDelegate> {
  NSWindow *window;
  NSTextField *uid;
  NSTextField *name;
  NSTextField *blurb;
  
  TSocketClient *transport;
  TBinaryProtocol *protocol;
  UserStorageClient *service;
}

@property (assign) IBOutlet NSWindow *window;
@property (assign) IBOutlet NSTextField *uid;
@property (assign) IBOutlet NSTextField *name;
@property (assign) IBOutlet NSTextField *blurb;

- (IBAction)store:(id)sender; // call thrift service store function.
- (IBAction)retrieve:(id)sender; // call thrift service retrieve function.

@end

5. Open the XIB file in Interface builder and drag out 3 NSTextField objects. Connect these to the uid, name, and blurb outlets.
6. Drag out 2 buttons. Label the first as 'Store' and connect it to the store action. Label the other as retrieve and connect it to the retrieve action.
7. Copy the following code into the app delegate implementation file (the .m file)

#import "ThriftCocoaAppDelegate.h"
#import "profile.h"


@implementation ThriftCocoaAppDelegate

@synthesize window;
@synthesize uid;
@synthesize name;
@synthesize blurb;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
  // Talk to a server via TCP sockets, using a binary protocol
  transport = [[TSocketClient alloc] initWithHostname:@"localhost" 
                                                 port:7911];
  protocol = [[TBinaryProtocol alloc] initWithTransport:transport 
                                             strictRead:YES 
                                            strictWrite:YES];
  
  // Use the service defined in profile.thrift
  service = [[UserStorageClient alloc] initWithProtocol:protocol];
}

- (void)store:(id)sender {
  NSLog(@"Called store.");
  // Make an object
  UserProfile *up = [[UserProfile alloc] initWithUid:[[uid stringValue] intValue]
                                                name:[name stringValue]
                                               blurb:[blurb stringValue]];
  
  // call the store function on the service
  [service store:up];
}

- (void)retrieve:(id)sender {
  NSLog(@"Called retrieve.");
  // Retrieve something as well
  UserProfile *up = [service retrieve:[[uid stringValue] intValue]];
  NSLog(@"Received User Profile: %@", up);
  [uid setStringValue:[NSString stringWithFormat:@"%d", [up uid]]];
  [name setStringValue:[up name]];
  [blurb setStringValue:[up blurb]];
}

@end

You can download the Xcode project for this step: ThriftObjectiveCClient.zip