2014-10-14 20 views
18

Si tenta di inviare e ricevere dati con NSOutputStream e NSInputStream in Swift. L'invio di dati funziona bene, ma ho alcune domande sulla ricezione.Ricezione di dati da NSInputStream in Swift

Ho trovato una soluzione con la gestione di NSStreamEvent, che ho provato.

Prima di tutto la mia funzione per inizializzare la connessione:

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() 
} 

Questa parte funziona. Ho impostato i delegati su se stessi, quindi dovrei essere in grado di gestire gli NSStreamEvents in questa classe.

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.") 
    } 
} 

Nella mia comprensione ogni volta quando arriva alcuni dati, si deve stampare "HasBytesAvaible", ma è stampata "sconosciuto". ogni volta. Così ho giocato un po 'intorno e ha funzionato con questo:

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.") 
    } 
} 

E' lavorare in questo modo, ma volevo chiederti se questa è la strada giusta? Qual è la migliore pratica a questo punto?

UPDATE ho lavorato su di esso ancora una volta un paio di settimane fa e capito i miei errori. Quindi ecco il codice funzionante.

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

Ciao, questa soluzione funziona per risposta multipla alla volta? –

+0

Il codice sopra riportato è per la ricezione di un messaggio, non per rispondere ad esso. Ci sono framework per inviare e rispondere con socket, forse dare un'occhiata a socket.io http://socket.io/blog/socket-io-on-ios/ – hoedding

+0

Sì, è per ricevere messaggi ma voglio chiederti andando a gestire se ho avuto più risposte dal server allo stesso tempo? –

risposta

3

Stai perdendo l'evento hasSpaceAvailable, che mi aspetto è che si verificano quando si dice "sconosciuto". Ti sta dicendo che è pronto per ricevere più dati.

In genere, evito di utilizzare default in istruzioni switch per enumerazioni, poiché il compilatore ti dirà quando ti sei perso qualcosa.

+0

L'ho capito un paio di settimane fa. Accetterò la tua risposta qui, perché hai ragione. Questo è stato un mio errore. – hoedding

+0

Sono contento che l'abbia risolto - ho solo capito la data della tua domanda dopo che avevo risposto! – Alex

+0

@Alexander questa soluzione funzionerà per risposta multipla alla volta? in (UPDATE) –

3

Sto utilizzando il codice scritto da Hoedding e ho notato un errore. La linea:

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

deve essere sostituito dal

:

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

Dovete ottenere nel output var solo il numero di caratteri restituiti dal server, e non per tutta la lunghezza del buffer, o otterrete spazzatura dalle richieste precedenti.