質問

私はObjective-CからSwiftまでアプリを移植しており、次の方法を使用する必要があります。

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

古いロジックはこのように見えます(いくつかのWebサイトは同意しているようです):

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;
.

フリーフリーブリッジングのおかげでうまくいく。ただし、ARCは「SWIFT-SPACE」には存在せず、タイプシステムが変更されました。

のインスタンスにストリームをどのように変える方法
CMutablePointer<Unmanaged<CFReadStream>?>, and
CMutablePointer<Unmanaged<CFWriteStream>?>
.

NSStream呼び出し後にそれらをCFStreamCreatePairWithSocketToHostサブクラスに変換しますか?

役に立ちましたか?

解決

私はそれがうまくいった、ここに私のコードです: 接続クラスのどこかに参照してください。 - )

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

他のヒント

私はこのスレッドで他のスレッドで提供された例を得ることができませんでした。確かに、彼らはまとめたが、それらは接続が開いたらすぐにクラッシュした。

しかし、私は、WWDC 2014ディスカッション(およびiOS 8リリースノート)に気付きました。

のバインド対のペアを作成するためのNSStreamを初期化するための新しい方法があることがわかっています。

下記参照:

var inputStream: NSInputStream?
var outputStream: NSOutputStream?

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

これは、管理されていないリソースの必要性を削除するだけでなく、AWKWARD CFStreamCreatePairWithSocketoSOCTOSCOST呼び出しの必要性を除去します。

私はそれをやる方法を取り出しました。いくつかの重要な注意事項:

  1. CMutablePointersは、&演算子を使用すると自動的に作成されます。
  2. TUnmanaged<T>.getUnretainedValue()getRetainedValue()と類似しているようです)
  3. .getUnretainedValue()に到達できます。
  4. オプションは自動的に__bridge_transferに初期化されます。
  5. オプションがnilの場合、それはnil状態に変換されます。
  6. これまでのところ(未テスト):

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

nsStreamクラスのgetStreamstoHostWithName関数を使用しています。CFStreamCreatepairwithSockettohost

よりも簡単でビートです。

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バージョンのCFおよびNSコード。どちらも私のために働いています。

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

}
.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top