ARKitを使った空間共有アプリを作るに当たってデバイス間通信の実装についてよく考えています。
iPhoneどうしで通信するに当たって一番便利なのがMultiPeerConnectivityです。MultiPeerConnectivityはWifiやbluetooth、そしてiPhoneの持っているp2p通信のシステムを使ってローカルのデバイス間通信をするためのフレームワーク。
そしてこのMultiPeerConnectivityを上からラップして使いやすくしているライブラリにPeerKitがあります。
日本語記事だと以下で紹介されています。
[iOS][Swift] イベント駆動型で P2P 通信をするPeerKit
PeerKitに問題があったのでフォークした
しかし、このPeerKit、
- 繋がりにくい
- 一度外れると復活できない
などなどのバグが少しあり、そのまま使うとハマってしまいます。メンテされていると良いのですが、このライブラリは現在メンテされていないようです。
ということで僕がフォークしていくつか修正したのがkboy-silvergym/PeerKitです。
しかしまだ問題があって、うまく繋がらないことがありました。
もう上から編集していくのはきつい。。!ってことで、真似して新しいライブラリをつくってみました。
BeerKit
PeerKitを真似てBeerKitという名前で作ってみました。ビールで乾杯するというローカルコミュニケーションはまさにP2P通信と言っても過言ではありません。
PeerKitとの大きな違いはData型を渡す前提で作っているところです。
データ送るとき
let data: Data = try! JSONEncoder().encode(message)
BeerKit.sendEvent("message", data: data)
PeerKitはAny型を渡すように作られているのですが、これが少し罠で、中でNSKeyedArchiverでアーカイブされてDataになるので、NSCodingに準拠している型じゃないとダメで、準拠してない型を渡すとクラッシュします。
だったら最初からData型を渡すようにしようということで、作り直しました。
データ受け取るとき
BeerKit.onEvent { (peerId, event, data) in
guard let data = data,
let message = try? JSONDecoder().decode(MessageEntity.self, from: data) else {
return
}
self.messages.append(message)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
JSONにして送受信することを想定してデモアプリはつくられています。
まとめ
ということで、もし良ければBeerKit使ってみてくださいー!何かあればPRもお待ちしています。
あと、⭐️もお待ちしてます。