2017-03-23 1 views
0

Je suis en train de faire une application de test où vous pouvez dessiner et envoyer des images en utilisant une connectivité multipeer. Il existe un contrôleur de vue de connexion pour l'hôte et un contrôleur séparé pour les autres homologues. Lorsque les pairs se seront connectés, l'hôte jouera le jeu et tous les contrôleurs de vue des pairs iront à la VC de dessin prouvant qu'ils sont connectés. Cependant, quand je veux envoyer des données dans le dessin VC, la console dit que les pairs connectés la session est 0 même s'il y a des pairs connectés. Je peux tester cela parce que quand la déconnexion je reçois l'avis de changement d'état dans la console. Alors quelqu'un peut-il me montrer ce qui ne va pas avec mon code? Merci.Swift 3 - Passer des variables et des fonctions entre les contrôleurs de vue

Ps Je suis relativement novice dans le développement iOS, mon code peut donc présenter des problèmes majeurs.

Connexion Gestionnaire de fichiers:

import UIKit 
import MultipeerConnectivity 

class ConnectionManager: NSObject { 

var localPeerId = MCPeerID(displayName: UIDevice.current.name) 
var service = "PI-Connect" 
var session: MCSession 
var browser: MCNearbyServiceBrowser 
var advertiser: MCAdvertiserAssistant 
var connectionDelegate: ConnectionManagerDelegate? 
var serviceDelegate: ServiceManagerDelegate? 
var gameStarted : Bool 

override init() { 

    self.session = MCSession(peer: self.localPeerId) 
    self.browser = MCNearbyServiceBrowser(peer: self.localPeerId, serviceType: service) 
    self.advertiser = MCAdvertiserAssistant(serviceType: service, discoveryInfo: nil, session: session) 
    gameStarted = false 

    super.init() 

    self.session.delegate = self 
    self.browser.delegate = self 
    self.advertiser.delegate = self 

} 

func startBrowsing() { 
    browser.startBrowsingForPeers() 
} 
func stopBrowsing() { 
    browser.stopBrowsingForPeers() 
} 
func startAdvertising() { 
    advertiser.start() 
} 
func stopAdvertising() { 
    advertiser.stop() 
} 

func startGame(gameStarted: String) { 
    NSLog("%@", "Start game: \(gameStarted) to \(session.connectedPeers.count) peers") 
    if session.connectedPeers.count > 0 { 
     do { 
      try session.send(gameStarted.data(using: .utf8)!, toPeers: session.connectedPeers, with: .reliable) 
     } 
     catch let error { 
      NSLog("%@", "Error for sending: \(error)") 
     } 
    } 
} 

func sendImage(imageData: Data) { 
    displayConnectedPeers() 
    NSLog("%@", "Attempting to send image to \(session.connectedPeers.count) peers") 
    if session.connectedPeers.count > 0 { 
     do { 
      try session.send(imageData, toPeers: session.connectedPeers, with: .reliable) 
      NSLog("%@", "Image sent") 
     } 
     catch let error { 
      NSLog("%@", "Error for sending image: \(error)") 
     } 
    } 
} 

func displayConnectedPeers() { 
    NSLog("%@", "Connected peers: \(session.connectedPeers.count)") 
} 
} 

extension ConnectionManager: MCNearbyServiceBrowserDelegate { 
func browser(_ browser: MCNearbyServiceBrowser, didNotStartBrowsingForPeers error: Error) { 
    NSLog("%@", "didNotStartBrowsingForPeers: \(error)") 
} 

func browser(_ browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) { 
    NSLog("%@", "foundPeer: \(peerID)") 
    NSLog("%@", "invitePeer: \(peerID)") 
    browser.invitePeer(peerID, to: session, withContext: nil, timeout: 10) 
    } 

func browser(_ browser: MCNearbyServiceBrowser, lostPeer peerID: MCPeerID) { 
    NSLog("%@", "lostPeer: \(peerID)") 
    self.connectionDelegate?.foundHost(manager: self) 
} 
} 

extension ConnectionManager: MCAdvertiserAssistantDelegate { 
func advertiserAssistantDidDismissInvitation(_ advertiserAssistant: MCAdvertiserAssistant) { 
    NSLog("%@", "Peer dismissed connection") 
} 

func advertiserAssistantWillPresentInvitation(_ advertiserAssistant: MCAdvertiserAssistant) { 
    NSLog("%@", "Peer accepted connection") 
} 
} 

extension ConnectionManager: MCSessionDelegate { 
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) { 
    NSLog("%@", "peer \(peerID) didChangeState: \(state)") 
    self.connectionDelegate?.foundHost(manager: self) 
} 

func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) { 

    NSLog("%@", "didReceiveData: \(data)") 

    if gameStarted == false { 
     stopBrowsing() 
     self.connectionDelegate?.hostInitsGame(manager: self) 
     NSLog("%@", "Game Started") 
     gameStarted = true 
    } 

    if gameStarted == true { 
     self.serviceDelegate?.changeImage(manager: self, imageData: data) 
    } 
} 

func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) { 
    NSLog("%@", "didReceiveStream") 
} 

func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) { 
    NSLog("%@", "didStartReceivingResourceWithName") 
} 

func session(_ session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, at localURL: URL, withError error: Error?) { 
    NSLog("%@", "didFinishReceivingResourceWithName") 
} 
} 

