Domanda

Sto portando un app da Objective-C a Swift e ho bisogno di utilizzare il seguente metodo:

CFStreamCreatePairWithSocketToHost(alloc: CFAllocator!, host: CFString!, port: UInt32, \
readStream: CMutablePointer<Unmanaged<CFReadStream>?>, \
writeStream: CMutablePointer<Unmanaged<CFWriteStream>?>)
.

La vecchia logica è simile a questa (che diversi siti Web sembrano essere d'accordo):

CFReadStreamRef readStream = NULL;
CFWriteStreamRef writeStream = NULL;
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)(host), port, \
                                   &readStream, &writeStream);

NSInputStream inputStream = (__bridge_transfer NSInputStream *)readStream;
NSOutputStream outputStream = (__bridge_transfer NSOutputStream *)writeStream;
.

che funziona bene grazie a Bridging senza pedine.Tuttavia, Arc non esiste in "Swift-Space" e il sistema di tipo è cambiato.

Come faccio a girare i miei flussi in istanze di

CMutablePointer<Unmanaged<CFReadStream>?>, and
CMutablePointer<Unmanaged<CFWriteStream>?>
.

e quindi convertili indietro nelle sottoclassi NSStream dopo la chiamata CFStreamCreatePairWithSocketToHost?

È stato utile?

Soluzione

L'ho capito per lavorare, ecco il mio codice: Assicurati di tenere un riferimento della classe di connessione da qualche parte: -)

class Connection : NSObject, NSStreamDelegate {
    let serverAddress: CFString = "127.0.0.1"
    let serverPort: UInt32 = 8443

    private var inputStream: NSInputStream!
    private var outputStream: NSOutputStream!

    func connect() {
        println("connecting...")

        var readStream:  Unmanaged<CFReadStream>?
        var writeStream: Unmanaged<CFWriteStream>?

        CFStreamCreatePairWithSocketToHost(nil, self.serverAddress, self.serverPort, &readStream, &writeStream)

        // Documentation suggests readStream and writeStream can be assumed to
        // be non-nil. If you believe otherwise, you can test if either is nil
        // and implement whatever error-handling you wish.

        self.inputStream = readStream!.takeRetainedValue()
        self.outputStream = writeStream!.takeRetainedValue()

        self.inputStream.delegate = self
        self.outputStream.delegate = self

        self.inputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
        self.outputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)

        self.inputStream.open()
        self.outputStream.open()
    }

    func stream(stream: NSStream, handleEvent eventCode: NSStreamEvent) {
        println("stream event")
    }
}
.

Altri suggerimenti

Non ero in grado di ottenere gli esempi che altri hanno fornito in questo thread per funzionare.Certo, hanno compilato, ma si sono schiantati non appena la connessione era aperta.

Tuttavia, ho notato nelle discussioni WWDC 2014 (e le note di rilascio iOS 8) che esiste un nuovo metodo per inizializzare un NSstream per la creazione di un paio di flussi / out rilegati.

Vedi sotto:

var inputStream: NSInputStream?
var outputStream: NSOutputStream?

NSStream.getStreamsToHostWithName("localhost", port: 1234, inputStream: &inputStream, outputStream: &outputStream)
.

Ciò rimuove la necessità per l'imbarazzante chiamata CFStreamCreatePairWithShelocketOhost e la rimozione della necessità di risorse non gestite.

Ho lavorato come farlo.Alcune note importanti:

    .
  1. CMutablePointers verrà creato automaticamente se si utilizza l'operatore e l'operatore.
  2. È possibile ottenere al T in un Unmanaged<T> con .getUnretainedValue() e getRetainedValue() (sembra .getUnretainedValue() è analogo a __bridge_transfer)
  3. Le opzioni vengono inizializzate automaticamente in generatori di generazioneGode.
  4. Se un opzionale è nil si tradurrà in una condizione nil.
  5. finora ho (non testato):

    var readStream: Unmanaged<CFReadStream>?
    var writeStream: Unmanaged<CFWriteStream>?
    
    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, host, port, \
    &readStream, &writeStream)
    
    if (readStream && writeStream) {
        inputStream = readStream!.takeUnretainedValue();
        outputStream = writeStream!.takeUnretainedValue();
    }
    
    .

Sto usando GetStreamstohostwithName Funzione della classe NSstream.È più facile e Beeter di cfstreamCreatePairWithSheetOhost

Func InitNetworkCommunication () {

print("connecting...")

let serverAddress = "gzoa.vps.infomaniak.com"
let serverPort = 1234

NSStream.getStreamsToHostWithName(serverAddress, port: serverPort, inputStream: &inputStream, outputStream: &outputStream)

self.inputStream!.delegate = self
self.outputStream!.delegate = self

self.inputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
self.outputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)

self.inputStream!.open()
self.outputStream!.open()
.

}

Swift 3 Versione di CF e codice NS.Entrambi lavorano per me.

CF:

class Connection: NSObject, StreamDelegate {

private var inputStream: InputStream!
private var outputStream: OutputStream!

var connected = false

func connect(host: String, port: UInt32) {
    var readStream:  Unmanaged<CFReadStream>?
    var writeStream: Unmanaged<CFWriteStream>?

    CFStreamCreatePairWithSocketToHost(nil, host as CFString, port, &readStream, &writeStream)

    self.inputStream = readStream!.takeRetainedValue()
    self.outputStream = writeStream!.takeRetainedValue()

    if let inputStream = inputStream, let outputStream = outputStream {
        inputStream.delegate = self
        outputStream.delegate = self

        inputStream.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
        outputStream.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)

        inputStream.open()
        outputStream.open()

        connected = true
    }
}

func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
    print("stream event, \(eventCode)")
}

}
.

ns:

class NSConnection: NSObject, StreamDelegate {

private var inputStream: InputStream?
private var outputStream: OutputStream?

var connected = false

func connect(host: String, port: Int) {
    Stream.getStreamsToHost(withName: host, port: port, inputStream: &inputStream, outputStream: &outputStream)

    if let inputStream = inputStream, let outputStream = outputStream {
        inputStream.delegate = self
        outputStream.delegate = self

        inputStream.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
        outputStream.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)

        inputStream.open()
        outputStream.open()
    }
}

func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
    print("stream event, \(eventCode)")
}

}
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top