문제

Objective-C에서 Swift로 앱을 포팅하려고 하는데 다음 방법을 사용해야 합니다.

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

이전 논리는 다음과 같습니다(여러 웹 사이트가 이에 동의하는 것으로 보입니다).

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;

무료 브리징 덕분에 잘 작동합니다.그러나 "Swift-space"에는 ARC가 존재하지 않으며 유형 체계가 변경되었습니다.

내 스트림을 인스턴스로 어떻게 바꾸나요?

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을 in / out 스트림의 바운드 쌍을 생성하기 위해 NSStream을 초기화하는 새로운 방법이 있다는 것을 알아 차렸다.

아래를 참조하십시오 :

var inputStream: NSInputStream?
var outputStream: NSOutputStream?

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

이것은 어색한 CFSTREAMCREATEPARWITHSockEttoHost 호출의 필요성을 제거하고 관리되지 않는 자원의 필요성을 제거합니다.

나는 그것을하는 방법을 알아 냈습니다.몇 가지 중요한 참고사항:

  1. CMutablePointers & 연산자를 사용하면 자동으로 생성됩니다.
  2. 에서 받으실 수 있습니다. TUnmanaged<T> ~와 함께 .getUnretainedValue() 그리고 getRetainedValue() (아마도 .getUnretainedValue() 와 유사하다 __bridge_transfer)
  3. 옵션은 자동으로 초기화됩니다. nil.
  4. 선택사항인 경우 nil 그것은 다음으로 번역될 것이다 false 상태.

지금까지 나는 (테스트되지 않음) :

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 함수를 사용하고 있습니다.CFSTREAMCREATEPARWITHSockETTOHOST

보다 쉽고 쉽게 쉽고 발이야합니다.

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