Swift 3 - 在视图控制器之间传递变量和函数 [英] Swift 3 - Passing Variables and Functions Between View Controllers

查看:60
本文介绍了Swift 3 - 在视图控制器之间传递变量和函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在制作一个测试应用,您可以在其中使用多点连接绘制和发送图片.主机有一个连接视图控制器,其他对等体有一个单独的连接视图控制器.当对等方连接后,主机将开始游戏,并且所有对等方的视图控制器都将转到绘图 VC 以证明它们已连接.但是,当我想在绘图 VC 中发送数据时,即使有连接的对等点,控制台也会说连接的对等点会话为 0.我可以测试一下,因为当断开连接时,我会在控制台中收到更改状态通知.那么有人可以告诉我我的代码有什么问题吗?谢谢.

I am currently making a test app where you can draw and send pictures using multipeer connectivity. There is a connection view controller for the host and a separate one for the other peers. When peers have connected the host will play the game and all the peer's view controllers will go to the drawing VC proving they are connected. However, when I want to send data in the drawing VC, the console says the connected peers the session is 0 even though there are connected peers. I can test that because when the disconnect I get the change state notice in the console. So can someone please show me what is wrong with my code? Thanks.

Ps 我对 iOS 开发还很陌生,所以我的代码可能有一些主要问题.

Ps I am fairly new to iOS development so my code may have some major problems.

连接管理器文件:

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)
}

浏览器文件

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)
        }
    }
}

搜索控制器与浏览器相同,只是它在播放按钮被点击时进行广告和发送数据.

The searching controller is the same as the browser except it advertises instead and sends the data when the play button is clicked.

最后是绘图控制器(这是有问题的,我删除了所有绘图代码)

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.
}

}

很抱歉,Xcode 以一种奇怪的方式复制了奇怪的格式,并没有保持跳格.提前致谢,马特.

Sorry for the weird formatting Xcode copies in a weird way the doesn't keep tabbing. Thanks in advanced, Matt.

推荐答案

当我在不同的类中调用该类时,我正在创建该类的新实例.这就是为什么我所有尚未初始化的值都等于 nil.这是我修复它的方式...

I was creating a new instance of the class when I called it in the different classes. That is why all my values that had not been initialized were equal to nil. This is the way I fixed it...

let connectionManager = ConnectionManager()

这是在创建一个实例而不是一个引用.

this was creating a instance and not a reference.

var connectionManager: ConnectionManager?

这是创建对已经存在的类的引用.

this is creating a reference to the class that already exists.

我必须做的另一件事是当我转到另一个视图控制器时,向前传递所有值.

The other thing I had to do was when I segue to another view controller, pass all the values forward.

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

我希望这对遇到此问题的其他人有所帮助.

I hope this helps anyone else who is having this issue.

这篇关于Swift 3 - 在视图控制器之间传递变量和函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