// // LocalChatCenter.h // TestLocalChat // // Created by 孫俊 on 14-4-6. // Copyright (c) 2014年 yipinapp. All rights reserved. // #import <Foundation/Foundation.h> @protocol LocalChatCenterDelegate <NSObject> @optional //鏈接相關 - (void)isConnection; - (void)isUnConnection; //數據傳輸相關 - (void)receiveData:(NSData *)data UserName:(NSString *)userName; @end @interface LocalChatCenter : NSObject @property (nonatomic, weak) id<LocalChatCenterDelegate> delegate; @property (nonatomic, assign, readonly) BOOL isConnected; + (LocalChatCenter *)shareInstance; - (void)startConnection; - (void)stopConnection; - (void)sendData:(NSData *)data; @end // // LocalChatCenter.m // TestLocalChat // // Created by 孫俊 on 14-4-6. // Copyright (c) 2014年 yipinapp. All rights reserved. // #define D_SessionID_My @"TestChat" #import "LocalChatCenter.h" #import <GameKit/GameKit.h> static LocalChatCenter *localChatCenter = nil; @interface LocalChatCenter()<GKPeerPickerControllerDelegate, GKSessionDelegate> @property (nonatomic, strong) GKPeerPickerController *peerPicker; @property (nonatomic, strong) GKSession *session; @property (nonatomic, strong) NSString *myPeerId; @property (nonatomic, assign) BOOL isConnected; @end @implementation LocalChatCenter + (LocalChatCenter *)shareInstance { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ localChatCenter = [[LocalChatCenter alloc] init]; }); return localChatCenter; } #pragma mark 通信鏈接相關方法 //啓動聯機 - (void)startConnection { if (self.isConnected == NO) { self.peerPicker = [[GKPeerPickerController alloc] init]; self.peerPicker.connectionTypesMask = GKPeerPickerConnectionTypeNearby | GKPeerPickerConnectionTypeOnline; self.peerPicker.delegate = self; [self.peerPicker show]; } } //設置會話屬性回調 - (GKSession *)peerPickerController:(GKPeerPickerController *)picker sessionForConnectionType:(GKPeerPickerConnectionType)type { if (self.session != nil) { return self.session; } self.session = [[GKSession alloc] initWithSessionID:D_SessionID_My displayName:nil sessionMode:GKSessionModePeer]; self.session.delegate = self; return self.session; } //聯機成功回調 - (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session { self.session = session; [self.session setDataReceiveHandler:self withContext:nil]; self.myPeerId = peerID; self.isConnected = YES; [picker dismiss]; } //取消聯機 - (void)peerPickerControllerDidCancel:(GKPeerPickerController *)picker { //此處能夠進行取消聯機後的處理,能夠什麼都不作。 } //中止聯機 - (void)stopConnection { if (self.isConnected == YES) { [self.session disconnectFromAllPeers]; self.session = nil; self.myPeerId = nil; self.isConnected = NO; } } //設備的聯機狀態改變回調 - (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state { NSString *peerName = [session displayNameForPeer:peerID]; if (peerName == nil) { peerName = peerID; } switch (state) { case GKPeerStateConnected: { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:[NSString stringWithFormat:@"%@進入會話",peerName] delegate:nil cancelButtonTitle:@"知道了" otherButtonTitles: nil]; [alertView show]; if ([self.delegate respondsToSelector:@selector(isConnection)]) { [self.delegate isConnection]; } } break; case GKPeerStateDisconnected: { self.isConnected = NO; [self stopConnection]; UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:[NSString stringWithFormat:@"會話結束"] delegate:nil cancelButtonTitle:@"知道了" otherButtonTitles: nil]; [alertView show]; if ([self.delegate respondsToSelector:@selector(isUnConnection)]) { [self.delegate isUnConnection]; } } break; default: break; } } - (void)hidePicker { if (self.peerPicker.isVisible) { [self.peerPicker dismiss]; } } //收到其它設備的鏈接請求回調 - (void)session:(GKSession *)session didReceiveConnectionRequestFromPeer:(NSString *)peerID { [session acceptConnectionFromPeer:peerID error:nil]; } //和其餘設備鏈接發生錯誤回調 - (void)session:(GKSession *)session connectionWithPeerFailed:(NSString *)peerID withError:(NSError *)error { } //GKSession內部發生錯誤回調 - (void)session:(GKSession *)session didFailWithError:(NSError *)error { } #pragma mark 收發信息相關方法 //發送消息 - (void)sendData:(NSData *)data { [self startConnection]; NSError *error; BOOL sendOk = [self.session sendDataToAllPeers:data withDataMode:GKSendDataReliable error:&error]; if (sendOk == NO) { NSLog(@"傳送信息失敗,緣由以下/n%@", error); } } //接收消息 - (void)receiveData:(NSData *)data fromPeer:(NSString *)peer inSession:(GKSession *)session context:(void *)context { if ([self.delegate respondsToSelector:@selector(receiveData: UserName:)]) { NSString *userName = [session displayNameForPeer:peer]; if (userName == nil || userName.length == 0) { userName = peer; } [self.delegate receiveData:data UserName:userName]; } } @end