TCP Stream и рассылка в 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?

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

Хорошо, это работает. Я могу открыть соединение и отправить данные. Но сейчас я не знаю, как использовать функцию из другого класса для чтения потока. Как создать поток self.a.stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent), когда я не знаю, как использовать событие, и как инициировать NSString для aString. Я знаю, это глупый вопрос, но для меня это сложно.

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

}

класс соединения:импортное основание

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

}

}

1 ответ

Решение

Первое: вам не нужны потоки для асинхронного ввода-вывода. IO может быть запланирован через GCD на runloop. Это хорошее введение: что нового в GCD.

Второе: я не уверен, что вы пытаетесь достичь с помощью dispatch_async секция кода. Он просто запускает print во вторичной ветке. Затем вы положили self.a.initNetworkCommunication назад в основную тему...

В-третьих: Глядя на код этого ChatClientSwift - a.sendData() кажется, делает блокировку записи. Который, ну, блоки...

Существует довольно много библиотек сокетов Swift GCD. Это одно: SwiftSockets, есть и другие. Вы, вероятно, хотите посмотреть на такое.

Другие вопросы по тегам