1

我目前有一个视图控制器,指定使用 Apple 的多点连接框架将两个设备连接在一起。一切都很好,并且可以在两个设备之间发送消息。一旦它们两个设备连接并且您点击开始按钮,两个设备都会转换到另一个呈现 SKScene 的视图控制器(这是一个游戏应用程序)。我希望 SKScene 也能够发送和接收消息,但是当转换到新的 VC/SKScene 时,连接会丢失。有没有办法保持视图控制器和 SKScene 之间的连接?

SKView * skView = (SKView *)self.view;
if (!skView.scene) {
    //skView.showsFPS = YES;
    //skView.showsNodeCount = YES;
    //skView.showsPhysics = YES;

    // Create and configure the scene.
    SKScene * scene = [gameMyScene sceneWithSize:skView.bounds.size];
    scene.scaleMode = SKSceneScaleModeAspectFill;
    [scene.userData setObject:[NSNumber numberWithBool:self.isMulti] forKey:@"Game"];
    [scene.userData setObject:[NSNumber numberWithBool:self.isAttack]        forKey:@"Attack"];
    [scene.userData setObject:self.appD forKey:@"AppDel"]; 
    // Present the scene.
    [skView presentScene:scene];
}

这就是我的场景在名为“gameViewController”的视图控制器的 viewWillLayoutSubviews 中呈现的方式。处理连接的视图控制器称为“ConnectGameViewController”,当按下开始按钮时它会转换为“gameViewController”。

4

1 回答 1

0

我知道这是一个较老的问题,但我很难找到一个明确的解决方案,所以这是我发现的:

  1. 创建一个可可触摸类(MPC 类)来处理您的会话、peerID... 同时导入 MultipeerConnectivity 并将您的类定义为 NSObject 和 MCSessionDelegate:

.

import UIKit
import MultipeerConnectivity
class mpc: NSObject, MCSessionDelegate {

    var peerID:MCPeerID!
    var session:MCSession!
    var browser:MCBrowserViewController!
    var advertiser:MCAdvertiserAssistant? = nil

    func setupPeerWithDisplayName (displayName:String){
        peerID = MCPeerID(displayName: displayName)
    }

    func setupSession(){
        session = MCSession(peer: peerID)
        session.delegate = self
    }

    func setupBrowser(){
        browser = MCBrowserViewController(serviceType: "ADDCONNECTIONNAME", session: session)

    }

    func advertiseSelf(advertise:Bool){
        if advertise{
            advertiser = MCAdvertiserAssistant(serviceType: "ADDCONNECTIONNAME", discoveryInfo: nil, session: session)
            advertiser!.start()
        }else{
            advertiser!.stop()
            advertiser = nil
        }
    }

    func sendData (variable: String, data: AnyObject, sendTo: AnyObject){
        //Send Data
        let archived = NSKeyedArchiver.archivedDataWithRootObject([variable : data])
        do{
            try session.sendData(archived, toPeers: session.connectedPeers, withMode: .Unreliable)
        }catch _ as NSError {
            print("Error: Cannot send Message.")
        }

    }

    func session(session: MCSession, peer peerID: MCPeerID, didChangeState state: MCSessionState) {

    }

    func session(session: MCSession, didReceiveData data: NSData, fromPeer peerID: MCPeerID) {
    //Receive Data
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
            let archived = NSKeyedUnarchiver.unarchiveObjectWithData(data) as! Dictionary<String, AnyObject>

            if archived.indexForKey("Variable1") != nil {
                let data = archived["Variable1"] //as! [String],Int,Bool...

            }else if archived.indexForKey("Variable2") != nil {
                let data = archived["Variable2"] //as! [String],Int,Bool...
            }
        }   
    }

    func session(session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, atURL localURL: NSURL, withError error: NSError?) {

    }

    func session(session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, withProgress progress: NSProgress) {

    }

    func session(session: MCSession, didReceiveStream stream: NSInputStream, withName streamName: String, fromPeer peerID: MCPeerID) {

    }  
}
  1. 在 App Delegate 中引用您在上面创建的 MPC 类:

     var MPC:mpc = mpc()
    
  2. 在您的第一个视图控制器中,全球化对您的 App Delegate 的引用:

    var appDelegate:AppDelegate!
    
  3. 将以下代码放入您的 viewDidLoad() 中。它只会运行一次,否则它将重置连接:

    func willRunOnce() -> () {
        struct TokenContainer {
            static var token : dispatch_once_t = 0
        }
    
        dispatch_once(&TokenContainer.token) {
            appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
            appDelegate.MPC.setupPeerWithDisplayName(UIDevice.currentDevice().name)
            appDelegate.MPC.setupSession()
            appDelegate.MPC.advertiseSelf(true)
    }
    

    }

  4. 最后,您可以使用以下格式调用 MPC 类中的任何函数或变量:

    appDelegate.MPC.//FUNCTION(),VARIABLE...
    
于 2016-08-05T09:19:48.563 回答