美文网首页iOS开发技能iOS开发iOS程序猿
iOS被遗忘的近距离通讯利器-MultipeerConnecti

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

作者: 卖报的小画家Sure | 来源:发表于2016-11-11 18:13 被阅读1673次

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

    iOS被遗忘的近距离通讯利器-MultipeerConnectivity
    个人认为其功能与iOS\MacOS中的AirDrop很相似,其飞一样的效率确实很酸爽。

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

    #import <MultipeerConnectivity/MultipeerConnectivity.h>
    

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

    /**
     *  表示为一个用户,亦可认为是当前设备
     */
    @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{
    
    }
    

    效果图如下


    1_发现附近设备.png
    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;
    }
    

    效果图


    3_传输数据.jpeg

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

    demo下载链接

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

    相关文章

      网友评论

      本文标题:iOS被遗忘的近距离通讯利器-MultipeerConnecti

      本文链接:https://www.haomeiwen.com/subject/tlhfpttx.html