iOS被遗忘的近距离通讯利器-MultipeerConnectivity

Multipeer connectivity是一个使附近设备通过Wi-Fi网络、P2P Wi-Fi以及蓝牙个人局域网进行通信的框架。互相链接的节点可以安全地传递信息、流或是其他文件资源。

iOS被遗忘的近距离通讯利器-MultipeerConnectivity_第1张图片
图片发自App

个人认为其功能与iOS\MacOS中的AirDrop很相似,其飞一样的效率确实很酸爽。

废话少说,我们来集成MultipeerConnectivity的功能。
首先引入系统框架

#import 

依次声明如下属性,这里都给予了详细的备注,就不赘述了。

/**
 *  表示为一个用户,亦可认为是当前设备
 */
@property (nonatomic,strong)MCPeerID * peerID;
/**
 *  数据流,启用和管理Multipeer连接会话中的所有人之间的沟通。 通过Sesion,给别人发送数据。类似于Scoket
 */
@property (nonatomic,strong)MCSession * session;
/**
 *  可以接收,并处理用户请求连接的响应。没有回调,会弹出默认的提示框,并处理连接。
 */
@property (nonatomic,strong)MCAdvertiserAssistant * advertiser;
/**
 *  用于搜索附近的用户,并可以对搜索到的用户发出邀请加入某个会话中。
 */
@property (nonatomic,strong)MCNearbyServiceBrowser * brower;
/**
 *  附近用户列表
 */
@property (nonatomic,strong)MCBrowserViewController * browserViewController;
/**
 *  存储连接
 */
@property (nonatomic,strong)NSMutableArray * sessionArray;

接下来我们将当前设备初始化,并开启附近用户搜索等功能。

/**
 *  连接设置
 */
- (void)createMC{
    //获取设备名称
    NSString * name = [UIDevice currentDevice].name;
    //用户
    _peerID = [[MCPeerID alloc]initWithDisplayName:name];
    //为用户建立连接
    _session = [[MCSession alloc]initWithPeer:_peerID];
    //设置代理
    _session.delegate = self;
    //设置广播服务(发送方)
    _advertiser = [[MCAdvertiserAssistant alloc]initWithServiceType:@"type" discoveryInfo:nil session:_session];
    //开始广播
    [_advertiser start];
    //设置发现服务(接收方)
    _brower = [[MCNearbyServiceBrowser alloc]initWithPeer:_peerID serviceType:@"type"];
    //设置代理
    _brower.delegate = self;
    [_brower startBrowsingForPeers];
}

这里不要忘记添加其协议,如下
MCSessionDelegateMCBrowserViewControllerDelegateMCNearbyServiceBrowserDelegate
最后实现其对应的代理方法即可

#pragma MC相关代理方法
/**
 *  发现附近用户
 *
 *  @param browser 搜索附近用户
 *  @param peerID  附近用户
 *  @param info    详情
 */
- (void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary *)info{
    NSLog(@"发现附近用户%@",peerID.displayName);
    if (_browserViewController == nil) {
        _browserViewController = [[MCBrowserViewController alloc]initWithServiceType:@"type" session:_session];
        _browserViewController.delegate = self;
        /**
         *  跳转发现界面
         */
        [self presentViewController:_browserViewController animated:YES completion:nil];
    }
}
/**
 *  附近某个用户消失了
 *
 *  @param browser 搜索附近用户
 *  @param peerID  用户
 */
- (void)browser:(MCNearbyServiceBrowser *)browser lostPeer:(MCPeerID *)peerID{
    NSLog(@"附近用户%@离开了",peerID.displayName);
}
#pragma mark BrowserViewController附近用户列表视图相关代理方法
/**
 *  选取相应用户
 *
 *  @param browserViewController 用户列表
 */
