2017-08-23 21 views
0

での作業:私は出力ストリームにバイナリデータを送信 https://www.raywenderlich.com/157128/real-time-communication-streams-tutorial-ios私はスウィフトに、クライアントアプリケーションを作成しようとしていると私はインスピレーションとして、このチュートリアルに従うことを選択したStreamDelegate /のInputStream

をし、私のサーバーを取得しますリクエストは成功し、返答します。残念ながら、SwiftクライアントアプリケーションのStreamDelegateは決して起動されません。

遊び場に私のアプリケーションがやっていると、同じ問題が発生したものと同様のHTTPリクエストの簡単な例Iを開発しました:私は取得

import UIKit 

class WebServerConnection: NSObject, StreamDelegate { 
    let host: String 
    var inputStream: InputStream! 
    var outputStream: OutputStream! 
    var responseHandler:((String) -> Void)? 

    init(_ host:String) { 
     self.host = host 
    } 

    func setup(responseHandler:((String) -> Void)?) { 
     self.responseHandler = responseHandler 
     var readStream: Unmanaged<CFReadStream>? 
     var writeStream: Unmanaged<CFWriteStream>? 
     CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, host as CFString, 80, &readStream, &writeStream) 
     inputStream = readStream!.takeRetainedValue() 
     outputStream = writeStream!.takeRetainedValue() 
     inputStream.delegate = self 
     inputStream.schedule(in: .current, forMode: .commonModes) 
     outputStream.schedule(in: .current, forMode: .commonModes) 
     inputStream.open() 
     outputStream.open() 
    } 

    func query(_ path:String = "/") { 
     let data = "GET \(path) HTTP/1.1\r\nhost: \(host)\r\n\r\n".data(using: .utf8)! 
     _ = data.withUnsafeBytes { outputStream.write($0, maxLength: data.count) } 
     print("sent!") 
    } 

    func stream(_ aStream: Stream, handle eventCode: Stream.Event) { 
     switch eventCode { 
     case Stream.Event.hasBytesAvailable: 
      printAvailableBytes(stream: aStream as! InputStream) 
     case Stream.Event.endEncountered: 
      print("<End Encountered>") 
     case Stream.Event.errorOccurred: 
      print("<Error occurred>") 
     default: 
      print("<Some other event>") 
     } 
    } 

    func printAvailableBytes(stream: InputStream) { 
     let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: 4096) 
     while stream.hasBytesAvailable { 
      let numberOfBytesRead = inputStream.read(buffer, maxLength: 4096) 
      if numberOfBytesRead < 0 { 
       if stream.streamError != nil { 
        break 
       } 
      } 

      if let message = String(bytesNoCopy: buffer, length: numberOfBytesRead, encoding: .utf8, freeWhenDone: true) { 
       responseHandler?(message) 
      } 
     } 
    } 

    func close() { 
     inputStream.close() 
     outputStream.close() 
    } 
} 

let google = WebServerConnection("google.com") 
google.setup() { message in 
    print(message) 
    google.close() 
} 
google.query() 

を「送信済みを!」コンソールにはメッセージがありますが、それ以外は何もありません!私はinput.delegate = selfと考えて、ストリーム関数は応答と共に呼び出されます。私は何が欠けていますか?マーティン-rが考え出し@として

+1

このhttps://stackoverflow.com/q/24058336/1187415? –

+0

ありがとう、それは動作します!しかし残念ながら、私は自分のアプリケーションで問題を再現することはできません。私は再現しようとします。 –

答えて

0

、私が行方不明になった:

import UIKit 
import PlaygroundSupport 

... 

google.query() 

PlaygroundPage.current.needsIndefiniteExecution = true 

編集:誰かが多分それはあなたとは何かを持っている、(StreamDelegateがトリガされません)私と同じ問題を抱えている場合はRunLoop。 raywenderlich.comの例と私が遊び場で作った例では、ネットワーク接続を設定する機能がメインスレッドから呼び出されましたが、私の場合は実行ループのない別のスレッドから呼び出されませんでした。

inputStream.schedule(in: .current, forMode: .commonModes) 
outputStream.schedule(in: .current, forMode: .commonModes) 

:私は置き換え

inputStream.schedule(in: .main, forMode: .commonModes) 
outputStream.schedule(in: .main, forMode: .commonModes) 

そして、それはシームレスに機能し始めました。