Gamekit API

Discussion in 'iOS Programming' started by iPhoneSpain, Feb 16, 2010.

  1. iPhoneSpain macrumors newbie

    Joined:
    Sep 27, 2009
    #1
    Hello everyone!

    I would like to connect to iPhone via GameKit but without using GKPeerPickerController. I want to show in a tableView the peers who want to connect (or are already connected) to the session and then select the chosen ones to do something. The same that GKPeerPickerController implements but doing it in a TableView myself. At the beginning I only want the name of the peers available for connecting.

    The steps I follow below;


    1-Create the session

    GKSession *currentSession=[[GKSession alloc] initWithSessionID:mad:"test" displayName:mad:"XXX" sessionMode:GKSessionModePeer];

    2-Get available peers

    [currentSession peersWithConnectionState:GKPeerStateAvailable];

    No result...

    Any idea?

    Thank you
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    How long are you allowing between 1) and 2)? If it's no time at all or even a very short amount of time that's the result I'd expect. It takes time for other peers to discover and if appropriate connect. Personally I'd set up a thread in the background that refreshes every second or so whilst your picker is visible...
     
  3. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #3
    What session delegate methods have you implemented?
     
  4. iPhoneSpain thread starter macrumors newbie

    Joined:
    Sep 27, 2009
    #4
    Only GKSessionDelegate. Do I have to implement any other?
     
  5. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #5
    That is a protocol. Which methods in the protocol do you implement (or do you implement them all). Can we see all the delegate code?
     
  6. iPhoneSpain thread starter macrumors newbie

    Joined:
    Sep 27, 2009
    #6
    I am a bit newbie so sorry if you see that this is basic stuff. Here is what I implement for testing:

    Code:
    - (void)viewDidLoad {
        
    
    	peers=[[NSMutableArray alloc] init];
    		
    	currentSession=[[GKSession alloc] initWithSessionID:@"session1" displayName:@"Hello" sessionMode:GKSessionModePeer];
    	currentSession.delegate=self;
    	
    	[super viewDidLoad];
    }
    
    
    - (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state{
    	
    	
    	switch (state)
        {
            case GKPeerStateConnected:
    		{
    			NSString *str=[NSString stringWithFormat:@"Connected from peer: ",peerID];
    			NSLog(@"%@",str);
    			[peers addObject:peerID];
    			break;
    		}
            case GKPeerStateDisconnected:
    		{
    			[peers removeObject:peerID];
    			
    			NSString *str=[NSString stringWithFormat:@"DisConnected from pier ",peerID];
    			NSLog(@"%@",str);
    			break;
    		}
        }
    }
    I also implement the other methods in the delegate in order only to see when they are called while testing:

    Code:
    - (void)session:(GKSession *)session didReceiveConnectionRequestFromPeer:(NSString *)peerID{
    	
    	printf("one");
    	
    }
    
    
    - (void)session:(GKSession *)session connectionWithPeerFailed:(NSString *)peerID withError:(NSError *)error{
    	
    		printf("two");
    	
    }
    
    - (void)session:(GKSession *)session didFailWithError:(NSError *)error{
    	
    		printf("three");
    	
    }
    I have a button which calls this method when pressed:

    Code:
    -(IBAction)showPeers{
    	
    	
    	NSArray *p0=[currentSession peersWithConnectionState:GKPeerStateAvailable];
    	NSArray *p1=[currentSession peersWithConnectionState:GKPeerStateUnavailable];
    	NSArray *p2=[currentSession peersWithConnectionState:GKPeerStateConnected];
    	NSArray *p3=[currentSession peersWithConnectionState:GKPeerStateDisconnected];
    	NSArray *p4=[currentSession peersWithConnectionState:GKPeerStateConnecting];
    	
    	for (int i=0; i<[p0 count]; i++) {
    		printf("\np0\n");
    	}
    	
    	for (int i=0; i<[p1 count]; i++) {
    		printf("\np1\n");
    	}
    	
    	for (int i=0; i<[p2 count]; i++) {
    		printf("\np2\n");
    	}
    	
    	for (int i=0; i<[p3 count]; i++) {
    		printf("\np3\n");
    	}
    	
    	for (int i=0; i<[p4 count]; i++) {
    		printf("\np4\n");
    	}
    
    
    }

    No matter how many times you pressed the button. No peers are found.

    Am I doing something wrong? I suppose so...
     
  7. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #7
    Quick sanity check: you have two devices and you are connected one to the other right?
     
  8. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #8
    Also, both devices must be second-generation devices (iPhone 3G or 3Gs, or second-generation iPod touch).
     
  9. iPhoneSpain thread starter macrumors newbie

    Joined:
    Sep 27, 2009
    #9
    I have N devices and I want to connect device number i (i=0...N-1) with device j (j=0...N-1). I mean, every peer with every peer (or the ones you want).

    My idea is that when I launch the app, every peer sees all available peers in a tableView and select the ones you want to connect with. The same as GKPeerPickerController where you can see available peers but with the possibility of selecting several peers to connect with. I think that with GKPeerPickerController you can only select one peer to connect at one time and if you want to connect with another peer you have to show the interface again. That´s annoying for me and the reason why I want to implement my custom picker.

    Sorry for my non perfect English. I hope you understand me well.

    Thanks 4 all previous replies!
     
  10. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #10
    I understand what you are trying to do. What I am asking is:

    Let D be the number of physical devices you have. Is D>=2?

    If you only have one real device you're not going to see any other peers to connect to...
     
  11. iPhoneSpain thread starter macrumors newbie

    Joined:
    Sep 27, 2009
    #11
    D could be 2 or more.

    I am testing with my iPhone and the simulator. I know I can't connect because of limitations of the iPhone simulator, but what I do know is that the simulator detects available peers and you can see the name in the GKPeerPickerViewController interface. That is very easy and straightforward. I want the same (the iPhone simulator detecting my real iPhone device) but with no GKPeerPickerViewController...
     
  12. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #12
    Is anything being logged to the console by the NSLog statements in the delegate methods?
     
  13. iPhoneSpain thread starter macrumors newbie

    Joined:
    Sep 27, 2009
    #13
    Nothing.. It´s like if they were never called...
     
  14. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #14
    Which makes it seem likely that your session is not being created correctly for some reason. Can you add a check after to alloc/init the session to see if it's nil?
     
  15. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #15
    And you're sure of that? Maybe try putting a breakpoint into your methods and see if they are triggered. For example, in session: peer: didChangeState:, execution could easily proceed without anything being NSLogged because neither of your switch cases would be executed and you have no default case.
     
  16. iPhoneSpain thread starter macrumors newbie

    Joined:
    Sep 27, 2009
    #16
    It's finally working!!! Here's what I've added:

    Code:
    self.curSession.available = YES;
    self.curSession.disconnectTimeout = 0;
    
    - (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state {
    	
    	// Retain new session.
    	self.curSession = session;
    	
    	// Do stuff depending on state.
    	switch (state) {
    		case GKPeerStateAvailable:
    			[session connectToPeer:peerID withTimeout:0];
    			break;
    	}
    }
    
    - (void)session:(GKSession*) session didReceiveConnectionRequestFromPeer:(NSString*) peerID {
    	
    ***[session acceptConnectionFromPeer:peerID error:nil];
    }
    
    

    Thank you all for trying to help me.

    One more question. I have the peerID. But if I want to show the iPhone User name...how can I get it once connected???

    Thanks!
     
  17. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #17
    Really? C'mon! You must know where the documentation for GKSession is by this point.
     
  18. iPhoneSpain thread starter macrumors newbie

    Joined:
    Sep 27, 2009
    #18
    haha ok just found this method

    Code:
    - (NSString *)displayNameForPeer:(NSString *)peerID
    Thank u all one more time. You r the best :)
     
  19. iPhoneSpain thread starter macrumors newbie

    Joined:
    Sep 27, 2009
    #19
    Hi again!

    I have some problems when connecting more than two devices. Imagine three iPhones (1, 2 and 3).

    - I fire up 1.
    - I fire up 2. Then method didChangeState is called into GKPeerStateAvailable case. As I call connectToPeer, then didChangeState is called again into GKPeerStateConnected this time. Everything is OK. Two devices connected.

    The problem is when I fire up 3. didChangeState is always called into GKPeerStateAvailable but sometimes it connects (didChangeState is called again into GKPeerStateConnected) once and then when I fire it up again it never connects.... But if I switched off device 2, then 1 and 3 can connect.

    So somebody can figure out what's happening?

    Thanks again
     
  20. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #20
    Not without seeing the new code for all your delegate methods. And even then, many of us probably can't help since we don't have three suitable devices of our own.
     
  21. HarryWorksInc macrumors regular

    Joined:
    Feb 21, 2010
    #21
    help is here

    I might be able to help i have 5 devices that I have access to.

    ...Nerd + Apps = Money
    Money +Nerd = 
     
  22. iPhoneSpain thread starter macrumors newbie

    Joined:
    Sep 27, 2009
    #22
    I have been working with three and four devices and the problem is that when you fire up every device, each one is able to see the other ones and you can connect to them, but imagine this situation with three devices (A, B and C).

    1 - U switch iPhone A on --> A is in "available state"
    2 - U switch iPhone B on --> B is in "available state"
    3 - A and B can see each other as they are using a GKSession with the same ID.
    4 - You connect A and B --> A and B are now in "connected state".
    5 - You switch device C and want to connect to B or A. Device C can see A and B but the problem is that neither A nor B can see C as method didChangeState is never called.

    ¿What can I do to make peers visible by peers which have previously had a connection between them?

    Thx
     
  23. LeenaTekani macrumors newbie

    Joined:
    Sep 7, 2010
    #23
    GKSesion

    I have query regarding GKSession and peerID.If i maintain session between different views does the peerID changes??
    :confused:
     

Share This Page