2009-03-24 4 views
1

J'écris un contrôleur pour un serveur audio sur l'iPhone. Chaque 'vue' doit généralement obtenir des données de la socket TCP/IP en tant que client. J'ai des sockets travaillant à partir d'une classe en utilisant la classe AsyncSocket. (Qui, après avoir essayé d'obtenir un socket client travaillant pour plus de temps que je voudrais admettre, est une classe très impressionnant et utile) .. Cela nécessite des fonctions de délégué à écrire pour recieving données ...iphone SDK: socket client ... comment gérer le délégué de données de réception à travers différentes vues/classes?

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag 

J'ai une interface de vue de tableau standard où je vois une liste d'artistes sur une vue, puis quand un artiste est sélectionné je passe aux albums sur la vue suivante et ainsi de suite.

Ma question est la suivante: Quand est-ce que je passe d'une vue à l'autre, quelle est la meilleure façon d'envoyer et de recevoir des données? Ai-je besoin de créer un nouveau socket pour chaque classe de vue? (semble un peu plus haut) Relier le délégué du récepteur local à nouveau? Je ne peux pas sembler penser à la «bonne» manière de faire fonctionner ceci en dehors de la classe 1 et il n'y a pas beaucoup en ligne au sujet des communications de client de douille sur l'iphone.

Répondre

2

Il semble que vous souhaitiez que les méthodes déléguées soient reçues par plusieurs objets, n'est-ce pas? Sur Mac OS X, la solution consiste à utiliser le système de notification. Je n'ai pas regardé la classe AsyncSocket, mais on dirait qu'elle ne supporte qu'un délégué hors de la boîte.

Les notifications sont excellentes car elles permettent à un objet de diffuser des informations à tous les autres objets qui souhaitent le recevoir. Les objets s'enregistrent auprès du centre de notification pour être notifiés lorsque des notifications particulières sont publiées. Vous pouvez très facilement ajouter cette fonctionnalité en implémentant votre propre classe pour envelopper AsyncSocket.

Voici ce que vous feriez. Vous écririez votre propre classe qui a une AsyncSocket en tant que variable d'instance. Vous devez définir cette classe en tant que délégué pour l'objet AsyncSocket. Ensuite, lorsque les méthodes de délégué sont appelées, vous devez publier des notifications au NSNotificationCenter. Vous devrez probablement insérer les paramètres des méthodes déléguées dans le dictionnaire userInfo de la notification. D'un autre côté, vos contrôleurs de vue s'inscrivent avec le NSNotificationCenter en tant qu'observateurs pour les notifications envoyées par votre classe personnalisée. Ensuite, chaque fois que les méthodes déléguées sont déclenchées, chaque contrôleur de vue reçoit une notification de cet événement.

Assez parlé; voici un code:

extern NSString *const AsyncSocketDidReadData; 

@interface MySocketWrapper : NSObject { // give this class a better name ;-) 
    AsyncSocket *socket; 
} 

@property (nonatomic, readonly) socket; 

@end 

Dans le fichier .m:

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 

Enfin, dans vos différents contrôleurs de vue, vous pouvez écrire du code comme ceci:

- (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 
} 

De toute évidence, ce code n'est pas entièrement terminée, et j'ai peut-être mal compris certains noms de méthodes (je le fais de mémoire) mais c'est une solution qui devrait fonctionner pour vous.

+0

Voici la référence à NSNotificationCenter: https://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/index.html – Alex

+0

Je ne pense pas que l'ajout de cette logique à un ViewController est une bonne idée. – RSully

0

La réponse précédente est bonne mais "notification:" dans l'extrait de contrôleur de vue doit être "nom:".

Questions connexes