您好,登錄后才能下訂單哦!
基于藍牙對等網絡通信就是使用Game Kit中的GKSession、GKSessionDelegate、 GKPeerPickerController和GKPeerPickerControllerDelegate來實現。開發過程分為3個步驟:連接、發 送數據和接收數據。
下面我們通過一個實例介紹一下基于藍牙對等網絡通信過程。用戶點擊“連接”按鈕,建立連接過程中會出現連接對話框,根據具體情況也會彈出其它的對話 框。這些都是針對藍牙對等網絡標準對話框,而Wifi對等網絡沒有標準對話框可以使用,需要開發者自己實現。當兩個設備連接好之后,兩個玩家就可以連續輕 點“點擊”按鈕,點擊的次數會傳遞給對方,倒計時時間是30秒。
1、連接
由于對等網絡連接過程有點復雜,貫穿了這些協議和類,我們繪制了連接過程的流程圖。
下面我們通過代碼直接介紹連接流程,其中ViewController.h代碼如下:
- #import <UIKit/UIKit.h>
- #import <GameKit/GameKit.h>
- #define GAMING 0 //游戲進行中
- #define GAMED 1 //游戲結束
- @interface ViewController : UIViewController <GKSessionDelegate, GKPeerPickerControllerDelegate>
- {
- NSTimer *timer;
- }
- @property (weak, nonatomic) IBOutlet UILabel *lblTimer;
- @property (weak, nonatomic) IBOutlet UILabel *lblPlayer2;
- @property (weak, nonatomic) IBOutlet UILabel *lblPlayer1;
- @property (weak, nonatomic) IBOutlet UIButton *btnConnect;
- @property (weak, nonatomic) IBOutlet UIButton *btnClick;
- @property (nonatomic, strong) GKPeerPickerController *picker;
- @property (nonatomic, strong) GKSession *session;
- - (IBAction)onClick:(id)sender;
- - (IBAction)connect:(id)sender;
- //清除UI畫面上的數據
- -(void) clearUI;
- //更新計時器
- -(void) updateTimer;
- @end
使用Game Kit需要引入頭文件<GameKit/GameKit.h>,之前需要把GameKit.framework框架添加 到工程中。而且定義類的時候需要實現協議GKSessionDelegate和GKPeerPickerControllerDelegate,并且定義 GKPeerPickerController類型的屬性picker,定義GKSession類型的屬性session。
ViewController.m中創建GKPeerPickerController對象的代碼如下:
- - (IBAction)connect:(id)sender {
- _picker = [[GKPeerPickerController alloc] init];
- _picker.delegate = self; ①
- _picker.connectionTypesMask = GKPeerPickerConnectionTypeNearby; ②
- [_picker show];
- }
用戶點擊的連接按鈕時,觸發connect:方法。在該方法中創建GKPeerPickerController對象。創建完成不要忘記設置 GKPeerPickerController委托為self,第②行代碼所示。在第③行代碼中connectionTypesMask屬性是設置對等網 絡連接類型,其中有兩種類型選擇:GKPeerPickerConnectionTypeNearby和 GKPeerPickerConnectionTypeOnline,GKPeerPickerConnectionTypeNearby用于藍牙通訊也 是默認的通訊方法,GKPeerPickerConnectionTypeOnline用于Wifi通訊的局域網通訊,這種方式麻煩,需要開發人員自己設 計UI畫面,自己使用Bonjour服務發現管理連接,以及自己編寫輸入輸出流實現通訊。如果給用戶一個選擇對話框,代碼可以如下編寫:
_picker.connectionTypesMask = GKPeerPickerConnectionTypeNearby | GKPeerPickerConnectionTypeOnline;
其中“在線”就是GKPeerPickerConnectionTypeOnline類型,“附近”就是GKPeerPickerConnectionTypeNearby類型。
連接成功之后回調ViewController.m中的回調委托方法peerPickerController:didConnectPeer:toSession:代碼:
- - (void)peerPickerController:(GKPeerPickerController *)pk didConnectPeer:(NSString *)peerID
- toSession:(GKSession *) session
- {
- NSLog(@”建立連接”);
- _session = session; ①
- _session.delegate = self; ②
- [_session setDataReceiveHandler:self withContext:nil]; ③
- _picker.delegate = nil;
- [_picker dismiss]; ④
- [_btnClick setEnabled:YES];
- [_btnConnect setTitle:@"斷開連接" forState:UIControlStateNormal];
- //開始計時
- timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self
- selector:@selector(updateTimer)
- userInfo:nil repeats:YES]; ⑤
- }
上述代碼第①行_session = session將委托方法中返回的會話參數賦值給成員變量,這樣我們就獲得了一個會話對象。這種方式中,會話 ID是應用程序的包ID,如果想自己分配會話ID,可以實現下面委托方法,在方法中使用GKSession的構造方法 initWithSessionID:displayName: sessionMode:,自己創建會話對象。
- - (GKSession *)peerPickerController:(GKPeerPickerController *)picker
- sessionForConnectionType:(GKPeerPickerConnectionType)type {
- GKSession *session = [[GKSession alloc] initWithSessionID: <自定義SessionID>
- displayName:<顯示的名字> sessionMode:GKSessionModePeer];
- return session;
- }
有的時候會話的狀態會發生變化,我們要根據狀態的變化做一些UI的清理和資源的釋放。監測狀態變化在委托方法session:peer:didChangeState:中實現,方法代碼如下:
- - (void)session:(GKSession *)session peer:(NSString *)peerID
- didChangeState:(GKPeerConnectionState)state
- {
- if (state == GKPeerStateConnected)
- {
- NSLog(@”connected”);
- [_btnConnect setTitle:@"斷開連接" forState:UIControlStateNormal];
- [_btnClick setEnabled:YES];
- } else if (state == GKPeerStateDisconnected)
- {
- NSLog(@”disconnected”);
- [self clearUI];
- }
- }
其中GKPeerStateConnected常量是已經連接狀態,GKPeerStateDisconnected常量是斷開連接狀態。
2、發送數據
發送數據的代碼如下:
- - (IBAction)onClick:(id)sender {
- int count = [_lblPlayer1.text intValue];
- _lblPlayer1.text = [NSString stringWithFormat:@"%i",++count];
- NSString *sendStr = [NSString
- stringWithFormat:@"{\"code\":%i,\"count\":%i}",GAMING,count]; ①
- NSData* data = [sendStr dataUsingEncoding: NSUTF8StringEncoding];
- if (_session) {
- [_session sendDataToAllPeers:data
- withDataMode:GKSendDataReliable error:nil]; ②
- }
- }
3、接收數據
為了接收數據首先需要在設置會話時候通過[_session setDataReceiveHandler:self withContext:nil]語句設置接收數據的處理程序是self。這樣當數據到達時候就會觸發下面的方法特定:
- - (void) receiveData:(NSData *)data fromPeer:(NSString *)peer
- inSession:(GKSession *)session context:(void *)context
- {
- id jsonObj = [NSJSONSerialization JSONObjectWithData:data
- options:NSJSONReadingMutableContainers error:nil];
- NSNumber *codeObj = [jsonObj objectForKey:@"code"];
- if ([codeObj intValue]== GAMING) {
- NSNumber * countObj= [jsonObj objectForKey:@"count"];
- _lblPlayer2.text = [NSString stringWithFormat:@"%@",countObj];
- } else if ([codeObj intValue]== GAMED) {
- [self clearUI];
- }
- }
上面的代碼是接收到數據之后,進行JSON解碼,取出游戲狀態和點擊次數。
主要的程序代碼就是這些,根據具體的業務情況還可以能有所變化,讀者可以下載完整代碼在兩臺之間設備或是一個設備一個模擬器之間進行測試。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。