extension browsingForPeers : ConnectionManagerDelegate { 

func foundHost(manager: ConnectionManager) { 
    OperationQueue.main.addOperation { 
     if self.connectionManager.session.connectedPeers.count > 0 { 
      self.header.text = "\(self.connectionManager.session.connectedPeers[0].displayName)'s game" 
      self.activityMonitor.alpha = 0 
     } 
     if self.connectionManager.session.connectedPeers.count == 0 { 
      self.header.text = "Searching for game" 
      self.activityMonitor.alpha = 1 
     } 
    } 
} 

func hostInitsGame(manager: ConnectionManager) { 
    OperationQueue.main.addOperation { 
     self.switchViewControllers(active: true) 
    } 
} 
} 

extension ViewController : ServiceManagerDelegate { 
func changeImage(manager: ConnectionManager, imageData: Data) { 
    self.imageView.image = nil 
    self.imageView.image = UIImage(data: imageData) 
} 

} 

protocol ConnectionManagerDelegate { 
func hostInitsGame(manager: ConnectionManager) 
func foundHost(manager: ConnectionManager) 
} 

protocol ServiceManagerDelegate { 
func changeImage(manager: ConnectionManager, imageData: Data) 
} 

File Browser

import UIKit 

class browsingForPeers: UIViewController { 

    let connectionManager = ConnectionManager() 
    @IBOutlet weak var header: UITextField! 
    @IBOutlet weak var activityMonitor: UIActivityIndicatorView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     connectionManager.connectionDelegate = self 
     connectionManager.startBrowsing() 
//  Constants().host = false 
    } 

    func switchViewControllers(active: Bool) { 
     if active == true { 
      performSegue(withIdentifier: "browsingToDrawing", sender: self) 
     } 
    } 
} 

Le contrôleur de recherche est le même que le navigateur sauf qu'il annonce au lieu et envoie les données lorsque le bouton de lecture est cliqué.

Et enfin le contrôleur de dessin (Ceci est celui avec le problème, et je retire tout le code de dessin)

import UIKit 
import MultipeerConnectivity 

class ViewController: UIViewController { 
var globalConstant: Constants? 

let connectionManager = ConnectionManager() 

@IBOutlet var imageView: UIImageView! 
@IBOutlet weak var more: UIButton! 
@IBOutlet weak var brushOptions: UIButton! 
@IBOutlet weak var colorOptions: UIButton! 
@IBOutlet weak var eraser: UIButton! 

@IBOutlet weak var brushSml: UIButton! 
@IBOutlet weak var brushMed: UIButton! 
@IBOutlet weak var brushLrg: UIButton! 

@IBOutlet weak var redButton: UIButton! 
@IBOutlet weak var orangeButton: UIButton! 
@IBOutlet weak var yellowButton: UIButton! 
@IBOutlet weak var greenButton: UIButton! 
@IBOutlet weak var lightBlueButton: UIButton! 
@IBOutlet weak var blueButton: UIButton! 
@IBOutlet weak var pinkButton: UIButton! 
@IBOutlet weak var greyButton: UIButton! 
@IBOutlet weak var blackButton: UIButton! 

@IBOutlet weak var slider: UISlider! 

var uiimage: UIImage! 
var ciimage: CIImage! 
var data: Data! 


override var prefersStatusBarHidden: Bool { 
    return true 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 
    connectionManager.serviceDelegate = connectionManager.connectionDelegate as! ServiceManagerDelegate? 
    NSLog("%@", "View loaded with \ (connectionManager.session.connectedPeers.count) peers") //Outputs 0 
//  connectionManager.session.disconnect() 
//  NSLog("%@", "Disconnected") 

@IBAction func doneButtonClicked(_ sender: UIButton) { 
    imageView.isUserInteractionEnabled = false 
    uiimage = imageView.image 
    if uiimage != nil { 
     data = UIImagePNGRepresentation(uiimage) 
     connectionManager.sendImage(imageData: data) 
     imageView.image = nil 
     imageView.image = UIImage(data: data) 
    } 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

} 

Désolé pour les copies étranges de mise en forme Xcode d'une manière bizarre lapines pas garder la tabulation. Merci à l'avance, Matt.

+1

browsingForPeers viewcontroller et ViewController viewcontroller ont différents objets de gestionnaire de connexion, et vous commencez seulement à naviguer sur browsingForPeers. – koropok

+0

Ok parce qu'ils se connectent et partagent des données. C'est quand je commute le contrôleur de vue qu'il devient foiré. Je ne pense pas que je passe les variables correctement. Des idées? – Matt319

+0

Quelqu'un a des idées? Je crois que cela peut être lié à la transmission des valeurs, comme l'a dit @koropok. Merci – Matt319

Répondre

0

Je créais une nouvelle instance de la classe lorsque je l'appelais dans les différentes classes. C'est pourquoi toutes mes valeurs qui n'avaient pas été initialisées étaient égales à zéro. C'est ainsi que je l'ai réparé ...

let connectionManager = ConnectionManager() 

cela créait une instance et non une référence.

à

var connectionManager: ConnectionManager? 

cela crée une référence à la classe qui existe déjà.

L'autre chose que je devais faire était de passer toutes les valeurs en avant lorsque je me connectais à un autre contrôleur de vue.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if let destinationViewController = segue.destination as? ViewController { 
     destinationViewController.connectionManager = self.connectionManager 
    } 
} 

J'espère que cela aide toute personne ayant ce problème. Votre classe de gestionnaire de connexion n'est pas un singleton.