Update (October 2011)
Opening and compiling the (original 3.1) OSCDemo project in Xcode 4.1 asks to 'modernize' it. Go ahead, modernize it.
For sending from the iOS device, also make sure to set the
sendiungToIP address, at line 40 of
OSCDemoViewController.m. For testing, also don't forget to set the IP address in
OSC Senderin the Quartz Composer patch.
Here's the
updated, Xcode 4.1 version of OSCDemo.
Update (April 2011)
Some users reported a problem where the transmission/reception speeds on newer hardware (iPhone 4, iPad) became unstable and "flaky". It seems that Bluetooth is causing some interference with OSC.
Solution: Make sure Bluetooth is off when you're using this code.
Thanks to
Hans Tutschku for finding this solution.
Sending data to and from the iPhone via OSC to applications on other machines should not be that difficult. Unfortunatly it's not as simple as it should be, but fortunalty Mr Ray (of VIDVOX fame) is so kind to share his code and his implementation of OSC for Objective-C.
There are some ancient libraries around, but let's better keep them buried where they are.
First a bit of an excursion on how to deal with external code on the iPhone.
Frameworks, Static Libraries or Inclusion?
Frameworks are the preferred method of distributing shared code on OSX. The idea behind being, that only one copy of the code can be shared amongst any number of applications. But at the iPhone true multi-tasking is not possible, so shared frameworks are not possible. Heck, they are even forbidden by Apple. But of course their own UIKit Frameworks are fine.
You could convert code for reuse to a Static Library, but with iPhone Dev you might deal with the simulator and the device, so you would need to either pre-compile the library for all plattforms or create a specific project, that compile the static library on demand. More on that at 519.
Frameworks are also nice, in that you only have to import them to your project and then they just work. Static Libraries need some special care, with header search paths, compiler flags, and of course putting them in a special place in ~/Library. That's fine if you develop on your own, but if you work with other people and share the code via a source code repository (like SVN), it might be difficult (or annoying) to maintain the same machine state across all the development machines.
So I resorted to including the classes directly into my project. That way they get compiled every time and I can poke around the code directly. If you really want a central source of your external classes, just don't add them to your project by copy but just by reference...
Sending OSC From the iPhone
Sending OSC data from the iPhone was always quite straightforward:
- (id) init {
NSLog(@"OSC init");
manager = [[OSCManager alloc] init];
[manager setDelegate:self];
// sending
NSString *sendingToIP = @"192.168.20.117";
int sendingToPort = 50000;
outPort = [manager createNewOutputToAddress:sendingToIP atPort:sendingToPort];
// receiving
int receivingOnPort = 51234;
//inPort = [manager createNewInput]; // default at port 1234
inPort = [manager createNewInputForPort:receivingOnPort];
return self;
}
Receiving OSC At the iPhone
The receiving part seems to catch many people out. Basically it's nothing more than set the right delegate, as specified in VVOSC:
// called by delegate on message
- (void) receivedOSCMessage:(OSCMessage *)m {
NSString *address = [m address];
OSCValue *value = [m value];
NSString *message;
if ([address isEqualToString:@"/mouseX"]) {
message = [NSString stringWithFormat:@"mouseX: %i", [value intValue]];
NSString *txt = [NSString stringWithFormat:@"%i", [value intValue]];
[receiveLabel performSelectorOnMainThread:@selector(setText:) withObject:txt waitUntilDone:NO];
} else if ([address isEqualToString:@"/mouseY"]) {
message = [NSString stringWithFormat:@"mouseY: %i", [value intValue]];
} else if ([address isEqualToString:@"/floatArray"]) {
message = [NSString stringWithFormat:@"floatArray: %f", [value floatValue]];
}
}
Change Notes
As VVOSC is targeted at both Cocoa and Cocoa Touch, there is a compiler directive that takes care of the switching. Or at least it should take care. I was unable to get the original code to run on the iPhone, because the compiler directive IPHONE was not recognized. I am sure I am missing something there...
To solve that, I change IPHONE (and !IPHONE) with TARGET_OS_IPHONE (and !TARGET_OS_IPHONE), and that did the trick.. And as this is going to be used for the iPhone only, I allowed myself the luxury of removing any code, that was not meant for execution on the iPhone OS.
Here's the original OSC demo Xcode 3.1-compatible project, hope it helps. Here's the newer, Xcode 3.2-compatible version (working with Xcode 4.1 on OSX 10.7). Drop me a line, if you have questions, suggestions or improvements.