MultiPeer 框架委托未触发/运行(无 UI)

Posted

技术标签:

【中文标题】MultiPeer 框架委托未触发/运行(无 UI)【英文标题】:MultiPeer Framework Delegates Not Firing/Running (No UI) 【发布时间】:2014-05-31 14:34:06 【问题描述】:

我已经被这个问题困扰了一段时间。我正在尝试测试多对等框架。我正在尝试在没有 UI 的情况下做到这一点。换句话说,我正在通过代码手动邀请其他同行。我希望能够启动应用程序,并且对等点会自动开始寻找彼此并连接。

为此,我设置了一个名为 SideWaysManager 的类,如下所示:

/**
  SidewaysManager.m
*/

#import "SidewaysManager.h"
#import "EPBmyConfig.h"

@implementation SidewaysManager

    NSString *databasePath;

    MCSession *currentSession;

    MCNearbyServiceBrowser *nearbyBrowser;

    MCNearbyServiceAdvertiser *nearbyAdvertiser;

    NSString *serviceType;




- (id) init


    self = [super init];

    if(self)
    

        EPBmyConfig *configInfo = [EPBmyConfig instance];

        NSString *assetID = [configInfo getAssetID];

        NSString *useageLocation = [configInfo getUseageLocation];

        NSString *peerDisplayName = [@"PCTouchPad-" stringByAppendingString:assetID];

        if(![useageLocation isEqualToString:@""])
        
            peerDisplayName = [peerDisplayName stringByAppendingString: [NSString stringWithFormat:@"-%@", useageLocation]];
        

        MCPeerID *localPeerID = [[MCPeerID alloc] initWithDisplayName:peerDisplayName];

        currentSession = [[MCSession alloc] initWithPeer:localPeerID];
        currentSession.delegate = self;

        serviceType = @"EPB-Session";

        nearbyBrowser = [[MCNearbyServiceBrowser alloc] initWithPeer:localPeerID serviceType:serviceType];
        nearbyBrowser.delegate = self;

        nearbyAdvertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:localPeerID discoveryInfo:nil serviceType:serviceType];
        nearbyAdvertiser.delegate = self;


        NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

        NSString *documentDir = [documentPaths objectAtIndex:0];

        databasePath = [documentDir stringByAppendingString:@"/voterdb_Prod"];

        [nearbyAdvertiser startAdvertisingPeer];

        [nearbyBrowser startBrowsingForPeers];

        return self;
    

    return self;



/**

 Session delegates
 */

// Remote peer changed state
- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state

    if(state == MCSessionStateConnected)
    
        [nearbyAdvertiser stopAdvertisingPeer];
        [nearbyBrowser stopBrowsingForPeers];

        NSLog(@"Peer connected to session");
    
    else if(state == MCSessionStateNotConnected)
    
        NSLog(@"Peer not connected");
    


// Received data from remote peer
- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID



// Start receiving a resource from remote peer
- (void)session:(MCSession *)session didStartReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID withProgress:(NSProgress *)progress



// Finished receiving a resource from remote peer and saved the content in a temporary location - the app is responsible for moving the file to a permanent location within its sandbox
- (void)session:(MCSession *)session didFinishReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID atURL:(NSURL *)localURL withError:(NSError *)error



- (void)session:(MCSession *)session didReceiveCertificate:(NSArray *)certificate fromPeer:(MCPeerID *)peerID certificateHandler:(void(^)(BOOL accept))certificateHandler

    NSLog(@"Received certificate");
    certificateHandler(YES);


- (void)session:(MCSession *)session didReceiveStream:(NSInputStream *)stream withName:(NSString *)streamName fromPeer:(MCPeerID *)peerID

    stream.delegate = self;

    [stream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [stream open];





/**
 MCBrowser Delegates
 */

// Found a nearby advertising peer
- (void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary *)info

    NSLog(@"Found Peer");

    [browser invitePeer:peerID toSession:currentSession withContext:nil timeout:0];


// A nearby peer has stopped advertising
- (void)browser:(MCNearbyServiceBrowser *)browser lostPeer:(MCPeerID *)peerID

    NSLog(@"Lost Peer");




/**Advertising Delegates
 */

- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler

    invitationHandler(YES, currentSession);



// Advertising did not start due to an error
- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didNotStartAdvertisingPeer:(NSError *)error

    NSLog(@"Did not start advertising");



@end

这是我的 SideWaysManager.h 文件:

#import <Foundation/Foundation.h>
#import <MultipeerConnectivity/MultipeerConnectivity.h>

@interface SidewaysManager : NSObject <MCNearbyServiceAdvertiserDelegate, MCNearbyServiceBrowserDelegate, MCSessionDelegate, NSStreamDelegate>


@end

然后我在我的 AppDelegate 类中初始化这个类。但是,出于某种原因,上面的委托方法中有 NONE 运行。任何熟悉该框架的人都可以帮助我或知道为什么这门课什么都没有发生吗?我将不胜感激。

【问题讨论】:

【参考方案1】:

我创建了一个基于单一视图应用程序模板的项目。我将您的 SideWaysManager 代码添加到项目中。为了使其编译,我删除了 EPBmyConfig 导入并修复了编译错误,如下所示:

//     EPBmyConfig *configInfo = [EPBmyConfig instance]; 

//     NSString *assetID = [configInfo getAssetID];

//     NSString *useageLocation = [configInfo getUseageLocation]; 

       NSString *peerDisplayName = @"PCTouchPad-Test";

//    if(![useageLocation isEqualToString:@""])
//    
//        peerDisplayName = [peerDisplayName stringByAppendingString: [NSString stringWithFormat:@"-%@", useageLocation]];
//    

      MCPeerID *localPeerID = [[MCPeerID alloc] initWithDisplayName:peerDisplayName];

在我的 iPhone 和模拟器上运行代码,调用了委托方法并创建了一个会话。所以看起来你的 Multipeer Connectivity 对象的设置没问题。

如何在 AppDelegate 中创建 SideWaysManager?

我就是这样做的:

@interface PFAppDelegate ()

@property (strong, nonatomic) SidewaysManager *manager;

@end


@implementation PFAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

    self.manager = [[SidewaysManager alloc]init];
    return YES;

重要的是,您的 AppDelegate 类包含对管理器的引用,否则会在 didFinishLaunchingWithOptions 返回后立即取消分配。这可以解释您的代码中没有发生任何事情。

或者,它们可能是创建对等显示名称(基本上是我注释掉的东西)的问题。

【讨论】:

非常感谢您将它加载到您的项目中并试一试。我实际上能够找到解决方案,但忘记在这里更新它。是的,我的问题是我没有横向管理器的属性或实例变量。因为它是一个局部变量,所以它立即被释放。 我要感谢你,因为你得到了完全相同的解决方案并且你加载了我的文件。

以上是关于MultiPeer 框架委托未触发/运行(无 UI)的主要内容,如果未能解决你的问题,请参考以下文章

Peer(MultiPeer Connectivity)已连接但未存储在 connectedPeers

didBeginContact 委托方法未触发 ARKit 碰撞检测

NSFetchedResultsController 委托方法未针对这些更改触发

NSFetchedResultsController 委托方法在 mergeChangesFromContextDidSaveNotification 后未触发

AngularJS模板中的元素仍未触发jQuery委托事件

MultiPeer 框架避免使用 MCBrowserView?