Avatar
Avatar
trickart
Network FrameworkでのTCPソケット通信の実装方法について質問です。 現在、iOSアプリでLAN内のホストとTCPソケット通信でやり取りするアプリを作ろうとしています。 当初はStreamを使って通信処理を書こうと思ったのですが、 CFStreamCreatePairWithSocketToHost(_:_:_:_:_:) はiOS15でdeprecatedになっており、「Jump to Definition」でインターフェイスを確認すると「Use nwconnection_t in Network framework instead」となっていたためNetwork Frameworkを使うことにしました。 ところがNetwork FrameworkのNWConnectionの receive(minimumIncompleteLength:maximumLength:completion:) メソッドは一度実行した後データを受信した場合、その後データが送られてきても何も起きないため、StreamDelegateの `stream(:handle:) がデータを受信するたびに実行されるのとは違う形のようでした。 今回実装したいアプリの通信の性質上、「いつ何回データが送られてくるか?」はあらかじめ把握できないため、StreamDelegateのように受信するたびにメソッドが実行される形が望ましいと考えております。 素朴な考えでは receive(minimumIncompleteLength:maximumLength:completion:) のcompletionの中で receive(minimumIncompleteLength:maximumLength:completion:) を呼ぶようにすれば何度データが送られてきてもcompletionが実行される実装に出来ると思ったのですが、この実装方法で問題ないかアドバイスをいただきたいです。 ( [weak self] を使っているから問題ない気がするけど循環参照の問題はないか?とかreceiveの取りこぼしがないか?が気になっています。) swift import Foundation import Network final class Client { let connection: NWConnection init(host: String, port: UInt16) { connection = NWConnection( to: .hostPort(host: .init(host), port: .init(integerLiteral: port)), using: .tcp ) } deinit { connection.cancel() } func start() { connection.start(queue: .main) addReceive() } func send(_ bytes: [UInt8]) { connection.send(content: bytes, completion: .contentProcessed { _ in // do something. }) } private func addReceive() { connection.receive(minimumIncompleteLength: .zero, maximumLength: .max) { [weak self] content, context, isComplete, error in // do something. self?.addReceive() } } } ` ご回答いただけますと幸いです.
omochimetaru 5/16/2023 7:46 AM
僕がNetwork.frameworkでソケット通信するときは、 receivecompletion の中で receive を呼ぶループを組みますね。一般的にはそうなると思います。
t_naruhodo 1