iOS GameKit蓝牙通信以及自定义cell的使用--实现仿微信聊天功能

一、概述

利用GameKit框架实现ios设备的蓝牙通讯,导入框架:#import <GameKit/GameKit.h>  , 注意: 此框架只能用于ios设置间蓝牙通讯。

如今苹果开放了接口来实现不仅限于在苹果设备间的蓝牙通讯,需要导入框架:#import <CoreBluetooth/CoreBluetooth.h>,此框架可以用在苹果设备间、苹果设备与各种符合苹果MFI认证的智能硬件的蓝牙通信。

以一个简单的APP聊天功能作为示例,讲解使用GameKit的蓝牙通信功能以及UITableView的自定义cell的使用方法。

二、用GameKit框架实现ios设备蓝牙通讯

基本属性和方法:

  属性

  • 是否可见:visible
  • 蓝牙连接类型:connectionTypesMask

  方法:

  • 显示蓝牙控制器:- (void)show;
  • 隐藏蓝牙控制器:- (void)dismiss;
  • 蓝牙连接成功会调用:- (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session
  • 取消蓝牙连接:- (void)peerPickerControllerDidCancel:(GKPeerPickerController *)picker
  • 接收到数据会调用:- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context
  • 发送数据给特定的对端蓝牙设备:self.session sendData:<#(NSData *)#> toPeers:<#(NSArray *)#> withDataMode:<#(GKSendDataMode)#> error:<#(NSError *__autoreleasing *)#>  
  • 发送数据给所有蓝牙设备:self.session sendDataToAllPeers:<#(NSData *)#> withDataMode:<#(GKSendDataMode)#> error:<#(NSError *__autoreleasing *)#>
Apple提供了一个内置的界面“对等设备选择器”,可用于查找要连接的设备,如下如所示,可以让用户轻易的查找并选择设备连接。

具体实现方式如下:
//初始化对等设备把设置代理
    GKPeerPickerController* peerPickerController=[[GKPeerPickerController alloc] init];
    peerPickerController.delegate=self;
    peerPickerController.connectionTypesMask=GKPeerPickerConnectionTypeNearby;
    self.peerPickerController=peerPickerController;
    [self.peerPickerController show];
//代理方法,用户点取消按钮调用
-(void)peerPickerControllerDidCancel:(GKPeerPickerController *)picker
{
    self.peerPickerController.delegate=nil;
}
//代理方法,用户选择连接某个设备时调用,连接建立一个会话
-(void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session
{
    [self.peerPickerController dismiss];
    SZChatVC* chatVC=[[SZChatVC alloc] init];
    chatVC.currrentSession=session;
    chatVC.peerID=peerID;
    [self.navigationController pushViewController:chatVC animated:YES];
}

//发送消息
- (IBAction)send:(id)sender
{
    NSString* messageStr=self.inputTextField.text;
    NSDictionary* messageDict=[[NSDictionary alloc] initWithObjectsAndKeys:messageStr,@"message",@"myself",@"sender", nil];
    [messageArray addObject:messageDict];
    NSLog(@"messageArray:%@",messageArray);
    NSError *error=nil;
    NSData* messageData=[messageStr dataUsingEncoding:NSUTF8StringEncoding];
    //通过前面连接的蓝牙会话发送数据
    [self.currrentSession sendDataToAllPeers:messageData withDataMode:GKSendDataReliable error:&error];
    if (error)
    {
        NSLog(@"Current session is error:%@",error);
    }
    //情况输入框和使发送按钮非使能
    [self.inputTextField setText:@""];
    [self.sendBtn setEnabled:NO];
    //刷新信息表格,滚动到底部
    [self.messageTableView reloadData];
    NSLog(@"[messageArray count]:%lu",[messageArray count]);
    NSIndexPath* indexPathLast=[NSIndexPath indexPathForRow:[messageArray count]-1 inSection:0];
    [self.messageTableView scrollToRowAtIndexPath:indexPathLast atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
//接收消息
- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context
{
    NSString *messageString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    
    NSDictionary *messageDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:messageString, @"message", @"peer", @"sender", nil];
    
    [messageArray addObject: messageDictionary];
    [self.messageTableView reloadData];
    
    //scroll to the last row
    NSIndexPath* indexPathForLastRow = [NSIndexPath indexPathForRow:[messageArray count]-1 inSection:0];
    [self.messageTableView scrollToRowAtIndexPath:indexPathForLastRow atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

三、自定义cell显示消息(类似于微信消息对话界面)

由于系统提供的tableview可能并不能满足我们的开发需求,所以经常要求我们能够自定义tableview。

自定义tableview有两种方式,一种是使用xib创建,一种是使用纯代码的方式创建。

对于样式一样的tableview,通常使用xib进行创建,对于高度不一样,内容也不完全一致的通常使用纯代码进行自定义。具体实现如下:

//代理方法,设置cell
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIImageView* messageBackground=nil;
    UILabel* messageLabel=nil;
    //cell重用
    NSString* const cellID=@"cellID";
    UITableViewCell* cell=[tableView dequeueReusableCellWithIdentifier:cellID];
    if (!cell)
    {
        cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
        //自定义的从cell主要包含了一个聊天气泡的背景视图和一个显示消息文本的Label
        messageBackground=[[UIImageView alloc] init];
        messageBackground.backgroundColor=[UIColor clearColor];
        //设置cell的concentView的tag,注意contentView的tag不能为0,否则程序崩溃
        messageBackground.tag=kmsgBackground;
        
        messageLabel=[[UILabel alloc] init];
        messageLabel.tag=kmsgText;
        messageLabel.numberOfLines=0;
        messageLabel.lineBreakMode=NSLineBreakByCharWrapping;
        messageLabel.font=[UIFont systemFontOfSize:14];
        
    }
    else
    {
        messageBackground=(UIImageView*)[cell.contentView viewWithTag:kmsgBackground];
        messageLabel=(UILabel*)[cell.contentView viewWithTag:kmsgText];
    }
    //取出当前cell的消息
    NSDictionary* messageDict=[messageArray objectAtIndex:indexPath.row];
    NSString* messageStr=[messageDict objectForKey:@"message"];
    NSString* sender=[messageDict objectForKey:@"sender"];
    //根据消息文本计算cell的大小
    CGSize messageSize=[messageStr sizeWithFont:[UIFont systemFontOfSize:14.] constrainedToSize:CGSizeMake(180, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping];
    UIImage* bubbleImage;
    CGFloat tableViewWidth=self.messageTableView.frame.size.width;
    if ([sender isEqualToString:@"myself"])
    {
        //设置消息气泡背景大小
        messageBackground.frame=CGRectMake(tableViewWidth-messageSize.width-34,1, messageSize.width+34, messageSize.height+12.);
        messageBackground.autoresizingMask=UIViewAutoresizingFlexibleLeftMargin;
        //拉伸聊天气泡图片
        bubbleImage=[[UIImage imageNamed:@"chatBubbleGreen"] stretchableImageWithLeftCapWidth:15 topCapHeight:13];
        //设置消息文本标签的大小
        messageLabel.frame=CGRectMake(tableViewWidth-messageSize.width-22., 5., messageSize.width+5, messageSize.height);
        messageLabel.autoresizingMask=UIViewAutoresizingFlexibleLeftMargin;
    }
    else
    {
        //同上设置方法
        messageBackground.frame=CGRectMake(0.,1., messageSize.width+34, messageSize.height+12.);
        messageBackground.autoresizingMask=UIViewAutoresizingFlexibleLeftMargin;
        bubbleImage=[[UIImage imageNamed:@"chatBubbleGray"] stretchableImageWithLeftCapWidth:23 topCapHeight:15];
        messageLabel.frame=CGRectMake(22., 5., messageSize.width+5, messageSize.height);
        messageLabel.autoresizingMask=UIViewAutoresizingFlexibleLeftMargin;
    }
    messageBackground.image=bubbleImage;
    messageLabel.text=messageStr;
    [cell.contentView addSubview:messageBackground];
    [cell.contentView addSubview:messageLabel];
    return cell;
}
//代理方法,设置cell的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString* messageStr=[[messageArray objectAtIndex:indexPath.row] objectForKey:@"message"];
    CGSize messageSize=[messageStr sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(180, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping];
    return messageSize.height+17.0f;
}
结果如下:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值