2014-10-14 17 views
18

Ich versuche, Daten mit NSOutputStream und NSInputStream in Swift zu senden und zu empfangen. Das Senden von Daten funktioniert gut, aber ich habe einige Fragen zum Empfang.Empfangen von Daten von NSInputStream in Swift

Ich fand eine Lösung mit der Handhabung des NStreamEvent, das ich ausprobiert habe.

Zu allererst meine Funktion zur Initialisierung der Verbindung:

func initNetworkCommunication(){ 
    var host : CFString = "127.0.0.1" 
    var port : UInt32 = 7001 
    var readstream : Unmanaged<CFReadStream>? 
    var writestream : Unmanaged<CFWriteStream>? 
    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, host, port, &readstream, &writestream) 

    inputstream = readstream!.takeRetainedValue() 
    outputstream = writestream!.takeRetainedValue() 

    inputstream.delegate = self 
    outputstream.delegate = self 


    inputstream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) 
    outputstream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) 

    inputstream.open() 
    outputstream.open() 
} 

Dieser Teil funktioniert. Ich habe die Delegierten auf self gesetzt, also sollte ich in der Lage sein, die NStreamEvents in dieser Klasse zu behandeln.

func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) { 
    switch (eventCode){ 
    case NSStreamEvent.OpenCompleted: 
     NSLog("Stream opened") 
     break 
    case NSStreamEvent.HasBytesAvailable: 
     NSLog("HasBytesAvailable") 
     break 
    case NSStreamEvent.ErrorOccurred: 
     NSLog("ErrorOccurred") 
     break 
    case NSStreamEvent.EndEncountered: 
     NSLog("EndEncountered") 
     break 
    default: 
     NSLog("unknown.") 
    } 
} 

In meinem Verständnis, jedes Mal, wenn einige Daten ankommen, sollte es drucken „HasBytesAvaible“, aber es gedruckt „unbekannt“. jedes Mal. Also spielte ich ein wenig herum und es funktionierte mit diesem:

func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) { 

    var buffer = [UInt8](count: 4096, repeatedValue: 0) 
    while (inputstream.hasBytesAvailable){ 
     let result: Int = inputstream.read(&buffer, maxLength: buffer.count) 
    } 

    switch (eventCode){ 
    case NSStreamEvent.OpenCompleted: 
     NSLog("Stream opened") 
     break 
    case NSStreamEvent.HasBytesAvailable: 
     NSLog("HasBytesAvailable") 
     var output = NSString(bytes: &buffer, length: buffer.count, encoding: NSUTF8StringEncoding) 
     NSLog("output: %@", output) 
     receiveMessage(output) //only adds the message to an array 
     break 
    case NSStreamEvent.ErrorOccurred: 
     NSLog("ErrorOccurred") 
     break 
    case NSStreamEvent.EndEncountered: 
      NSLog("EndEncountered") 
     break 
    default: 
     NSLog("unknown.") 
    } 
} 

Es ist auf diese Weise zu arbeiten, aber ich wollte Sie fragen, ob dies der richtige Weg ist? Was ist zu diesem Zeitpunkt die beste Vorgehensweise?

UPDATE Ich habe vor ein paar Wochen noch einmal daran gearbeitet und meine Fehler herausgefunden. Also hier ist der Arbeitscode.

func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) { 
     switch (eventCode){ 
    case NSStreamEvent.ErrorOccurred: 
     NSLog("ErrorOccurred") 
     break 
    case NSStreamEvent.EndEncountered: 
     NSLog("EndEncountered") 
     break 
    case NSStreamEvent.None: 
     NSLog("None") 
     break 
    case NSStreamEvent.HasBytesAvailable: 
     NSLog("HasBytesAvaible") 
     var buffer = [UInt8](count: 4096, repeatedValue: 0) 
     if (aStream == inputstream){ 

      while (inputstream.hasBytesAvailable){ 
       var len = inputstream.read(&buffer, maxLength: buffer.count) 
       if(len > 0){ 
        var output = NSString(bytes: &buffer, length: buffer.count, encoding: NSUTF8StringEncoding) 
        if (output != ""){ 
         NSLog("server said: %@", output!) 
        } 
       } 
      } 
     } 
     break 
    case NSStreamEvent.allZeros: 
     NSLog("allZeros") 
     break 
    case NSStreamEvent.OpenCompleted: 
     NSLog("OpenCompleted") 
     break 
    case NSStreamEvent.HasSpaceAvailable: 
     NSLog("HasSpaceAvailable") 
     break 
    } 
+0

Hallo, funktioniert diese Lösung für mehrere Antworten gleichzeitig? –

+0

Der obige Code dient zum Empfangen einer Nachricht, nicht zum Antworten darauf. Es gibt Frameworks zum Senden und Antworten mit Sockets, vielleicht werfen Sie einen Blick auf socket.io http://socket.io/blog/socket-io-on-ios/ – hoedding

+0

Ja, es ist für den Empfang von Nachrichten, aber ich möchte Sie fragen, ist es gehen, wenn ich mehrere Antworten vom Server gleichzeitig habe? –

Antwort

3

Sie verpassen das Ereignis hasSpaceAvailable, die ich erwarte, dass auftritt, wenn er sagt, „unbekannt“. Es sagt Ihnen, dass es bereit ist, mehr Daten zu erhalten.

Im Allgemeinen vermeide ich default in Switch-Anweisungen für Enums, da der Compiler wird Ihnen sagen, wenn Sie etwas verpasst haben.

+0

Ich habe es vor ein paar Wochen herausgefunden. Ich werde deine Antwort hier akzeptieren, weil du recht hast. Das war mein Fehler. – hoedding

+0

Ich bin froh, dass Sie es sortiert haben - ich habe nur das Datum Ihrer Frage erkannt, nachdem ich geantwortet hatte! – Alex

+0

@Alexander diese Lösung wird für mehrere Antworten gleichzeitig arbeiten? in (UPDATE) –

3

Ich benutze den Code von Hoedding geschrieben, und bemerkte einen Fehler. Die Linie:

var output = NSString(bytes: &buffer, length: buffer.count, encoding: NSUTF8StringEncoding) 

ersetzt werden durch: vom Server und nicht über die volle Länge des Puffers zurück

var output = NSString(bytes: &buffer, length: len, encoding: NSUTF8StringEncoding) 

Sie haben zu bekommen in den output var nur die Anzahl der Zeichen, oder Sie werden Müll von früheren Anfragen bekommen.