NSOutputStream阻塞,未触发HasBytesAvailable事件

时间:2015-12-21 15:21:20

标签: ios swift external-accessory nsinputstream nsoutputstream

我正在尝试创建自定义框架,以处理ExternalAccessory.framework与连接附件进行读/写操作。

我可以创建会话并打开设备进行读/写操作。 我面临的问题是,当我尝试使用NSOutputStream.write从应用程序写入数据时,附件成功收到数据,但在该UI没有响应之后,应用程序未收到数据返回的字节附件(HasBytesAvailable不是叫)

这是我的UIViewController.swift

let sessionHandler = SessionHandler().sharedController()
ViewDidLoad()

中的

let runLoop = NSRunLoop.currentRunLoop()
sessionHandler.openDeviceWithProtocolString(runLoop)

@IBAction致电sessionHandler._WriteData()

这个SessionHandler类位于我的自定义SDK(自定义框架)

这是我的SessionHandler班级

import UIKit
import ExternalAccessory


public class SessionHandler: NSObject, NSStreamDelegate {

    var readData: NSMutableData?
    var writeData: NSMutableData?
    var _session: EASession?

    public func sharedController() -> SessionHandler{
        var sessionController: SessionHandler?
        if sessionController == nil {
            sessionController = SessionHandler()
        }
        return sessionController!
    }

    func getConnectedAccessoris() -> Array<EAAccessory>{
        let accessories : Array<EAAccessory> = EAAccessoryManager.sharedAccessoryManager().connectedAccessories
        return accessories
    }


    public func openDeviceWithProtocolString(_runLoop: NSRunLoop){
        print("Inside openDeviceWithProtocolString")
        let _accessories = getConnectedAccessoris()
        var _accessory: EAAccessory?
        for acsy in _accessories {
            if acsy.protocolStrings.contains("my.protocol.string") {
                _accessory = acsy
            }
        }
        if _accessory != nil {
            _session = EASession(accessory: _accessory!, forProtocol: "my.protocol.string")
            print("EASession create :: \(_session)")
            if _session != nil {

                _session?.inputStream?.delegate = self
                _session?.inputStream?.scheduleInRunLoop(_runLoop, forMode: NSDefaultRunLoopMode)
                _session?.inputStream?.open()
                print("Input stream Opened")
                _session?.outputStream?.delegate = self
                _session?.outputStream?.scheduleInRunLoop(_runLoop, forMode: NSDefaultRunLoopMode)
                _session?.outputStream?.open()
                print("Output Stream Opened")
            }else {
                print("SessionHandler : session nil")
            }
        }
    }



    public func _readData() {
        print("Trying to read data")
        let INPUT_BUFFER_SIZE = 65536
        let buf = UnsafeMutablePointer<UInt8>.alloc(INPUT_BUFFER_SIZE)
        while ((_session?.inputStream?.hasBytesAvailable) != nil) {
            let bytesRead = _session?.inputStream?.read(buf, maxLength: INPUT_BUFFER_SIZE)
            if readData == nil {
                readData = NSMutableData()
            }
            readData?.appendBytes(buf, length: bytesRead!)
        }
        if readData != nil {
            let data: NSData = readData!
            let count = data.length / sizeof(UInt8)

            // create an array of Uint8
            var array = [UInt8](count: count, repeatedValue: 0)

            // copy bytes into array
            data.getBytes(&array, length:count * sizeof(UInt8))
            print("Data Received :: \(array)")
            validateData(array)
        }
    }

    public func _writeData() {

        while _session?.outputStream?.hasSpaceAvailable != nil && writeData?.length > 0 {
            print("Writting bytes :: \(writeData?.bytes)")
            let bytesWritten = _session?.outputStream?.write(UnsafePointer<UInt8>((writeData?.bytes)!), maxLength: (writeData?.length)!)
            print("written bytes : \(bytesWritten)")
            if bytesWritten == -1 {
                //Write error
                print("written error")
                break
            }else if bytesWritten > 0 {
                print("Written success")
                validateData(writeData)
                writeData?.replaceBytesInRange(NSMakeRange(0, bytesWritten!), withBytes: nil, length: 0)
            }
        }
    }


    func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
        switch (eventCode) {
        case NSStreamEvent.None:
            print("NSStream None")
            break
        case NSStreamEvent.OpenCompleted:
            print("Open Completed")
            break
        case NSStreamEvent.HasBytesAvailable:
            print("Has Bytes Available")
            _readData()
            break
        case NSStreamEvent.HasSpaceAvailable:
            print("Hase space Available")
            _writeData()
            break
        case NSStreamEvent.ErrorOccurred:
            print("Error occurred")
            break
        case NSStreamEvent.EndEncountered:
            print("End Encountered")
            break
        default:
            print("No stream event")
            break
        }
    }
}

先谢谢..

2 个答案:

答案 0 :(得分:0)

sessionHandler.openDeviceWithProtocolString(runLoop)

是不是应该在另一个线程上调用?

答案 1 :(得分:0)

我确定这为时已晚,但

while ((_session?.inputStream?.hasBytesAvailable) != nil)
对我来说看起来像是一个无限循环,因为 true/false 总是 != nil。