reader = [FileReader new];we now ask the gnustep-base library to give us the object registered with the name FileReader on a remote machine:
reader = (id <FileReader>)[NSConnection rootProxyForConnectionWithRegisteredName: @"FileReader" host: @""];strictly speaking, reader is a local proxy to the remote object - but the whole thing is made so that you can forget about this distinction, and think of reader simply as the remote object. Using an empty string for the host argument means that gnustep-base will look for an object registered with name FileReader on the local host; if you know the host on which you want to access the FileReader object, you should better use your specific host name, such 192.168.29.1.
We need a cast to id <FileReader> because the call to NSConnection returns a generic object, while we know the FileReader object implements getFile:. A more robust application could check at execution time that the remote object in the server actually can respond to getFile: messages before doing the cast (for example by using the method respondsToSelector:); we skip this little complication in this first example.
But we need to check that we have a real reader object - if it is nil, it is because for some reason the gnustep-base library couldn't connect to an object registered as FileReader on the network. Usually this is because the server is not running; there is nothing we can do in the client in these cases, so we simply print an error message and exit.
As promised, the rest of the function is unchanged; in particular, when we send the getFile: method to the remote object, that starts a network connection to the server, and returns the result - but the nice thing is that we don't need to do anything special to perform this remote call: we just call the method normally, as if the object were our old friendly local object.
Here is the source code:
#include <Foundation/Foundation.h> /* This tells us how the reader object behaves */ @protocol FileReader - (NSString *)getFile: (NSString *)fileName; @end int main (void) { NSAutoreleasePool *pool; NSArray *args; int count; id <FileReader> reader; NSString *filename; NSString *file; pool = [NSAutoreleasePool new]; /* Create our FileReader object */ reader = (id <FileReader>)[NSConnection rootProxyForConnectionWithRegisteredName: @"FileReader" host: @""]; if (reader == nil) { NSLog (@"Error: could not connect to server"); exit (1); } /* From now on the code is the same, whether reader is in the local process or in a remote one */ /* Get program arguments */ args = [[NSProcessInfo processInfo] arguments]; /* the first string in args is the program name; get the second one if any */ if ([args count] == 1) { NSLog (@"Error: you should specify a filename"); exit (1); } filename = [args objectAtIndex: 1]; /* Ask the reader object to get the file */ file = [reader getFile: filename]; /* If the reader object could get the file, show it */ if (file != nil) { printf ("%s\n", [file lossyCString]); } else { NSLog (@"Error: could not read file `%@'", filename); exit (1); } return 0; }