您的位置:首页 > 其它

利用Multipeer Connectivity框架进行WiFi传输

2016-04-27 15:27 639 查看

什么是MultipeerConnectivity?

在iOS7中,引入了一个全新的框架——MultipeerConnectivity(多点连接)。利用MultipeerConnectivity框架,即使在没有连接到WiFi(WLAN)或移动网络(xG)的情况下,距离较近的Apple设备(iMac/iPad/iPhone)之间可基于蓝牙和WiFi(P2PWiFi)技术进行发现和连接实现近场通信。

MultipeerConnectivity扩充的功能与利用AirDrop传输文件非常类似,可以将其看作AirDrop不能直接使用的补偿,代价是需要自己实现。

本Demo主要用到4个类:

MCBrowserViewController:MCBrowserViewController继承自UIViewController,提供了基本的UI应用框架。

MCAdvertiserAssistant、MCAdvertiserAssistant为针对Advertiser封装的管理助手,主要处理广播信息。

MCSession:类似TCP链接中的socket。创建MCSession时,需指定自身MCPeerID,类似bind。

MCPeerID:类似sockaddr,用于标识连接的两端endpoint,通常是昵称或设备名称。

1、简单地建立一个界面,主要有连接和发送2个UIButton。

create_button.png

2、MultipeerConnectivity框架初始化这4个类。

#pragmamark-WifiSharingMethods
-(void)setUpMultipeer
{
//SetuppeerID
self.myPeerID=[[MCPeerIDalloc]initWithDisplayName:[UIDevicecurrentDevice].name];

//Setupsession
self.mySession=[[MCSessionalloc]initWithPeer:self.myPeerID];
self.mySession.delegate=self;

//SetupBrowserViewController
self.browserVC=[[MCBrowserViewControlleralloc]initWithServiceType:@"chat"session:self.mySession];
self.browserVC.delegate=self;

//SetupAdvertiser
self.advertiser=[[MCAdvertiserAssistantalloc]initWithServiceType:@"chat"discoveryInfo:nilsession:self.mySession];
[self.advertiserstart];
}

-(void)showBrowserVC
{
[selfpresentViewController:self.browserVCanimated:YEScompletion:nil];
}

-(void)dismissBrowserVC
{
[self.browserVCdismissViewControllerAnimated:YEScompletion:^(void){
[selfinvokeAlertMethod:@"连接成功"Body:@"Bothdeviceconnectedsuccessfully."Delegate:nil];
}];
}

-(void)stopWifiSharing:(BOOL)isClear
{
if(isClear&&self.mySession!=nil){
[self.mySessiondisconnect];

[self.mySessionsetDelegate:nil];

self.mySession=nil;

self.browserVC=nil;
}
}


3、MCBrowserViewController代理方法

#pragmamarksMCBrowserViewControllerDelegate
//点击完成
-(void)browserViewControllerDidFinish:(MCBrowserViewController*)browserViewController
{
[selfdismissBrowserVC];
[marrReceiveDataremoveAllObjects];
}

//点击取消
-(void)browserViewControllerWasCancelled:(MCBrowserViewController*)browserViewController
{
[selfdismissBrowserVC];
}


4、MCSession代理方法

主要处理发送方传递的文件或者信息

