多点连接 API 的使用
SDK及版本信息
MultipeerConnectivity.frameworkiOS 7.0OS X 10.10
可以看到基于MC可以做到电脑与手机的通信。 了解了其能力与SDK相关信息后,下面我们看看工作流程: 使设备可被发现--->浏览设备,建立连接--->传输数据 。 关于使用大家可以看看参考资源与 MCDemo, 这里只是做一个代码导读。
1、初始化 MCPeerID 及 MCSession, MCPeerID 用来唯一的标识设备, MCSession 是通信的基础:
1
2
3
4
5
6
|
-(
void
)setupPeerAndSessionWithDisplayName:(NSString *)displayName{
_peerID = [[MCPeerID alloc] initWithDisplayName:displayName];
_session = [[MCSession alloc] initWithPeer:_peerID];
_session.delegate = self;
}
|
2、广播设备,使设备可以被发现:
1
2
3
4
5
6
7
8
9
10
11
12
|
-(
void
)advertiseSelf:(BOOL)shouldAdvertise{
if
(shouldAdvertise) {
_advertiser = [[MCAdvertiserAssistant alloc] initWithServiceType:
@chat
-files
discoveryInfo:nil
session:_session];
[_advertiser start];
}
else
{
[_advertiser stop];
_advertiser = nil;
}
}
|
3、浏览“局域网”中的设备,并建立连接:
1
2
3
|
-(
void
)setupMCBrowser{
_browser = [[MCBrowserViewController alloc] initWithServiceType:
@chat
-files session:_session];
}
|
MCBrowserViewController实例化后,直接弹出,这个类内部会负责查找设备并建立连接。 对于有界面定制化需求的,也可以通过相关接口实现类似的功能。
4、发送消息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
-(
void
)sendMyMessage{
NSData *dataToSend = [_txtMessage.text dataUsingEncoding:NSUTF8StringEncoding];
NSArray *allPeers = _appDelegate.mcManager.session.connectedPeers;
NSError *error;
[_appDelegate.mcManager.session sendData:dataToSend
toPeers:allPeers
withMode:MCSessionSendDataReliable
error:&error];
if
(error) {
NSLog(@%@, [error localizedDescription]);
}
[_tvChat setText:[_tvChat.text stringByAppendingString:[NSString stringWithFormat:
@I
wrote:
%@
, _txtMessage.text]]];
[_txtMessage setText:@];
[_txtMessage resignFirstResponder];
}
|
发送消息时有个选项:MCSessionSendDataReliable,MCSessionSendDataUnreliable 但是不管是可靠还是不可靠,数据都是基于 UDP 进行传输的。
5、接收消息:
1
2
3
4
5
6
7
8
9
|
-(
void
)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID{
NSDictionary *dict = @{
@data
: data,
@peerID
: peerID
};
[[NSNotificationCenter defaultCenter] postNotificationName:
@MCDidReceiveDataNotification
object:nil
userInfo:dict];
}
|
消息的接收是通过 MCSession 的回调方法进行的。 MCSession的回调方法非常重要, 设备状态的改变、消息的接收、资源的接收、流的接收都是通过这个回调进行通知的。
6、发送资源,资源可以是本地的URL,也可以是 Http 链接:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
-(
void
)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
if
(buttonIndex != [[_appDelegate.mcManager.session connectedPeers] count]) {
NSString *filePath = [_documentsDirectory stringByAppendingPathComponent:_selectedFile];
NSString *modifiedName = [NSString stringWithFormat:@%
@_
%@, _appDelegate.mcManager.peerID.displayName, _selectedFile];
NSURL *resourceURL = [NSURL fileURLWithPath:filePath];
dispatch_async(dispatch_get_main_queue(), ^{
NSProgress *progress = [_appDelegate.mcManager.session sendResourceAtURL:resourceURL
withName:modifiedName
toPeer:[[_appDelegate.mcManager.session connectedPeers] objectAtIndex:buttonIndex]
withCompletionHandler:^(NSError *error) {
if
(error) {
NSLog(
@Error
: %@, [error localizedDescription]);
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:
@MCDemo
message:
@File
was successfully sent.
delegate:self
cancelButtonTitle:nil
otherButtonTitles:
@Great
!, nil];
[alert performSelectorOnMainThread:
@selector
(show) withObject:nil waitUntilDone:NO];
[_arrFiles replaceObjectAtIndex:_selectedRow withObject:_selectedFile];
[_tblFiles performSelectorOnMainThread:
@selector
(reloadData)
withObject:nil
waitUntilDone:NO];
}
}];
//NSLog(@*** %f, progress.fractionCompleted);
[progress addObserver:self
forKeyPath:
@fractionCompleted
options:NSKeyValueObservingOptionNew
context:nil];
});
}
}
|
可以通过 NSProgress查询相关状态。
7、接收资源:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
-(
void
)session:(MCSession *)session didStartReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID withProgress:(NSProgress *)progress{
NSDictionary *dict = @{
@resourceName
: resourceName,
@peerID
: peerID,
@progress
: progress
};
[[NSNotificationCenter defaultCenter] postNotificationName:
@MCDidStartReceivingResourceNotification
object:nil
userInfo:dict];
dispatch_async(dispatch_get_main_queue(), ^{
[progress addObserver:self
forKeyPath:
@fractionCompleted
options:NSKeyValueObservingOptionNew
context:nil];
});
}
|