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.
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.
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.
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 |
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 |
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