It sounds like you want to have the delegate methods received by multiple objects, right? On Mac OS X, the solution is to use the notification system. I haven't looked at the AsyncSocket
class, but it looks like it only supports a delegate out of the box.
Notifications are great because they let an object broadcast information to any other objects that are interested in receiving it. Objects register themselves with the notification center to be notified when particular notifications are posted. You could very easily add this capability by implementing your own class to wrap AsyncSocket
.
Here's what you'd do. You'd write your own class that has an AsyncSocket
as an instance variable. You would set this class as the delegate for the AsyncSocket
object. Then, when the delegate methods get called, you would post notifications to the NSNotificationCenter
. You'll probably need to stuff the parameters from the delegate methods into the notification's userInfo
dictionary.
On the flip side, your view controllers would sign up with the NSNotificationCenter
as observers for the notifications your custom class sends. Then, every time the delegate methods fire, each view controller will receive a notification of that event.
Enough talk; here's some code:
extern NSString *const AsyncSocketDidReadData;
@interface MySocketWrapper : NSObject { // give this class a better name ;-)
AsyncSocket *socket;
}
@property (nonatomic, readonly) socket;
@end
In the .m file:
NSString *const AsyncSocketDidReadData = @"AsyncSocketDidReadData";
@implementation MySocketWrapper
@synthesize socket;
- (id)init {
if (![super init]) return nil;
socket = [[AsyncSocket alloc] init]; // initialize this however you want
[socket setDelegate:self];
return self;
}
- (void)onSocket:(AsyncSocket *)aSocket didReadData:(NSData *)data withTag:(long)tag {
NSDictionary *userInfo =
[NSDictionary dictionaryWithObjectsAndKeys:
data, @"data",
[NSNumber numberWithLong:tag], @"tag",
nil];
[[NSNotificationCenter defaultCenter] postNotificationName:AsyncSocketDidReadData object:self.socket userInfo:userInfo];
}
@end
Finally, in your various view controllers, you can write code like this:
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle {
if (![super initWithNibName:nibName bundle:bundle]) return nil;
// Do any initalization you need here
// Note that if you specify 'nil' for object, you'll be sent notifications for every MySocketWrapper object.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(asyncSocketDidReadData:) notification:AsyncSocketDidReadData object:nil];
return self;
}
- (void)asyncSocketDidReadData:(NSNotification *)notification {
AsyncSocket *socket = [[notification object] socket];
NSData *theData = [[notification userInfo] objectForKey:@"data"];
long tag = [[[notification userInfo] objectForKey:@"tag"] longValue];
// Do what you want with the data here
}
Obviously, this code isn't entirely complete, and I may have gotten some method names wrong (I'm doing this from memory) but this is a solution that should work for you.