title: Callbacks in ObjC+Cocoa
body: <p>I'm relatively new to Cocoa/ObjC. Could someone please help me change my code to use asynchronous network calls? Currently it looks like this (fictional example):</p>
  
  <pre><code>// Networker.m
  -(AttackResult*)attack:(Charactor*)target {
      // prepare attack information to be sent to server
      ServerData *data = ...;
      id resultData = [self sendToServer:data];
      // extract and return the result of the attack as an AttackResult
  }
  
  -(MoveResult*)moveTo:(NSPoint*)point {
      // prepare move information to be sent to server
      ServerData *data = ...;
      id resultData = [self sendToServer:data];
      // extract and return the result of the movement as a MoveResult
  }
  
  
  -(ServerData*)sendToServer:(ServerData*)data {
      // json encoding, etc
      [NSURLConnection sendSynchronousRequest:request ...]; // (A)
      // json decoding
      // extract and return result of the action or request
  }
  </code></pre>
  
  <p>Notice that for each action (attack, move, etc), the Networker class has logic to convert to and from ServerData. It is unacceptable to expect the other classes in my code to deal with this ServerData.</p>
  
  <p><strong>I need to make line A an asynchronous call.</strong> It seems that the correct way to do this is to use [NSURLConnection connectionWithRequest:...delegate:...] implementing a callback to do the post-processing. This is the only way I can think to do it:</p>
  
  <pre><code>//Networker.m
  -(void)attack:(Charactor*)target delegate:(id)delegate {
      // prepare attack information to be sent to server
      ServerData *data = ...;
      self._currRequestType = @"ATTACK";
      self._currRequestDelegate = delegate;
      [self sendToServer:data];
      // extract and return the result of the attack
  }
  
  -(void)moveTo:(NSPoint*)point delegate:(id)delegate {
      // prepare move information to be sent to server
      ServerData *data = ...;
      self._currRequestType = @"MOVE";
      self._currRequestDelegate = delegate;
      [self sendToServer:data];
      // extract and return the result of the movement
  }
  
  
  -(void)sendToServer:(ServerData*)data {
      // json encoding, etc
      [NSURLConnection connectionWithRequest:...delegate:self] // (A)
  }
  
  - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
      //json decoding, etc
      switch( self._currRequestType ) {
          case @"ATTACK": {...} // extract and return the result of the attack in a callback
          case @"MOVE": {...} // extract and return the result of the move in a callback
      }
  }
  </code></pre>
  
  <p>However, this is very ugly and not thread safe. <strong>What is the proper way to do this?</strong></p>
  
  <p>Thanks,</p>