0

I have tried going through this Question: How Does A Delegate Work and I still don't seem to have a full grasp on it. I am trying to use the CocoaAsyncSocket library to create a TCP socket connection. Thanks to help from a very friendly SO user, I have the following code to perform a read data request to the server:

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    NSData *strData = [data subdataWithRange:NSMakeRange(0, [data length])];
    NSString *msg = [[NSString alloc] initWithData:strData encoding:NSUTF8StringEncoding];
    if(msg)
    {
        NSLog(@"RX:%@",msg);
    }
}

Now, forgive my ignorance as I'm pretty new to iOS development. So now I have this method that I want to invoke which will perform my ReadData. The problem is, I do not know WHERE to put this method (I have several views, with several header/implementation files). I want this method to be a delegate method, but I do not know how to make it a delegate method. I want to invoke this delegate method from my view.

If anyone could explain:

  • Where do I put this code? (What file, etc)
  • How do I make this a delegate method?
  • How do I invoke this delegate method?

I've been stuck on this all day, and I'm about to throw it the towel lol. Any and all help is much appreciated. Thanks so much!

EDIT:

This is kind of a bridge from a previous question, but I don't think that question has too much relevance to this question. Question

Community
  • 1
  • 1
Skizz
  • 1,211
  • 5
  • 17
  • 28
  • Just for clarification, you want to call this method, pass in the parameters, and get msg back as the return value? – Sierra Alpha Jun 05 '12 at 20:24
  • This is a function that is part of the CocoaAsyncLibrary. I Edited my Question above, as this question is kind of a bridge from my first. I don't think any of the details in my first question are relevant, however. – Skizz Jun 05 '12 at 20:30

3 Answers3

0

Thanks for updating. It is now clearer. Here are some answers. If it is not clear, please let me know.

- Where do I put this code? (What file, etc)

This is a delegate method of CocoaAsyncSocket. Back to your first question, when you initialized it, you set yourself (your appDelegate) as the delegate.

socket = [[AsyncSocket alloc] initWithDelegate:self];

That means, you will be called from another class. So that means this method should be in the same class where you initialized the object (here socket) and set it as the delegate. So it stays in appDelegate

- How do I make this a delegate method?

You don't. This is a delegate method itself.

- How do I invoke this delegate method?

You don't. Another class (here AsyncSocket) will invoke it.

You may now ask, how you pass the data to your viewControllers? That depends on your design. Once this method is called and you get notified that there is a connection, and data is being read, depending on your design, you pass the data to other view controllers. One way is by using NSNotification. e.g.

// Call this in onSocket:didReadData:withTag: instead of logging
[[NSNotificationCenter defaultCenter] postNotificationName:@"DataIsReadNotification" object:msg]



// In one of your view controllers
// View controllers insterested in this message, register to get notified:
// add to -viewDidLoad
[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateViewWithNotification:) name:@"DataIsReadNotification" object:nil];
...
// and somewhere in the view controller class implement this
- (void)updateViewWithNotification:(NSNotification *)notification {
NSString *msg = [notification object];
}
Sierra Alpha
  • 3,707
  • 4
  • 23
  • 36
  • This is an excellent description. I understand this much better now. I have placed my method onSocket:didReadData:withTag: method in my appDelegate. I do not see anything in my NSLog from the readData, but that could be because there is no data ready to be read from the server side (Another person is working on the server side application). Thanks again for the help! – Skizz Jun 06 '12 at 14:24
  • Using the debug mode, I stepped through my code and realized that this method (onSocket:didReadData:withTag:) is not even getting called. As I stated, all I did was simply add my add the onSocket:didReadData:withTag: method to the bottom of my appDelegate.m file. I don't know if you use Skype, but you can reach me at CaffeineWakeUp if you're a Skype user. It looks like I'm really close to getting this squared away. Thanks! – Skizz Jun 06 '12 at 14:45
  • Through some digging, I think I was able to figure it out. I'm going to keep working through it and if I get into trouble I'll create a new question. It looks like I'm getting the hang of invoking the methods. Thanks again for all the help! – Skizz Jun 06 '12 at 15:06
  • Glad that it was helpful. The reason `onSocket:didReadData:withTag:` method doesn't get called, is probably because your `appDelegate` has not adopted the delegation. If so, in `appDelegate.h`, you should add `` at the end of the line of `@interface`. The concept and idea is exactly the same as `UITableViewDataSource` or `UITableViewDelegate`. You can always send me an email too. – Sierra Alpha Jun 06 '12 at 18:07
0

I am not familiar with the - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag method but using delegate in iOS is very common way to have your objects communicate between each others without introducing some dependencies.

Here are few hints to answer your 3 bullets questions:

Where do I put this code?

The best bet will be within the controller you want your ReadData to be performed or in the appDelegate

How do I make this a delegate method?

If this method has been defined in a protocol this is already by definition a delegate method. You just need to have your viewcontroller class to conform to this protocol and make your controller the delegate for this method.

How do I invoke this delegate method

You don't invoke a delegate method. You have an other object that belongs to this CocoaAsyncSocket library which will make a call to this delegate method. You simply take care of handling some code within the delegate method for your controller because you have defined it as the object who will handle this method.

Just see a delegate as a way to defer some work to an other object (it is a design pattern btw)

tiguero
  • 11,477
  • 5
  • 43
  • 61
0

To make a delegate you would declare that stuff in the header file. Example below.

//SomeClass.h

@protocol SomeClassDelegate <NSObject>
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
@end


@interface SomeClass : NSObject {

id<SomeClassDelegate>delegate;

}
@property(nonatomic,assign)id<SomeClassDelegate>delegate;
@end

Now when you initialize SomeClass, you can set the delegate to whatever self is. Now In your SomeClass file, you can do

[self.delegate onSocket: .. didReadData: .. withTag:];

If the method exists in the class you set as the delegate to SomeClass, it will call it. Hope this helps.

skram
  • 5,314
  • 1
  • 22
  • 26