【发布时间】:2014-06-04 05:17:07
【问题描述】:
我正在尝试使用多点连接框架建立一对一的点对点连接。当我向附近的对等方发送邀请时,该设备已连接(有时需要很长时间才能连接),并且发送请求的对等方总是需要很长时间才能将其状态更改为已连接,一旦立即连接,它就会断开连接从会话。我尝试调试问题但没有发现任何问题,不知道发生了什么问题,如果我遗漏任何内容或代码中有任何错误,请告诉我。
下面给出的是相同的代码sn-p。
MPCHandler.m
#define DidChangeStateNotification @"E_DidChangeStateNotification"
#define DidReceiveDataNotification @"E_DidReceiveDataNotification"
#define DidInviteNotification @"E_DidInvitedNotification"
#define DidReceivedInvetationNotification @"E_DidReceivedInvetationNotification"
static NSString * const EServiceType = @"E-service";
@interface MPCHandler ()
@property AppDelegate *appDelegate;
@end
@implementation MPCHandler
- (void)setupPeerWithDisplayName:(NSString *)displayName {
self.appDelegate = [[UIApplication sharedApplication] delegate];
self.peerID = [[MCPeerID alloc] initWithDisplayName:displayName];
self.connectedPeers = [NSMutableArray array];
self.foundPeers = [NSMutableArray array];
self.invitedPeers = [NSMutableArray array];
}
- (void)setupSession {
self.session = [[MCSession alloc] initWithPeer:self.peerID securityIdentity:nil encryptionPreference:MCEncryptionNone];
self.session.delegate = self;
}
- (void)setupBrowser {
self.browser = [[MCNearbyServiceBrowser alloc] initWithPeer:self.peerID serviceType:EServiceType];
self.browser.delegate = self;
}
- (void)advertiseSelf:(BOOL)advertise {
if (advertise) {
self.advertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:self.peerID discoveryInfo:nil serviceType:EServiceType];
self.advertiser.delegate = self;
[self.advertiser startAdvertisingPeer];
} else {
[self.advertiser stopAdvertisingPeer];
self.advertiser = nil;
}
}
#pragma MCSessionDelegate methods
- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state {
NSDictionary *userInfo = @{ @"peerID": peerID,
@"state" : @(state) };
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:DidChangeStateNotification
object:nil
userInfo:userInfo];
});
}
- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID {
NSDictionary *userInfo = @{ @"data": data,
@"peerID": peerID };
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:DidReceiveDataNotification
object:nil
userInfo:userInfo];
});
}
- (void)session:(MCSession *)session didReceiveCertificate:(NSArray *)certificate fromPeer:(MCPeerID *)peerID certificateHandler:(void (^)(BOOL))certificateHandler{
certificateHandler(YES);
}
#pragma MCNearbyServiceAdvertiserDelegate 方法
// Incoming invitation request. Call the invitationHandler block with YES and a valid session to connect the inviting peer to the session.
- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler{
NSDictionary *info =[NSDictionary dictionaryWithObject:peerID.displayName forKey:@"displayName"];
NSLog(@"%@ Received Invetation from : %@",self.peerID.displayName,peerID.displayName);
invitationHandler(YES,self.session);
[self.connectedPeers addObject:peerID];
self.invited = NO;
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:DidReceivedInvetationNotification
object:nil
userInfo:info];
});
} #pragma MCNearbyServiceBrowserDelegate 方法
// Found a nearby advertising peer
- (void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo: (NSDictionary *)info{
// NSLog(@"Peer : %@ found.",peerID.displayName);
// if (![self.peerID isEqual:peerID]) {
NSLog(@"%@ Found Peer : %@",self.peerID.displayName,peerID.displayName);
[self.foundPeers addObject:peerID];
if (![self.connectedPeers containsObject:peerID])
{
if ([self.invitedPeers count] == 0 && [self.session.connectedPeers count]==0)
{
NSLog(@"%@ Invited Peer : %@",self.peerID.displayName,peerID.displayName);
[self.invitedPeers addObject:peerID];
[browser invitePeer:peerID
toSession:self.session
withContext:[@"Empath" dataUsingEncoding:NSUTF8StringEncoding]
timeout:0];
// [browser stopBrowsingForPeers];
self.invited = YES;
NSDictionary *userInfo = @{ @"peerID": peerID };
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:DidInviteNotification
object:nil
userInfo:userInfo];
});
}
}
// }
}
// A nearby peer has stopped advertising
- (void)browser:(MCNearbyServiceBrowser *)browser lostPeer:(MCPeerID *)peerID{
[self.foundPeers removeObject:peerID];
[self.invitedPeers removeAllObjects];
[browser startBrowsingForPeers];
}
- (void)browser:(MCNearbyServiceBrowser *)browser didNotStartBrowsingForPeers:(NSError *)error
{
NSLog( @"Unable to start browsing for peers. Error: %@", error );
}
ViewController.m
#define DidChangeStateNotification @"E_DidChangeStateNotification"
#define DidReceiveDataNotification @"E_DidReceiveDataNotification"
#define DidInviteNotification @"E_DidInvitedNotification"
#define DidReceivedInvetationNotification @"E_DidReceivedInvetationNotification"
@interface ViewController ()
@property (nonatomic, strong) AppDelegate *appDelegate;
@end
@implementation ViewController
@synthesize txtMessage;
@synthesize tvHistory;
@synthesize btnSend;
@synthesize lblName;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
// self.appDelegate.connectedPeers = [NSMutableArray array];
// self.appDelegate.foundPeers = [NSMutableArray array];
[self AddObservers];
[self setUserInteraction:NO];
[self.lblName setText:@""];
[self.btnSend setUserInteractionEnabled:NO];
[self performSelector:@selector(advertisePeer) withObject:nil afterDelay:0.0];
}
-(void) AddObservers{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleReceivedDataWithNotification:)
name:DidReceiveDataNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(peerChangedStateWithNotification:)
name:DidChangeStateNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(receivedInvetationWithNotification:)
name:DidReceivedInvetationNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(peerInvitedWithNotification:)
name:DidInviteNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(sessionDidTimeout:) name:kSessionDidTimeoutNotification object:nil];
}
-(void) advertisePeer{
[self setUserInteraction:NO];
[self.lblName setText:@""];
[self.appDelegate.mpcHandler setupPeerWithDisplayName:[UIDevice currentDevice].name];
[self.appDelegate.mpcHandler setupSession];
[self.appDelegate.mpcHandler advertiseSelf:YES];
[self.btnSend setUserInteractionEnabled:YES];
}
- (IBAction)searchAndConnectPeer:(id)sender{
[self.lblName setText:@"Searching..."];
if (self.appDelegate.mpcHandler.session != nil) {
[[self.appDelegate mpcHandler] setupBrowser];
[[[self.appDelegate mpcHandler] browser] startBrowsingForPeers];
}
}
- (IBAction)sendMessage:(id)sender{
NSString *messageToSend = [txtMessage text];
NSUInteger len = 0;
if ([messageToSend length]) {
NSData *messageAsData = [messageToSend dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
[self.appDelegate.mpcHandler.session sendData:messageAsData
toPeers:self.appDelegate.mpcHandler.session.connectedPeers
withMode:MCSessionSendDataReliable
error:&error];
// If any error occurs, just log it.
// Otherwise set the following couple of flags to YES, indicating that the current player is the creator
// of the game and a game is in progress.
len = [[tvHistory text] length];
if (error != nil) {
NSLog(@"%@", [error localizedDescription]);
[self.tvHistory setText:[NSString stringWithFormat:@"%@",[error localizedDescription]]];
} else{
NSString *history = [NSString stringWithFormat:@"Me : %@\n\n",messageToSend];
[self.tvHistory setText:[self.tvHistory.text stringByAppendingString:history]];
}
}
[self.txtMessage setText:@""];
[self.tvHistory scrollRangeToVisible:NSMakeRange([self.tvHistory.text length], len)];
}
- (void)peerInvitedWithNotification:(NSNotification *)notification{
[self setUserInteraction:NO];
MCPeerID *peerID = [[notification userInfo] objectForKey:@"peerID"];
[self.lblName setText:[NSString stringWithFormat:@"Connecting to %@...",peerID.displayName]];
}
- (void)receivedInvetationWithNotification:(NSNotification *)notification{
[self setUserInteraction:YES];
NSString *name = [[notification userInfo] objectForKey:@"displayName"];
[self.lblName setText:[NSString stringWithFormat:@"Connected : %@",name]];
}
- (void)peerChangedStateWithNotification:(NSNotification *)notification {
// Get the state of the peer.
int state = [[[notification userInfo] objectForKey:@"state"] intValue];
MCPeerID *peerID = [[notification userInfo] objectForKey:@"peerID"];
// We care only for the Connected and the Not Connected states.
// The Connecting state will be simply ignored.
if (state == MCSessionStateConnected) {
// We'll just display all the connected peers (players) to the text view.
NSString *allPlayers = @"Connected : ";
allPlayers = [allPlayers stringByAppendingString:[NSString tringWithFormat:@"%@",peerID.displayName]];
[self.lblName setText:allPlayers];
[self setUserInteraction:YES];
NSLog(@"%@...",allPlayers);
// // Fire up the timer upon first event
// if(!_idleTimer) {
// [self resetIdleTimer];
// }
}else if (state == MCSessionStateConnecting){
[self setUserInteraction:NO];
[self.lblName setText:[NSString stringWithFormat:@"Connecting to %@...",peerID.displayName]];
NSLog(@"Connecting %@...",peerID.displayName);
}else if (state == MCSessionStateNotConnected){
NSLog(@"Disconnected %@...",peerID.displayName);
// [self sessionDidTimeout:nil];
}
}
-(void) setUserInteraction:(BOOL)enabled{
[self.btnSend setUserInteractionEnabled:enabled];
[self.txtMessage setUserInteractionEnabled:enabled];
}
- (void)handleReceivedDataWithNotification:(NSNotification *)notification {
// Get the user info dictionary that was received along with the notification.
NSDictionary *userInfoDict = [notification userInfo];
// Convert the received data into a NSString object.
NSData *receivedData = [userInfoDict objectForKey:@"data"];
NSString *message = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
// Keep the sender's peerID and get its display name.
MCPeerID *senderPeerID = [userInfoDict objectForKey:@"peerID"];
NSString *senderDisplayName = senderPeerID.displayName;
// Add this guess to the history text view.
NSUInteger len = [[tvHistory text] length];
NSString *history = [NSString stringWithFormat:@"%@ : %@\n\n", senderDisplayName, message];
[self.tvHistory setText:[self.tvHistory.text stringByAppendingString:history]];
[self.tvHistory scrollRangeToVisible:NSMakeRange([self.tvHistory.text length], len)];
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
- (void)resetIdleTimer
{
if (_idleTimer) {
[_idleTimer invalidate];
}
// Schedule a timer to fire in kApplicationTimeoutInMinutes * 60
int timeout = kSessionTimeoutInSeconds;
_idleTimer = [NSTimer scheduledTimerWithTimeInterval:timeout
target:self
selector:@selector(idleTimerExceeded)
userInfo:nil
repeats:NO];
}
- (void)idleTimerExceeded {
/* Post a notification so anyone who subscribes to it can be notified when
* the application times out */
[[NSNotificationCenter defaultCenter]
postNotificationName:kSessionDidTimeoutNotification object:nil];
}
- (void) sessionDidTimeout:(NSNotification *) notif {
// [self setUserInteraction:NO];
//
// [self.lblName setText:@"Session expired..."];
//
// NSLog(@"============================Session Expired...=====================");
//
// [[[self.appDelegate mpcHandler] session] disconnect];
//
// if ([[[self appDelegate]mpcHandler] invited]) {
// [self performSelector:@selector(advertisePeer) withObject:nil afterDelay:0.0];
// [self performSelector:@selector(searchAndConnectPeer:) withObject:nil afterDelay:1.0];
// }
}
【问题讨论】:
-
任何人都可以在上面指导我
-
您同时浏览和投放广告。看看这个 SO 问题:stackoverflow.com/questions/19469984/…
标签: ios objective-c bluetooth multipeer-connectivity