Swift:如何在收听流时更新 UI

标签 swift sockets

下面的代码似乎可以工作,除了我似乎无法在获取流事件后更新 button

我已经尝试了 delegatedispatch_async,但似乎都无法解决问题。

我在这里缺少什么魔法?

import UIKit

class TestViewController: UIViewController {

    @IBOutlet weak var connectButton: UIBarButtonItem!
    @IBOutlet weak var stopButton: UIBarButtonItem!

    let socket = Socket()

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    @IBAction func connectServer(sender: UIBarButtonItem) {
        socket.connect("10.0.0.1", port: 12345)
    }

    func setStopButtonState(state: String) {
        switch state {
        case "go":
            stopButton?.title = "STOP"
            break
        case "stop":
            stopButton?.title = "Start"
            break
        default:
            break
        }
    }
}

class Socket: NSObject, NSStreamDelegate {
    var inputStream: NSInputStream?
    var outputStream: NSOutputStream?

    func connect(host: String, port: Int) {
        NSStream.getStreamsToHostWithName(host, port: port, inputStream: &inputStream, outputStream: &outputStream)
        if inputStream != nil && outputStream != nil {
            inputStream!.delegate = self
            outputStream!.delegate = self
            inputStream!.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
            outputStream!.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
            inputStream!.open()
            outputStream!.open()
        }
    }

    func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
        if aStream === inputStream {
            switch eventCode {
            case NSStreamEvent.HasBytesAvailable:
                var inputBuffer = Array<UInt8>(count:2048, repeatedValue: 0)
                inputStream?.read(&inputBuffer, maxLength: 2048)
                TestViewController().setStopButtonState(String(bytes: inputBuffer, encoding: NSUTF8StringEncoding)!)
                break
            default:
                break
            }
        }
    }
}

最佳答案

让套接字有一个回调,并在流有字节时调用它:

import UIKit

class TestViewController: UIViewController {

@IBOutlet weak var connectButton: UIBarButtonItem!
@IBOutlet weak var stopButton: UIBarButtonItem!

let socket = Socket()

override func viewDidLoad() {
    super.viewDidLoad()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

@IBAction func connectServer(sender: UIBarButtonItem) {
    socket.connect("10.0.0.1", port: 12345)
    socket.changeWhenHasBytesAvailable = { str in
        // do change for the string
    }
}

func setStopButtonState(state: String) {
    switch state {
    case "go":
        stopButton?.title = "STOP"
        break
    case "stop":
        stopButton?.title = "Start"
        break
    default:
        break
    }
}
}

class Socket: NSObject, NSStreamDelegate {
var inputStream: NSInputStream?
var outputStream: NSOutputStream?
var changeWhenHasBytesAvailable: ((String)->())?

func connect(host: String, port: Int) {
    NSStream.getStreamsToHostWithName(host, port: port, inputStream: &inputStream, outputStream: &outputStream)
    if inputStream != nil && outputStream != nil {
        inputStream!.delegate = self
        outputStream!.delegate = self
        inputStream!.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
        outputStream!.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
        inputStream!.open()
        outputStream!.open()
    }
}

func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
    if aStream === inputStream {
        switch eventCode {
        case NSStreamEvent.HasBytesAvailable:
            var inputBuffer = Array<UInt8>(count:2048, repeatedValue: 0)
            inputStream?.read(&inputBuffer, maxLength: 2048)
            //call it in main queue
            dispatch_async(dispatch_get_main_queue(), { 
                self.changeWhenHasBytesAvailable?(String(bytes: inputBuffer, encoding: NSUTF8StringEncoding)!)
            })
            break
        default:
            break
        }
    }
}
}

关于Swift:如何在收听流时更新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37428188/

相关文章:

swift - 当用户不允许使用定位服务时处理 didFailToLocateUserWithError

ios - 'GMSReverseGeocodeCallback!'类型的reverseGeocodeCooperative()函数的回调处理程序的示例是什么?

ios - Xcode Swift 以编程方式将 UITextfield X 位置设置为中心

swift - 核心数据 : Loading Integers out of a File

c - 设置 tcp header 中的最大段大小

java - 无法使私有(private)广播方法起作用

python - Zeromq:不允许使用 unicode,请使用 send_unicode

python - pyOpenSSL SSL3_WRITE_PENDING :bad write retry,返回self._sslobj.write(数据)错误:[Errno 10054]

ios - 如何强制 Swift 可选数组(很好)

c - 为什么我可以绑定(bind)到 C 中的(看似)无效端口?