Design with iPhone Project 8: Networking

Warning:
Content of this website may change at any time up until class meeting.

Project Topics


Preparation


Create a new iOS app in Xcode

p1fig-IosView.jpg
Fig. 1
p1fig-projWin1.jpg
Fig. 2 Xcode Workspace Window





Bluetooth Networking

p8fig-bluetoothGui.jpg
Fig. 3

@interface project8tpwViewController : UIViewController {  
    UITextField *myTextField;
    UITextView *myTextView;
}
@property (nonatomic, retain) IBOutlet UITextField *myTextField;
@property (nonatomic, retain) IBOutlet UITextView *myTextView;
- (IBAction)myGkPickButton:(id)sender;
- (IBAction)mySendButton:(id)sender;
- (IBAction)resignTextFieldKeyboard:(id)sender;
@end
- (IBAction)resignTextFieldKeyboard:(id)sender {
    [myTextField resignFirstResponder];
}




The PeerPicker
#import <UIKit/UIKit.h>
#import <GameKit/GameKit.h>                                             //tpw gkpick
@interface project8tpwViewController : UIViewController
<GKPeerPickerControllerDelegate, GKSessionDelegate, UIAlertViewDelegate> //tpw gkpick
{
    UITextField *myTextField;
    UITextView *myTextView;
    GKSession       *gameSession;                                           //tpw gkpick
    NSString        *gamePeerId;                                             //tpw gkpick
    UIAlertView     *connectionAlert;                                   //tpw gkpick
}
@property (nonatomic, retain) IBOutlet UITextField *myTextField;
@property (nonatomic, retain) IBOutlet UITextView *myTextView;
- (IBAction)myGkPickButton:(id)sender;
- (IBAction)mySendButton:(id)sender;
- (IBAction)resignTextFieldKeyboard:(id)sender;
@property(nonatomic, retain) GKSession   *gameSession;                //tpw gkpick
@property(nonatomic, copy)   NSString    *gamePeerId;                  //tpw gkpick
@property(nonatomic, retain) UIAlertView *connectionAlert;         //tpw gkpick
- (void)endSession:(GKSession *)session;                             //tpw gkpick
- (void) mySendDataToPeers: (NSData *) data;                            //tpw gkpick
@end

@synthesize gameSession;                //tpw gkpick
@synthesize gamePeerId;                 //tpw gkpick
@synthesize connectionAlert;            //tpw gkpick

- (IBAction)myGkPickButton:(id)sender {                     //tpw gkpick
    GKPeerPickerController*     picker;   
    picker = [[GKPeerPickerController alloc] init];     picker.delegate = self;
    picker.connectionTypesMask = GKPeerPickerConnectionTypeNearby ;
    [picker show];
}

p8fig-gameKitLib.jpg
Fig. 4

p8fig-appSim1.jpg
Fig. 5

- (void)peerPickerController:(GKPeerPickerController *)picker didSelectConnectionType:(GKPeerPickerConnectionType)type {
    if (type == GKPeerPickerConnectionTypeOnline) {
        picker.delegate = nil;
        [picker dismiss];
        [picker autorelease];
        // Implement your internet interface here.
    }
}

- (GKSession *)peerPickerController:(GKPeerPickerController *)picker sessionForConnectionType:(GKPeerPickerConnectionType)type
{
    GKSession* session = [[GKSession alloc] initWithSessionID:@"tpwNet" displayName:nil sessionMode:GKSessionModePeer];
    return [session autorelease];
}

- (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession: (GKSession *) session {
    self.gamePeerId = peerID; 
    self.gameSession = session;
    self.gameSession.delegate = self;
    [self.gameSession setDataReceiveHandler:self withContext:nil];
    picker.delegate = nil;
    [picker dismiss];   
    [picker autorelease];
}

- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state {
    NSString *message;
    switch (state) {
        case GKPeerStateConnected: 
            self.gamePeerId = peerID; 
            break;
        case GKPeerStateDisconnected:
             message = [[NSString alloc ]stringWithFormat:@"Could not reconnect with %@.", [session displayNameForPeer:peerID]];
            if( self.connectionAlert && self.connectionAlert.visible) {
                self.connectionAlert.message = message;
            }
            else {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Lost Connection" message:message delegate:self cancelButtonTitle:@"End" otherButtonTitles:nil];
                self.connectionAlert = alert;
                [alert show];
                [alert release];
            }
            break;
        case GKPeerStateAvailable:
            break;
        caseGKPeerStateUnavailable:
            break;
        case GKPeerStateConnecting:
            break;
        default:
            break;        
    }
}

- (void)peerPickerControllerDidCancel:(GKPeerPickerController *)picker
{
    picker.delegate = nil;
    [picker autorelease];
    if(self.gameSession != nil)    {
        [self endSession:self.gameSession];
        self.gameSession = nil;
    }
}

- (void)endSession:(GKSession *)session {
     if(session != nil) {
        [session disconnectFromAllPeers];
        session.available = NO;
        [session setDataReceiveHandler: nil withContext: nil];
        session.delegate = nil;
    }
}


- (void)dealloc
{
    if(self.connectionAlert.visible) {
        [self.connectionAlert dismissWithClickedButtonIndex:-1 animated:NO];
    }
    self.connectionAlert = nil;
     [self endSession:self.gameSession];
    self.gameSession = nil;
    self.gamePeerId = nil;

    [myTextField release];
    [myTextView release];
    [super dealloc];
}
p8fig-appSim2.jpg
Fig. 6




-(IBAction)mySendButton:(id)sender {
    NSData* data;
    NSString *str = [NSString stringWithString:myTextField.text];
    data = [str dataUsingEncoding: NSASCIIStringEncoding];   
    if ([data length]>0)   
        [self mySendDataToPeers:data];
}

- (void) mySendDataToPeers: (NSData *) data
{
    if((self.gameSession != nil) && ([data length] >0) )
    {
        [self.gameSession sendDataToAllPeers: data withDataMode: GKSendDataReliable error: nil];
    }
    else
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Send Error" message:@"Cant send until a network is established." delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil];
        self.connectionAlert = alert;
        [alert show];
        [alert release];
    }
}

- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context {
    if([data length] >0)
    {
        NSString* str1;
        NSString* str2;
        str1 = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
        str2 = [[NSString alloc] initWithFormat:@"%@: %@ \n", session.displayName,str1] ;
        NSLog(@"%@: %@ \n", session.displayName, str1);
        myTextView.text=[ str2 stringByAppendingString: myTextView.text];  
        [str1 release];
        [str2 release];
    }
}

p8fig-appSim3.jpg
Fig. 7

    picker.connectionTypesMask = GKPeerPickerConnectionTypeNearby | GKPeerPickerConnectionTypeOnline;


p8fig-appSim4.jpg
Fig. 8




Other Networking Resources




Demonstration



Report



Copyright 2011 by T.P. Weldon


Apple, iPhone, iPad, and Xcode  are registered trademarks of Apple Inc.