//Receiveddatafromremotepeer
-(void)session:(MCSession*)sessiondidReceiveData:(NSData*)datafromPeer:(MCPeerID*)peerID
{
NSLog(@"datareceiveddddd:%lu",(unsignedlong)data.length);

if(data.length>0){
if(data.length<2){
noOfDataSend++;
NSLog(@"noofdatasend:%zd",noOfDataSend);
NSLog(@"arraycount:%zd",marrFileData.count);
if(noOfDataSend<([marrFileDatacount])){
[self.mySessionsendData:[marrFileDataobjectAtIndex:noOfDataSend]toPeers:[self.mySessionconnectedPeers]withMode:MCSessionSendDataReliableerror:nil];
}else{
[self.mySessionsendData:[@"FileTransferDone"dataUsingEncoding:NSUTF8StringEncoding]toPeers:[self.mySessionconnectedPeers]withMode:MCSessionSendDataReliableerror:nil];
}
}else{
if([[[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding]isEqualToString:@"FileTransferDone"]){
[selfappendFileData];
}else{
[self.mySessionsendData:[@"1"dataUsingEncoding:NSUTF8StringEncoding]toPeers:[self.mySessionconnectedPeers]withMode:MCSessionSendDataReliableerror:nil];
[marrReceiveDataaddObject:data];
}
}
}
}

//Receivedabytestreamfromremotepeer
-(void)session:(MCSession*)sessiondidReceiveStream:(NSInputStream*)streamwithName:(NSString*)streamNamefromPeer:(MCPeerID*)peerID
{
NSLog(@"didreceivestream");
}

//Startreceivingaresourcefromremotepeer
-(void)session:(MCSession*)sessiondidStartReceivingResourceWithName:(NSString*)resourceNamefromPeer:(MCPeerID*)peerIDwithProgress:(NSProgress*)progress
{
NSLog(@"startreceiving");
}

//Finishedreceivingaresourcefromremotepeerandsavedthecontentinatemporarylocation-theappisresponsibleformovingthefiletoapermanentlocationwithinitssandbox
-(void)session:(MCSession*)sessiondidFinishReceivingResourceWithName:(NSString*)resourceNamefromPeer:(MCPeerID*)peerIDatURL:(NSURL*)localURLwithError:(NSError*)error
{
NSLog(@"finishreceivingresource");
}

-(void)session:(MCSession*)sessionpeer:(MCPeerID*)peerIDdidChangeState:(MCSessionState)state
{
NSLog(@"changestate:%zd",state);
}


5、发送图片(此Demo只是简单地做了个收发图片的Demo,此框架可实现的功能当然不止这么简单。)

-(void)sendData
{
[marrFileDataremoveAllObjects];

NSData*sendData=UIImagePNGRepresentation([UIImageimageNamed:@"test2.png"]);
NSUIntegerlength=[sendDatalength];
NSUIntegerchunkSize=100*1024;
NSUIntegeroffset=0;
do{
NSUIntegerthisChunkSize=length-offset>chunkSize?chunkSize:length-offset;
NSData*chunk=[NSDatadataWithBytesNoCopy:(char*)[sendDatabytes]+offset
length:thisChunkSize
freeWhenDone:NO];
NSLog(@"chunklength:%lu",(unsignedlong)chunk.length);

[marrFileDataaddObject:[NSDatadataWithData:chunk]];
offset+=thisChunkSize;
}while(offset<length);

noOfdata=[marrFileDatacount];
noOfDataSend=0;

if([marrFileDatacount]>0){
[self.mySessionsendData:[marrFileDataobjectAtIndex:noOfDataSend]toPeers:[self.mySessionconnectedPeers]withMode:MCSessionSendDataReliableerror:nil];
}
}

-(void)appendFileData
{
NSMutableData*fileData=[NSMutableDatadata];

for(inti=0;i<[marrReceiveDatacount];i++){
[fileDataappendData:[marrReceiveDataobjectAtIndex:i]];
}

[fileDatawriteToFile:[NSStringstringWithFormat:@"%@/Image.png",[NSHomeDirectory()stringByAppendingPathComponent:@"Documents"]]atomically:YES];

UIImageWriteToSavedPhotosAlbum([UIImageimageWithData:fileData],self,@selector(image:didFinishSavingWithError:contextInfo:),nil);
}

-(void)image:(UIImage*)imagedidFinishSavingWithError:(NSError*)errorcontextInfo:(void*)contextInfo
{
if(!error){
[selfinvokeAlertMethod:@"发送成功"Body:@"图片已保存到手机相册"Delegate:nil];
}
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: