- 了解: MultiPeerConnectivity
Multipeer Connectivity Framework是iOS 7 推出的眾多新框架的一種佣谐,它拓寬了操作系統(tǒng)中應(yīng)用的范圍卵凑。其目的是使開發(fā)者可以創(chuàng)建通過Wi-Fi或藍牙在近距離建立連接的應(yīng)用停蕉。是在近距離設(shè)備間建立互動,交換數(shù)據(jù)和其他資源的很好的簡單工具硼被。
有一款iOS 應(yīng)用 FireChat , 它的特別之處就是在沒有互聯(lián)網(wǎng)的環(huán)境下允粤,安裝了該應(yīng)用的用戶可以通過藍牙暖庄、WiFi 建立連接直接開聊弊予! 就是基于 **Multipeer Connectivity Framework **開發(fā)的! 有興趣的可以下載看看!
{ImgCap}FireChat {/ImgCap}
-
框架
首先必須在工程中導(dǎo)入MultiPeerConnectivity.framework框架
{ImgCap}MultiPeerConnectivity.framework{/ImgCap}
- 用MultiPeerConnectivity進行通訊, 如同三次握手的通訊類似, A先放出廣播, B用于搜索! B搜到之后, 會向A發(fā)送邀請, 建立連接, 當你接受了之后, A會向B發(fā)送一個會話(session), 若建立成功則可以互傳數(shù)據(jù)!
一般 MCAdvertiserAssistant 與 MCBrowserViewController 互用,MCNearbyServiceAdvertiser 與 MCNearbyServiceBrowser 互用 , 前一組系統(tǒng)已經(jīng)封裝好的界面, 后邊一組與第一組功能相似, 單方法更多, 可以自定義界面! 進行操作性多一些!
MCPeerID 是設(shè)置自己的設(shè)備名字! MCSession則是最重要的, 傳輸消息文字, 文件, 圖片都要通過它!
MCPeerID 只有這一個方法用于設(shè)置設(shè)備名稱!
- (instancetype)initWithDisplayName:(NSString*)myDisplayName
-
MCAdvertiser 用于廣播! 這有兩個類了!
5.1 MCNearbyServiceAdvertiser // 需要自己設(shè)置
- (instancetype)initWithPeer: (MCPeerID *)myPeerID discoveryInfo: (NSDictionary *)info serviceType: (NSString *)serviceType
三個參數(shù)
參數(shù)1: 設(shè)備名稱:(昵稱), 參數(shù)2: 發(fā)現(xiàn)信息:(可以置空!) 參數(shù)2: 參照上邊設(shè)備標示符
- (void)startAdvertisingPeer;
- (void)stopAdvertisingPeer;
是開始廣播和停止廣播!代理方法 (這個方法重要 ! )
//處理接收到的邀請
invitationHandler這個參數(shù)是用來處理是否接收請求的, 如下所示
- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void(^)(BOOLaccept, MCSession *session))invitationHandler;
參數(shù)1: 表示 用來接收邀請的advertiser
參數(shù)2: 表示 從哪個peerID過來的邀請
參數(shù)3: 用于表示接收邀請的時候, 接收context ; 沒用過!
參數(shù)4: invitationHandler(BOOL, session) 一個block方法,
invitationHandler(YES, self.session);
表示接收邀請! 并開始建立會話
invitationHandler(NO, nill);
表示拒絕邀請! 當然, 可以在這個方法中設(shè)置彈窗用于確定是否接收邀請!!- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didNotStartAdvertisingPeer:(NSError *)error; // 用于處理連接錯誤
5.2 MCAdvertiserAssistant
用于初始化廣播服務(wù),
- (instancetype)initWithServiceType:(NSString *)serviceType discoveryInfo:(NSDictionary *)info session:(MCSession *)session
參數(shù)1 : serviceType 一個類型標示符,通過一個小的文本描述為了瀏覽器能夠發(fā)現(xiàn)廣播者祥楣,這個小文本應(yīng)該是相同的.只用相同的serviceType,才能相互的連接到!
關(guān)于它的名字有兩個規(guī)則:- 必須是1 - 15字符。
- 只能包含ASCII小寫字母,數(shù)字和連字符
參數(shù)2 : 可置空 (類似于剛剛接觸的時發(fā)給對方的消息, 不過沒弄明白)
參數(shù)3 : session 一個已經(jīng)創(chuàng)建好的會話(下邊講到)
當然, 若用MCAdvertiserAssistant 就相當于調(diào)用的系統(tǒng)已經(jīng)封裝好的, 較為方便一些! 唯一就是界面不可定制!
- (void)start; - (void)stop;
// 表示開始廣播 和 停止廣播
還有兩個 代理 方法
// An invitation will be presented to the user
- (void)advertiserAssistantWillPresentInvitation:(MCAdvertiserAssistant *)advertiserAssistant;
// An invitation was dismissed from screen
- (void)advertiserAssistantDidDismissInvitation:(MCAdvertiserAssistant *)advertiserAssistant;
算是兩個回調(diào), 用處不大!. MCBrowser 搜索周圍的設(shè)備可以發(fā)出會話邀請建立連接
6.1 MCNearbyServiceBrowser
// 需要自己設(shè)置!
- (instancetype)initWithPeer:(MCPeerID*)myPeerID serviceType:(NSString*)service
// 設(shè)備名字, 設(shè)備識別碼!
- (void)startBrowsingForPeers;
// 開始搜索
- (void)stopBrowsingForPeers; //
停止搜索
// 在搜索到周圍設(shè)備后調(diào)用此方法, 邀請相應(yīng)的設(shè)備加入會話!
- (void)invitePeer:(MCPeerID*)peerID toSession:(MCSession*)session withContext:(NSData*)context timeout:(NSTimeInterval)timeout;
參數(shù)1: 邀請的peerID 參數(shù)2:建立的session 參數(shù)3:置空(沒搞太明白) 參數(shù)4:延遲時間
MCNearbyServiceBrowser的代理方法 ,
// 表示發(fā)現(xiàn)了周圍的設(shè)備, 再次代理方法中處理是否發(fā)送會話邀請!
- (void)browser:(MCNearbyServiceBrowser*)browser foundPeer:(MCPeerID*)peerID withDiscoveryInfo:(NSDictionary*)info;
如:
- (void)browser:(MCNearbyServiceBrowser)browser foundPeer:
(MCPeerID)peerID withDiscoveryInfo:(NSDictionary*)info{
[browser invitePeer: peerID toSession:self.session withContext:nil timeout:30];
}
// 此方法用于對斷開連接的設(shè)備做處理!
- (void)browser:(MCNearbyServiceBrowser*)browser lostPeer:(MCPeerID*)peerID
6.2 MCBrowserViewController ---- (系統(tǒng)封裝好的視圖, 可直接顯示周圍已廣播的設(shè)備!)

