读书笔记---蓝牙 (Game Kit)

蓝牙是一种无线通讯协议,主要用于短程和低耗电的设备,其有效通讯范围约30ft,传输速度为1Mb/s.在蓝牙4.0以后将通信模式分为高速和低速类型.高速类型是传统蓝牙,在iOS中高速蓝牙通信开发可以通过GameKit实现.低俗类型成为低功耗蓝牙,可以连接一些量测型传感器,可以通过CoreBluetooth.frameWork实现.


GameKit


GameKit开发采用的网络结构通常是对等结构网络.对等结构网络也叫点对点网络,每个节点之间是对等的.对等结构网络分布范围比较小,通常在一间办公室或一个家庭内,因此它非常适合于iOS设备间的网络通信,网络链路层是由蓝牙和WIFI实现.


对等结构网络是苹果AdHoc网络的一种,在小空间里构建无线网络的解决方案.苹果在GameKit框架中提供了开发这种网络API


连接一旦创建,会话也就建立起来.会话是与网络中运行应用的对等点对应的,每一对等点都会有一个PeerID作为标示区别彼此,可以指定也可以系统分配.在彼此发现方面,GameKit采用Banjour发现服务,这些对于开发人员是不可见的,不用关心他们的细节问题.


为了能够发现彼此,会话可以配置为:"服务器"(发布服务),"客户端"(搜索服务)和"对等点"(发布和搜索服务)三种类型


基于蓝牙连接的对等网络在数据传输时,传输的距离有限,另外GameKit对于传输的数据量也有一定的限制,数据量最大不能超过87KB,处于性能考虑传输数据不要超过1000B,如果超过,分隔成几个数据包传输.


基于蓝牙对等网络通信就是使用GameKit中的GKSession,GKSessionDelegate,GKPeerPickerController,GKPeerPickerControllerDelegate来实现.开发过程分为3个步骤:连接,发送数据和接收数据


具体的连接过程是

1.创建GKPeerPickerController对象

2.设置GKPeerPickerController的委托为self

3.成功回调委托方法- (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session

4.获得Session对象

5.设置Session的委托为self

6.Session状态变化回调委托方法- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state


我根据源码做了一点小修改


- (void)viewDidLoad
{
    [super viewDidLoad];
    [self clearUI];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}


-(void) clearUI
{
    [_btnConnect setTitle:@"连接" forState:UIControlStateNormal];
    [_btnClick setEnabled:NO];
    _lblPlayer2.text = @"0";
    _lblPlayer1.text = @"0";
    
}

- (void)viewDidUnload {
    [self setBtnConnect:nil];
    [self setLblPlayer1:nil];
    [self setLblPlayer2:nil];
    [self setBtnClick:nil];
    [super viewDidUnload];
}

- (IBAction)onClick:(id)sender {
    
    _lblPlayer1.text = [NSString stringWithFormat:@"我发送了:%@",self.sendTextField.text];
    
    NSDictionary *str = @{@"code":@(0),@"count":self.sendTextField.text};
    NSString *str2 = [str JSONString];
    
    NSData* data = [str2 dataUsingEncoding: NSUTF8StringEncoding];
    if (_session)
    {
        [_session sendDataToAllPeers:data
                        withDataMode:GKSendDataReliable
                               error:nil];
    }
    
}

- (IBAction)connect:(id)sender {
    
    _picker = [[GKPeerPickerController alloc] init];
    _picker.delegate = self;
    _picker.connectionTypesMask = GKPeerPickerConnectionTypeNearby;
    [_picker show];
}

#pragma mark--GKPeerPickerControllerDelegate

- (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];
    
}

- (void)peerPickerControllerDidCancel:(GKPeerPickerController *)pk
{
    NSLog(@"取消连接");
    _picker.delegate = nil;
}

#pragma mark--GKSessionDelegate
- (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];
    }
    
}

- (void)session:(GKSession *)session didFailWithError:(NSError *)error
{
    NSLog(@"error %@",[error description]);
}

- (void) receiveData:(NSData *)data
            fromPeer:(NSString *)peer
           inSession:(GKSession *)session
             context:(void *)context
{
    id jsonObj = [NSJSONSerialization JSONObjectWithData:data
                                                 options:NSJSONReadingAllowFragments error:nil];

    
    NSNumber *codeObj = [jsonObj objectForKey:@"code"];
    
    if ([codeObj intValue]== GAMING) {
        NSString * countObj= [jsonObj objectForKey:@"count"];
        _lblPlayer2.text = [NSString stringWithFormat:@"对方发送了:%@",countObj];
        
    } else if ([codeObj intValue]== GAMED) {
        [self clearUI];
    }
    
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [self.sendTextField resignFirstResponder];
}





你可能感兴趣的:(ios,读书笔记,蓝牙)