Sunday, April 21, 2013

Sending files with XMPPFramework and TurnSockets

This is a short example about how to send files from Objective-C applications via XMPP. For that I use the XMPP client library XMPPFramework and it's TURNSocket class (a XEP-0065: SOCKS5 Bytestreams implementation).

This code solely handles actual file sending. It assumes an established XMPP connection. myJid is the JID the application uses for connection to the XMPP server. Below you find the the methods needed for sending of files via XMPP. You actually just have to call the sendToOtherDevice method from your code.

- (void)sendToOtherDevice:(NSData *)fileData receiverJid:(NSString *)receiverJid {    
    XMPPJID *jid = [XMPPJID jidWithString:receiverJid];
    if ([jid.domain isEqualToString:myJid.domain]) {
        [TURNSocket setProxyCandidates:[NSArray arrayWithObjects:jid.domain, nil]];
    } else {
        [TURNSocket setProxyCandidates:[NSArray arrayWithObjects:jid.domain, myJid.domain, nil]];
    DataAwareTurnSocket *socket = [[DataAwareTurnSocket alloc] initWithStream:xmppStream toJID:jid];
    [socket setDataToSend:fileData];
    [socket startWithDelegate:self delegateQueue:dispatch_get_main_queue()];

- (void)turnSocket:(DataAwareTurnSocket *)sender didSucceed:(GCDAsyncSocket *)socket {
    [socket writeData:sender.dataToSend withTimeout:60.0f tag:0];
    [socket disconnectAfterWriting];

- (void)turnSocketDidFail:(TURNSocket *)sender {
    NSLog(@"Couldn't set up bytestream for file transfer!");

DataAwareTurnSocket is a TURNSocket subclass which holds a reference to the file which shall be transmitted via XMPP. Its header class looks like this:

#import "TURNSocket.h"

@interface DataAwareTurnSocket : TURNSocket {
    NSData *dataToSend;

@property (nonatomic, readwrite) NSData *dataToSend;


The actual implementation is also fairly simple (it actually consists of no real code^^):

#import "DataAwareTurnSocket.h"

@implementation DataAwareTurnSocket

@synthesize dataToSend;


Keep in mind, that I'm a Objective-C beginner and the code might be not optimal. However it should give you a hint of how to accomplish sending a file via XMPP from Objective-C code.