2016-05-12 12 views
0

データの送受信もできるアプリケーションを構築する必要があります。 少なくとも2つのスレッドを作成する必要があります。 1つは継続的にリッスンし、インターフェイスに応答してデータを送信する。TCPストリームとiOSでの発送

var a = connectionClass() 

@IBOutlet weak var textField: UITextField! 
@IBAction func myButton(sender: AnyObject) { 
    a.sendData() 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 
    let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT 
    dispatch_async(dispatch_get_global_queue(priority, 0), {()->() in 
     print("gcd hello") 
     dispatch_async(dispatch_get_main_queue(), { 
      self.a.initNetworkCommunication() 
      print("hello from UI thread executed as dispatch") 
     }) 
    }) 
    print("hello from UI thread") 
} 

このコードはユーザーインターフェイスをロックしますが、データを受信して​​います。 私は解決策を探しています、または私の問題の解決策を見いだすことができる例を探しています。

ストリームを作成するには、ここからコードを使用してください:https://github.com/troligtvis/SwiftChatClient/blob/master/ChatClientSwift/ViewController.swift

============================================== ===========================

いいですよ。私は接続を開いてデータを送ることができます。 しかし、私は他のクラスの関数を使ってストリームを読む方法を知らない。 イベントを使用するhawとNSStringのaStringを初期化する方法がわからないときに、self.a.stream ストリーム(aStream:NSStream、handleEventイベントコード:NSStreamEvent)を作成する方法 私は、それは愚かな質問ですが、私にとっては複雑です。

ViewControler: インポートのUIKit

クラスのViewController:のUIViewController、NSStreamDelegate {

var a = connectionClass() 

@IBOutlet weak var textField: UITextField! 
@IBAction func myButton(sender: AnyObject) { 
    a.sendData() 
} 
override func viewDidLoad() { 
    super.viewDidLoad() 
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), {()->() in 
     print("Inicjalizowanie") 
     self.a.initNetworkCommunication() 

     dispatch_async(dispatch_get_main_queue(), { 
      print("hello from UI thread executed as dispatch") 
     }) 
    }) 
    print("hello from UI thread") 
} 
override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

}

接続クラス: インポート財団

クラスconnectionClass:NSObjectの、NSStreamDelegate {

override init(){ 

} 

//deklaracja podstawowych zmiennych 
private let serverAddress: CFString = "someIp" 
private let serverPort: UInt32 = 10001 

private var inputStream: NSInputStream! 
private var outputStream: NSOutputStream! 
var i = 0 

//Inicjalizacja połączenia 
func initNetworkCommunication() { 

    //zmienne potrzebne do pobierania i wysyłania danych 
    var readStream: Unmanaged<CFReadStream>? 
    var writeStream: Unmanaged<CFWriteStream>? 

    //tworzy stream 
    autoreleasepool { 
    CFStreamCreatePairWithSocketToHost(nil, self.serverAddress, self.serverPort, &readStream, &writeStream) 
    } 
    self.inputStream = readStream!.takeRetainedValue() 
    self.outputStream = writeStream!.takeRetainedValue() 

    //delegaty w SWIFT - doczytać 
    self.inputStream.delegate = self 
    self.outputStream.delegate = self 

    //tworzy pętlę dla połączenia - doczytać 
    self.inputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) 
    self.outputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) 

    self.inputStream.open() 
    self.outputStream.open() 
    print("Zainicjalizowane") 

} 

//co ta funkcja robi i gdzie jest używana. Czy ona oczekuje na wywołanie połączenia z serwerem? 
func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) { 
    print("a tu jest stream") 
    switch eventCode{ 
    case NSStreamEvent.OpenCompleted: 
     print("Otwarto połączenie") 
     break 
    case NSStreamEvent.HasSpaceAvailable: 
     if outputStream == aStream{ 
      print("Połączenie jest gotowe") 
      break 
     } 
    case NSStreamEvent.HasBytesAvailable: 
     print("Są ramki") 
     if aStream == inputStream{ 
      var buffer: UInt8 = 0 
      var len: Int! 

      while (inputStream?.hasBytesAvailable != nil) { 
       len = inputStream?.read(&buffer, maxLength: 32) 
       if len > 0 { 
        let output = buffer 

        print("Server odpowiedział: \(output)") 

       } 
      } 
     } 
     break 
    case NSStreamEvent.ErrorOccurred: 
     print("Nie można połączyć się z serwerem!") 
     break 
    case NSStreamEvent.EndEncountered: 
     outputStream.close() 
     outputStream.removeFromRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) 
     outputStream = nil 
    default: 
     print("Nieznane działanie ") 
    } 
} 

func sendData() { 

    let data = NSData(bytes: [0x0F, 0x00, 0x10, 0x00, 0x00, 0x80, 0x55, 0x00, 0x55, 0x04, 0x00, 0x01, 0x00, 0x00, 0xB2, 0x04 ] as [UInt8], length: 16) 

    outputStream?.write(UnsafePointer<UInt8>(data.bytes) , maxLength: data.length) 

    print("wysłano: \(data)") 

} 

}

+0

AFNetworkingのようなフレームワークを使用しないと、メインスレッドにブロックネットワークコードが送信されないのはなぜですか? – Paulw11

+0

エラーが発生していますか?デバッグ情報を提供できますか?私はあなたがメインスレッドをブロックしているかを把握しようとしています。 –

答えて

1

まず:あなたはasync IOの行うためのスレッドを必要としません。 IOは、ランループ上のGCDを介してスケジュールすることができます。これは良い紹介です:What's New in GCD

2番目:あなたのdispatch_asyncコードセクションで達成しようとしていることはわかりません。セカンダリスレッドでprintを実行するだけです。次に、self.a.initNetworkCommunicationをメインスレッドに戻します。

3番目:チャットクライアントのコードを見ると、a.sendData()はブロック書き込みを行うようです。これは、よく、ブロック...

利用できるかなりの数のスウィフトGCDソケットライブラリがあります。これは1つです:SwiftSockets、もっとあります。あなたはおそらくそのようなものを見たいと思うでしょう。

+0

私はSwiftSocketsをダウンロードしてビルドしようとしましたが、Swift 3より前のSwiftのバージョンで書かれています。そして、私はそれを修正しようとしましたが、編集 - 変換と自動修正-I私は持っています。私はMacとSwiftにはまったく新しいので、おそらくそれは問題の一部です。とにかく、Swift 3、GCD、TCPソケットを組み合わせた他の最新のチュートリアルやオープンソースプロジェクトをお勧めすることができたら、私はそれを感謝します。私は空白になるよ...ありがとう。 – RenniePet

+0

私の前のコメントの続きで、私は今GitHubでこのプロジェクトを見つけました:https://github.com/IBM-Swift/BlueSocketそれは最新のものです(Swift 3、そして1日に数回コミットする)、ソケット用の純粋なSwiftラッパーを提供します。 GCD自体は使用していませんが、Swiftで書かれた呼び出しプログラムでGCDをどのように使用できるかを示す「読み込み中」のテストプログラムがあります。 – RenniePet

関連する問題