Сеть

Еще в темные века, когда я вошел в мир вычислений, способ заставить два компьютера общаться друг с другом заключался в использовании черной магии, также известной как сокеты.

Техники Apple, которые, как я должен признать, довольно хороши в разработке фреймворков, решили обратить внимание на обновление сокетов. Они сделали это с помощью Network framework, опубликованной в 2018 году.

Я надеюсь, что в этой статье я расскажу о супер простой реализации сокета. Я также надеюсь окунуться в SwiftUI, пока я тоже это делаю. Мне нравится вызов.

Когда начать. Хорошо, есть два варианта: TCP и UDP. Короче говоря, TCP-сокеты гарантируют доставку, а UDP-сокеты — нет. TCP полезен, когда вам нужно убедиться, что отправленное вами сообщение прибыло. Сокеты UDP полезны, когда вас больше волнует скорость.

В этой статье я сосредоточусь на UDP, потому что их немного проще реализовать :) и, возможно, они более интересны читателю, поскольку они представляют собой своего рода сокеты, которые вы хотите использовать для того убийственного игрового приложения, которое вы намеревались разработать.

Теперь, как и во всех разговорах, у нас есть кто-то, кто говорит, и кто-то, кто слушает. Пара сокетов в socketese. На одном устройстве вы слушаете, а на другом говорите.

Давайте начнем с создания проекта, назовем его nudeNetworking, почему бы и нет. Я использую iOS 13, Swift 5 и Xcode 11.3.1.

Создайте проект и используйте шаблон Hello World, который вы получаете при выборе интерфейса SwiftUI. Затем создайте отдельный файл для кода нашей сети, класс, который мы назовем Connect. Вот код для этого.

import Network
class Connect: NSObject {
private var talking: NWConnection?
private var listening: NWListener?
func listenUDP(port: NWEndpoint.Port) {
do {
self.listening = try NWListener(using: .udp, on: port)
self.listening?.stateUpdateHandler = {(newState) in
switch newState {
case .ready:
print("ready")
default:
break
}
}
self.listening?.newConnectionHandler = {(newConnection) in
newConnection.stateUpdateHandler = {newState in
switch newState {
case .ready:
print("new connection")
self.receive(on: newConnection)
default:
break
}
}
newConnection.start(queue: DispatchQueue(label: "new client"))
}
} catch {
print("unable to create listener")
}
self.listening?.start(queue: .main)
}

Итак, у нас есть слушатель [слушающий] и говорящий [говорящий]. конечно, есть больше случаев, чем я включил здесь, вы должны добавить их. Нам нужно сосредоточиться на голом здесь.

Внимательные читатели, возможно, заметили, что здесь в коде есть метод, который не определен. Я определил это здесь.

func receive(on connection: NWConnection) {
connection.receiveMessage { (data, context, isComplete, error) in
if let error = error {
print(error)
return
}
if let data = data, !data.isEmpty {
let backToString = String(decoding: data, as: UTF8.self)
print("b2S",backToString)
}
}
}

Я добавил здесь проверку ошибок, потому что это не так очевидно для непосвященного читателя, строго говоря, это не голое кодирование.

Теперь у вас почти голые кости, вам просто нужно начать слушать. Вы делаете это в представлении, добавляя этот код ContentView.swift.

Text(“Hello World”).onAppear {
let communication = Connect()
let port2U = NWEndpoint.Port.init(integerLiteral: 1984)
communication.listenUDP(port: port2U)
}

Теперь вы должны быть в состоянии скомпилировать и запустить его. На экране вы увидите слова «Hello World», что абсолютно бесполезно, но полезно, ваш сетевой код также будет работать в фоновом режиме. Чтобы проверить это, вам нужно отправить что-то в сокет UDP, который вы слушаете. Для этого запустите эту команду на терминале.

echo -n "peek" | nc -4u -w1 192.168.1.123 1984

Вам не нужно беспокоиться обо всех флагах здесь, только об IP-адресе [который должен быть вашим устройством или компьютером, если вы работаете в симуляторе, и номером порта «1984», который исходит из кода, см. выше ].

Запустите приложение и попробуйте эхо. Вы должны увидеть слово «Peek» на экране отладки.

SwiftUI

Хорошо, я знаю, о чем ты думаешь. Приложение, которое выводит что-то на консоли отладки, не очень полезно, как насчет SwiftUI.

Apple представила SwiftUI в 2019 году, когда они это сделали, они показали ряд интересных способов соединения вещей вместе, хотя, к сожалению, в моем исследовании для этой статьи я не нашел этот метод для выполнения того, что я хочу здесь, поэтому имейте в виду, что мы ре будет летать наши штаны здесь.

В планах вывод данных отправить на этикетку. Мы можем начать с класса Connect. Давайте создадим внутри него еще один класс и опубликуем через него переменную.

class BlobModel: ObservableObject {
static let sharedInstance = BlobModel()
@Published var score: String = ""
}
var globalVariable = BlobModel()

@Published — это новый класс тегов, появившийся в SwiftUI. Затем нам нужно заменить наш оператор печати в методе приема класса Connect, чтобы установить значение нашей переменной score, которую мы только что определили. Обратите внимание, что я использовал синглтон для оценки, потому что, говоря словами манты SwiftUI, мне нужен единственный источник правды :)

DispatchQueue.main.async {
globalVariable.score = backToString
}

Также обратите внимание, что я запускаю это в основном потоке, это важно сделать, поскольку этот оператор будет действовать путем обновления дисплея.

Мы почти закончили. Теперь нам просто нужно внести несколько небольших изменений в класс ContentView, полную копию которого я привожу сюда для простоты.

struct ContentView: View {
@ObservedObject var globalVariable:BlobModel = BlobModel.sharedInstance
var body: some View {
Text("\(globalVariable.score)")
.onAppear {
let communication = Connect()
let port2U = NWEndpoint.Port.init(integerLiteral: 1984)
communication.listenUDP(port: port2U)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(globalVariable: globalVariable)
}
}

Теперь, если вы снова запустите это эхо, вы увидите слово, которое вы только что отправили, на экране вашего устройства. Попробуйте другую ноту, скажем, «заглянуть» или «поп». И это все, что я закрываю статью.

Хотя прямо перед тем, как я уйду, вы правы, мы проделали наполовину работу над сетевым кодом, где же речь, вы можете справедливо спросить. Это будет в следующем голом выпуске Networking.