Я пытаюсь работать с NSInputStream
и NSOutputStream
, но это причиняет много боли.
У меня есть два устройства, которые обмениваются данными Json. Некоторые данные могут быть очень длинными, поэтому NSOutputStreamsends
разбивает их на несколько пакетов.
Мне нужно, чтобы получение не блокировалось в основном потоке и могло читать все необходимые пакеты json, прежде чем пытаться его проанализировать. Затем продолжите чтение остальных пакетов данных json.
Мне нужно, чтобы отправка не блокировалась в основном потоке и могла завершить отправку данных, если первая партия не была отправлена. Затем продолжите отправку остальных данных json.
Я использую swift, но также могу использовать и цель c.
Вот код до сих пор. Мой основной вспомогательный класс потока:
public class StreamHelper : NSObject, NSStreamDelegate {
static let DATA_BYTE_LENGTH = 4;
public static func writeToOutputStream(text: String!, outputStream:NSOutputStream!) -> Int!{
let encodedDataArray = [UInt8](text.utf8)
var count: Int = encodedDataArray.count.littleEndian
//convert int to pointer, which is required for the write method.
withUnsafePointer(&count) { (pointer: UnsafePointer<Int>) -> Void in
outputStream.write(UnsafePointer<UInt8>(pointer), maxLength: DATA_BYTE_LENGTH)
}
let bytesWritten = outputStream.write(encodedDataArray, maxLength: encodedDataArray.count)
return bytesWritten;
}
public static func readFromInputStream(inputStream: NSInputStream!) -> String!{
var buffer = [UInt8](count: 4096, repeatedValue: 0)
var text = ""
while (inputStream.hasBytesAvailable){
let len = inputStream!.read(&buffer, maxLength: buffer.count)
if(len > 0){
if let output = NSString(bytes: &buffer, length: buffer.count, encoding: NSUTF8StringEncoding) as? String{
if (!output.isEmpty){
text += output
}
}
}
}
return text
}
}
Основной код:
public func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
print("Reading from stream... ")
switch (eventCode){
case NSStreamEvent.ErrorOccurred:
print("ErrorOccurred")
break
case NSStreamEvent.None:
print("None")
break
case NSStreamEvent.EndEncountered:
print("EndEncountered")
if((aStream == inputStream) && inputStream!.hasBytesAvailable){
// If all data hasn't been read, fall through to the "has bytes" event
} else{
break
}
case NSStreamEvent.HasBytesAvailable:
print("HasBytesAvaible")
let methodJson = StreamHelper.readFromInputStream(inputStream!)
if(!methodJson.isEmpty){
let cMethodJson = methodJson.cStringUsingEncoding(NSUTF8StringEncoding)!
let returnedJsonString = String.fromCString(callMethod(cMethodJson))
StreamHelper.writeToOutputStream(returnedJsonString, outputStream: outputStream!)
}
break
case NSStreamEvent.OpenCompleted:
print("OpenCompleted")
break
case NSStreamEvent.HasSpaceAvailable:
print("HasSpaceAvailable")
if(aStream == outputStream){
}
break
default:
break
}
}
Некоторый код установки:
func connectToService(service: NSNetService!){
service.getInputStream(&inputStream, outputStream: &outputStream)
inputStream!.delegate = self
outputStream!.delegate = self
inputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
outputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
inputStream!.open()
outputStream!.open()
}
Как правильно работать с NSStreams или есть лучшее решение, чем использование NSStreams?