2013-09-26 81 views
5

我想要follow the WWDC talk瞭解MultipeerConnectivity框架。經過多次錯誤啓動後,瀏覽器顯示同行,併發出邀請。Multipeer Connectivity:接受邀請(使用內置瀏覽器VC)

但是當我點擊對方設備上的「接受」時,瀏覽器不斷顯示「正在連接」。我認爲MCBrowserViewController照顧了邏輯,我可以放鬆,直到瀏覽器的用戶按下取消或完成,並且委託方法被解僱。我敢打賭,這是明顯的,但它躲過了我。

以下是我希望的相關代碼。我在AppDelegate中有它。不同的委託方法中的NSLog語句會按我所期望的方式被調用,當然除了browserViewControllerDidFinish:中的那個。

請記住,瀏覽器和邀請確實出現,所以東西是正確的!

在@interface ...

@property (strong, nonatomic) MCSession *theSession; 
@property (strong, nonatomic) MCAdvertiserAssistant  *assistant; 
@property (strong, nonatomic) MCBrowserViewController  *browserVC; 

在@implementation

static NSString* const kServiceType = @"eeps-multi"; 

// called from viewDidAppear in the main ViewController 

-(void)  startSession 
{ 
    if (!self.theSession) { 
     UIDevice *thisDevice = [UIDevice currentDevice]; 

     MCPeerID *aPeerID = [[ MCPeerID alloc ] initWithDisplayName: thisDevice.name]; 
     self.theSession = [[ MCSession alloc ] initWithPeer: aPeerID ]; 
     self.theSession.delegate = self; 
    } else { 
     NSLog(@"Session init skipped -- already exists"); 
    } 
} 

// called from viewDidAppear in the main ViewController 

- (void) startAdvertising 
    { 
    if (!self.assistant) { 
     self.assistant = [[MCAdvertiserAssistant alloc] initWithServiceType:kServiceType 
                   discoveryInfo:nil 
                    session:self.theSession ]; 
     self.assistant.delegate = self; 
     [ self.assistant start ]; 
    } else { 
     NSLog(@"Advertiser init skipped -- already exists"); 
    } 
} 

// called from the main ViewController in response to a button press 

- (void) startBrowsing 
{ 
    if (!self.browserVC){ 
     self.browserVC = [[MCBrowserViewController alloc] initWithServiceType:kServiceType 
                     session:self.theSession]; 
     self.browserVC.delegate = self; 
    } else { 
     NSLog(@"Browser VC init skipped -- already exists"); 
    } 

    [ self.window.rootViewController presentViewController:self.browserVC animated:YES completion:nil]; 
} 

提前感謝!

回答

16

多虧了評論者的很好的建議,導致我發現我自己的錯誤。並且這裏是:

如果您實施MCSessionDelegate方法session:didReceiveCertificate:fromPeer:certificateHandler方法,它將攔截對等體嘗試連接到會話。您應該明確批准該方法中的連接或將其註釋掉。

詳細信息和經驗教訓:

的各種委託方法

除了代碼我發現,我做了粗短的實現。一個MCSessionDelegate方法是這樣的一個:

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

} 

擴展@大O克萊爾的建議以上,我開始看所有這些委託方法,以防萬一。當對等點擊AdvertiserAssistant UI中的「接受」按鈕時,就會觸發此事件。

如果不需要,此方法可讓您有機會決定對等方是否合法,而不是連接(使用certificateHandler:)。蘋果說,

你的應用程序應該檢查附近的同行的證書,然後應該決定是否信任該證書。在做出該決定後,您的應用程序應該調用提供的certificateHandler塊,傳遞YES(信任附近的對等)或NO(拒絕它)。

另外,您得到這個提示:

重要:本multipeer連接框架並沒有試圖驗證以任何方式對提供的身份或證書。如果您的委託沒有實施此方法,則所有證書都會自動接受。

當我評論這種方法時,連接經歷了 - 至少解決了這個問題。

+0

非常感謝,這節省了我幾個小時的調試時間。我只是拋出所有委託方法在那裏,以便稍後實施它們,甚至不知道didReceiveCertificate。 – cargath

1

我在使用新的MC框架時並未走完MCBrowserViewController路線,而是從WWDC演示文稿的第51張幻燈片中看到browserViewControllerDidFinish:僅在用戶按下完成時調用。因此,如果您的對等方仍顯示爲「正在連接...」,則此回調可能不是問題所在。

我想知道你是否需要手動將你的對等端連接到會話。您已經設置了MCSession代表,因此我假設您正在實施session:peer:didChangeState。設置一個斷點並注意MCSessionStateMCSessionStateConnected。我不確定的唯一情況是,如果您需要在廣告客戶端,瀏覽器端或兩者上手動處理此問題。如果你能弄清楚框架在哪一步停止處理它,那會很有幫助。

+0

好主意,所以更新:當我更仔細地觀看更多的委託調用(並在下面實現@Alla的建議)時,我發現當設備拒絕連接時,我得到'didChangeState'使**沒有連接**,但在接受它時不會改變。 所以我仍然感到困惑(而且還在尋找)。歡迎任何建議! –

+0

我在這一點上,我的方法是設置一個靜態的可選稱爲currentSession。在遊戲中,我引用這個對象來發送數據包。這樣,當會話報告沒有連接時,我可以將其設置爲零,並且遊戲可以優雅地處理網絡連接失敗。這樣我就不會直接引用瀏覽器會話或廣告會話。 – FrostyL

3

我有同樣的問題,它原來我用的是同一個會話的瀏覽器和廣告商都。分手了會議,但要確保的serviceType是相同的,它會工作像一個魅力

- (void) setUpMultipeer{ 
    // Setup Peer ID 
    self.myPeerID = [[MCPeerID alloc] initWithDisplayName:[UIDevice currentDevice].name]; 

    // Setup Sessions 
    self.advertiseSession = [[MCSession alloc] initWithPeer:self.myPeerID]; 
    self.advertiseSession.delegate = self; 

    self.browserSession = [[MCSession alloc] initWithPeer:self.myPeerID]; 
    self.browserSession.delegate = self; 


    // Setup BrowserVC 
    self.browserVC = [[MCBrowserViewController alloc] initWithServiceType:@"SERVICE_TYPE" session:self.browserSession]; 
    self.browserVC.delegate = self; 

    // Setup Advertiser 
    self.advertiser = [[MCAdvertiserAssistant alloc] initWithServiceType:@"SERVICE_TYPE" discoveryInfo:nil session:self.advertiseSession]; 
    [self.advertiser start]; 
} 
+0

謝謝!試了一下,它不起作用,但幫助我找到了實際問題(下文)。一旦發現工作,我回去嘗試了一個單一的會議,到目前爲止工作得很好。當然,我仍然只是發現工作,所以我可能很快就需要你的建議。隨着事情的進展,我會提交一份報告。 :) –

+1

這一個爲我工作,正在使用[appcoda](http://www.appcoda.com/intro-multipeer-connectivity-framework-ios-programming/)的教程,它使用相同的會話廣告和通信,「完成」按鈕從未被解僱。 – Deano

相關問題