- (void)browserViewControllerDidFinish:(MCBrowserViewController *)browserViewController{
    [self dismissViewControllerAnimated:YES completion:nil];
    _browserViewController = nil;
    //关闭广播服务,停止其他人发现
    [_advertiser stop];
}
/**
 *  用户列表关闭
 *
 *  @param browserViewController 用户列表
 */
- (void)browserViewControllerWasCancelled:(MCBrowserViewController *)browserViewController{
    [self dismissViewControllerAnimated:YES completion:nil];
    _browserViewController = nil;
    [_advertiser stop];
}
#pragma mark MCSession代理方法
/**
 *  当检测到连接状态发生改变后进行存储
 *
 *  @param session MC流
 *  @param peerID  用户
 *  @param state   连接状态
 */
- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state{
    //判断如果连接
    if (state == MCSessionStateConnected) {
        //保存这个连接
        if (![_sessionArray containsObject:session]) {
            //如果不存在 保存
            [_sessionArray addObject:session];
        }
    }
}
/**
 *  接收到消息
 *
 *  @param session MC流
 *  @param data    传入的二进制数据
 *  @param peerID  用户
 */
- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID{
    NSString * message = [NSString stringWithFormat:@"%@:%@",peerID.displayName,[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]];
    dispatch_async(dispatch_get_main_queue(), ^{
        [_dataArray addObject:message];
        NSIndexPath * indexPath = [NSIndexPath indexPathForRow:_dataArray.count - 1 inSection:0];
        [_tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
        [_tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
    });
}
/**
 *  接收数据流
 *
 *  @param session    MC流
 *  @param stream     数据流
 *  @param streamName 数据流名称(标示)
 *  @param peerID     用户
 */
- (void)session:(MCSession *)session didReceiveStream:(NSInputStream *)stream withName:(NSString *)streamName fromPeer:(MCPeerID *)peerID{
    
}
/**
 *  开始接收资源
 */
- (void)session:(MCSession *)session didStartReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID withProgress:(NSProgress *)progress{

}
/**
 *  资源接收结束
 */
- (void)session:(MCSession *)session didFinishReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID atURL:(NSURL *)localURL withError:(NSError *)error{

}

效果图如下


iOS被遗忘的近距离通讯利器-MultipeerConnectivity_第2张图片
1_发现附近设备.png

iOS被遗忘的近距离通讯利器-MultipeerConnectivity_第3张图片
2_连接设备成功.png

选定后点击Done即可完成连接。
代理方法中具有监听附近设备,连接,接收流程等流程。
对于发送数据,可以简单搭建一个页面来进行。比如在textField点击Return时触发。对于发送的数据类型具有两种形式,对应的即为socket中的UDP与TCP。

- (BOOL)textFieldShouldReturn:(UITextField *)textField{
    if (textField.text.length > 0) {
        /**
         *  两种类型
         MCSessionSendDataUnreliable 类似于UDP连接方式
         MCSessionSendDataReliable 类似于TCP连接方式
         */
        [_session sendData:[textField.text dataUsingEncoding:NSUTF8StringEncoding] toPeers:_session.connectedPeers withMode:MCSessionSendDataUnreliable error:nil];
        //UI操作
        [_dataArray addObject:textField.text];
        NSIndexPath * indexPath = [NSIndexPath indexPathForRow:_dataArray.count - 1 inSection:0];
        [_tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
        [_tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
    }
    return YES;
}

效果图


iOS被遗忘的近距离通讯利器-MultipeerConnectivity_第4张图片
3_传输数据.jpeg

这里测试的话可以使用两台设备,模拟器、真机均可。当其中一个设备检测到附近设备后会弹起附近设备列表,点击选取后即可进行通讯操作。用例里模拟的是发送字符串操作,也可以替换为文件,因为都传递的为二进制嘛。相信你会察觉到其飞一样的速度的,就写到这里。

demo下载链接

iOS被遗忘的近距离通讯利器demo

你可能感兴趣的:(iOS被遗忘的近距离通讯利器-MultipeerConnectivity)