How to read data from NSInputStream explicitly in swift?
I am using socket connection in my application.
Here mine SocketConnection.swift
init(host: String, port:UInt32){
self.host = host
self.port = port
self.status = false
output = ""
super.init()
}
func stream(aStream: NSStream, handleEvent aStreamEvent: NSStreamEvent) {
switch aStreamEvent {
case NSStreamEvent.OpenCompleted:
break
case NSStreamEvent.HasBytesAvailable:
break
case NSStreamEvent.HasSpaceAvailable:
break
case NSStreamEvent.EndEncountered:
// aStream.close()
aStream.removeFromRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
break
case NSStreamEvent.None:
break
case NSStreamEvent.ErrorOccurred:
break
default:
println("# something weird happend")
break
}
}
func connect() {
println("# connecting to \(host):\(port)")
var cfReadStream : Unmanaged<CFReadStream>?
var cfWriteStream : Unmanaged<CFWriteStream>?
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, host, port, &cfReadStream, &cfWriteStream)
inputStream = cfReadStream!.takeRetainedValue()
outputStream = cfWriteStream!.takeRetainedValue()
inputStream!.delegate = self
outputStream!.delegate = self
inputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
outputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
inputStream!.open()
outputStream!.open()
}
func read(){
var buffer = [UInt8](count: bufferSize, repeatedValue: 0)
output = ""
while (self.inputStream!.hasBytesAvailable){
var bytesRead: Int = inputStream!.read(&buffer, maxLength: buffer.count)
if bytesRead >= 0 {
output += NSString(bytes: UnsafePointer(buffer), length: bytesRead, encoding: encoding)! as String
} else {
println("# error")
}
println("> \(output)")
}
}
func send(message:String){
let data:NSData = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
let bytesWritten = self.outputStream!.write(UnsafePointer(data.bytes), maxLength: data.length)
println("< send to \(host)")
}
In mine ViewController.swift
, I connect to the server as follows
var socketConnection = SocketConnection(host: _ip, port: _port)
socketConnection.connect()
socketConnection.send(urlString)
socketConnection.read()
Now I can send the url string over the socket, but when I read explicitly I am not receiving data from the server if I call the same read function from the case NSStreamEvent.HasBytesAvailable
when it prints the server response .. but how can I fire the event queue?
I want to explicitly call it socketConnection.read()
.. How can I do this?
After 2 seconds of connecting, it closes the connection channel, I want to keep my connection until closed.
Help me solve this problem.
thank
source to share
Modify read () as shown below, and then call read () in the case of NSStreamEvent.HasBytesAvailable:
private func read(stream: InputStream) {
let maxReadLength = 1024
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: maxReadLength)
while stream.hasBytesAvailable {
let numberOfBytesRead = inputStream?.read(buffer, maxLength: maxReadLength)
if numberOfBytesRead! < 0 {
if let _ = inputStream?.streamError {
break
}
}
if let message = processedMessageString(buffer: buffer, length: numberOfBytesRead!) {
delegate?.receivedMessage(message: message)
}
}
}
source to share
You don't need to explicitly call the read function. Modify the read function as shown below and call in case Stream.Event.hasBytesAvailable:.
func read(stream: InputStream) {
let maxReadLength = 1024
var buffer = [uint8](repeating: 0, count: maxReadLength)
while stream.hasBytesAvailable {
let numberOfBytesRead : Int = stream.read(&buffer, maxLength: maxReadLength)
if numberOfBytesRead < 0 {
if let _ = stream.streamError {
break
}
}
if let message = processedMessageString(buffer: buffer, length: numberOfBytesRead) {
delegate?.receivedMessage(message: message)
}
}}
If you want to call read () explicitly, then you need to pass the stream as parameters and call the read function in the ViewController class -
socketConnection.read(stream)
source to share