代理方法!
方法1: 用于初始化,MCBrowserViewController, 并附上 serviceType 和 session;
// Create a browser view controller with a service type and a session
- (instancetype)initWithServiceType:(NSString *)serviceType session:(MCSession *)session;
兩個代理方法, 代表上邊MCBrowserViewController 對應(yīng)的兩個按鈕! cancel button 和 done button 所執(zhí)行的方法, 由于 MCBrowserViewController是個ViewController,所以需要 presentViewController, 因而可以在此方法中調(diào)用 dismissViewController !!!
- (void)browserViewControllerDidFinish:(MCBrowserViewController *)browserViewController;
// done button- (void)browserViewControllerWasCancelled:(MCBrowserViewController *)browserViewController;
// cancel button
-
MCSession
- (instancetype)initWithPeer:(MCPeerID *)myPeerID; // session初始化 Create a session with an MCPeerID for the local peer
7.1 發(fā)送普通數(shù)據(jù)
- (BOOL)sendData:(NSData *)data toPeers:(NSArray *)peerIDs withMode:(MCSessionSendDataMode)mode error:(NSError **)error;
// 參數(shù)1: 發(fā)送的數(shù)據(jù), 要轉(zhuǎn)成data類型!
// 參數(shù)2: 要發(fā)給的所在這個會話中的所有Peers! session中有個 NSArray *connectedPeers, 表示
// 參數(shù)3: MCSessionSendDataMode: 是個枚舉
typedefNS_ENUM(NSInteger, MCSessionSendDataMode) {
MCSessionSendDataReliable, // 保證可靠和按順序傳遞
MCSessionSendDataUnreliable // 立即發(fā)送無需排隊汉柒,沒法保證交付
}
參數(shù)4: 回調(diào)的Error 若是沒成功, 就返回Error!
- (void)disconnect;
// 斷開連接的方法- (NSProgress*)sendResourceAtURL:(NSURL*)resourceURL withName:(NSString*)resourceName toPeer:(MCPeerID*)peerID withCompletionHandler:(void(^)(NSError*error))completionHandler;
// 用于發(fā)送圖片或者文件, 用于還可以用 progress來監(jiān)控傳送進度!
- (NSOutputStream*)startStreamWithName:(NSString*)streamName toPeer:(MCPeerID*)peerID error:(NSError**)error;
// 用來傳輸流 streamMCSession的代理方法!
方法1 :
- (void)session:(MCSession*)session peer:(MCPeerID*)peerID didChangeState:(MCSessionState)state;
// 用于檢測連接狀態(tài), 可以在這根據(jù)不同的連接狀態(tài)來進行判斷操作 !注: MCSessionState 是個枚舉
typedefNS_ENUM(NSInteger, MCSessionState) {
MCSessionStateNotConnected, // not in the session
MCSessionStateConnecting, // connecting to this peer
MCSessionStateConnected // connected to the session
}
方法2:
- (void)session:(MCSession*)session didReceiveData:(NSData*)data fromPeer:(MCPeerID*)peerID;
// 用于簡單數(shù)據(jù)從這個方法中進行接收! 可以在這個中對數(shù)據(jù)做處理 !方法3
- (void)session:(MCSession*)session didReceiveStream:(NSInputStream*)stream withName:(NSString*)streamName fromPeer:(MCPeerID*)peerID;
// 用于對流 stream 的接收!方法4.1:
- (void)session:(MCSession*)session didStartReceivingResourceWithName:(NSString*)resourceName fromPeer:(MCPeerID*)peerID withProgress:(NSProgress*)progress;
// 已經(jīng)開始從遠端開始接收文件
方法4.2:
- (void)session:(MCSession*)session didFinishReceivingResourceWithName:(NSString*)resourceName fromPeer:(MCPeerID*)peerID atURL:(NSURL*)localURL withError:(NSError*)error
// 已經(jīng)完成接收文件 連接流程圖
{ImgCap}連接流程圖{/ImgCap}
9.以后還有補充的: 關(guān)于傳輸數(shù)據(jù)的! (待續(xù))
- 參考資料:
- MultipeerConnectivity.framework梳理 (詳細, 比較深刻)
- MultipeerConnectivity 點對點連接
- iOS7新技術(shù):如何使用Multipeer Connectivity
- 理解iOS7的Multipeer Connectivity框架 - 第1部分 (超詳細解說, 很適合初學(xué)者!)
- 樓上的英文版 -> Understanding Multipeer Connectivity Framework in iOS 7 – Part 1