😎
シミュレータで試せるNearbyInteractionの最小実装(Swift)
はじめに
iOS 14 から NearbyInteraction
とかあったなあというのを思い出しました。
デバイス間の相対位置が確認できるやつみたいです。
こんな感じでシミュレータでも確認ができます。
公式のサンプルもあるのですがトークンのやりとりに MultipeerConnectivity
などを使わないといけないのでできるだけ少ないコードで動作確認できるものを目指してみました。
環境
- Xcode 14.3
- iOS 16.4
トークンの取得
NearbyInteraction
を試すには NIDiscoveryToken
を端末間でやりとりする必要があります。
ちゃんとしたアプリを作るなら CoreBluetooth
や MultipeerConnectivity
などを使ってやりとりする必要があるかと思います。今回はシミュレータで動かしてみたかっただけなのでファイルに書き出してそのファイルを手動で渡すことにします。
MultipeerConnectivity
使ってやりたい方はこちらを参考にどうぞ(ファイルの読み書きしているところを書き換えればいけると思います)。
Multipeer ConnectivityでのP2P通信(Swift)
実装
ストーリーボードはこんな感じでラベルとボタンを置いただけです。
コードはこんな感じで 50 行くらいでおさまりました👏
import UIKit
import NearbyInteraction
final class ViewController: UIViewController {
// ここ書き換える
private let isWriting = true
@IBOutlet private weak var label: UILabel!
private var session: NISession!
private let tokenDirectoryPath = NSHomeDirectory() + "/Documents"
private var tokenFilePath: String {
return tokenDirectoryPath + "/token"
}
override func viewDidLoad() {
super.viewDidLoad()
print("directoryPath: \(tokenDirectoryPath)")
if NISession.deviceCapabilities.supportsPreciseDistanceMeasurement {
session = NISession()
session.delegate = self
}
}
@IBAction private func tokenKonekone(_ sender: Any) {
if isWriting {
writeToken()
} else {
readToken()
}
}
private func writeToken() {
if let discoveryToken = session.discoveryToken,
let token = try? NSKeyedArchiver.archivedData(withRootObject: discoveryToken, requiringSecureCoding: true) {
FileManager.default.createFile(atPath: tokenFilePath, contents: token, attributes: nil)
}
}
private func readToken() {
if let data = FileManager.default.contents(atPath: tokenFilePath),
let token = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NIDiscoveryToken.self, from: data) {
let config = NINearbyPeerConfiguration(peerToken: token)
session.run(config)
}
}
}
extension ViewController: NISessionDelegate {
func session(_ session: NISession, didUpdate nearbyObjects: [NINearbyObject]) {
label.text = String(format: "%0.2f m", nearbyObjects.compactMap { $0.distance }.max() ?? 0)
}
}
動作確認
シミュレータは iOS 16 未満か iOS 16.4 を使ってください。iOS 16.1 で確認してみましたが NISession()
でクラッシュします。
参考:NISession creation not working
以下が実行手順です。
- シミュレータ A で
private let isWriting = true
の状態で実行 - コンソールにトークン保存用フォルダのパスが出力される
- Finder -> 移動 -> フォルダへ移動... を開きコピペして該当フォルダに移動
- シミュレータ A のアプリを停止
- シミュレータ B で
private let isWriting = false
の状態で実行 - 3同様にシミュレータ B のフォルダに移動
- シミュレータ B のアプリを起動したままシミュレータ A のアプリを起動
- シミュレータ A でボタンを押下してトークンを出力
- シミュレータ A のフォルダの token ファイルをシミュレータ B のフォルダに移動
- シミュレータ B でボタンを押下すれば完成!
おわりに
これでサクッと NearbyInteraction
で遊べるようになりました✌️
U1 チップ対応端末も増えてきたのでいろいろ遊べる気がします。
Discussion