如何使用 Apple 的 NearbyInteraction 框架连接多个设备(实现多个正在进行的会话)
Posted
技术标签:
【中文标题】如何使用 Apple 的 NearbyInteraction 框架连接多个设备(实现多个正在进行的会话)【英文标题】:How to connect multiple devices (implement multiple ongoing sessions) using Apple's NearbyInteraction Framework 【发布时间】:2021-02-20 01:46:30 【问题描述】:我正在编写一个应用程序,该应用程序需要具有使用 Apple 的 NearbyInteraction 框架连接的多个 iPhone 的功能。我需要有多个正在进行的 NISession 才能在任何特定时间将多个 iPhone 相互连接。我一直在玩 Apple 提供的一个项目的示例代码,它只实现了一个允许一个会话在任何特定时间存在的程序。可以在以下位置找到:https://developer.apple.com/documentation/nearbyinteraction/implementing_interactions_between_users_in_close_proximity
我正在通过 MultipeerConnectivity 发送发现令牌(需要启动每个新会话),这似乎工作正常。下面的代码或多或少是 Apple 提供的代码,适用于一个会话。如果我使用另一部 iPhone 尝试创建第二个会话,我会从第二个设备接收到发现令牌(通过 MultiPeer 连接),但是当第二个会话应该同时启动时,两个会话都会失效并停止工作。
是否有人可以帮助我正确地指导我如何调整下面的代码以允许多个正在进行的会话连接多个设备?
func startup()
// Create the NISession.
session = NISession()
session?.delegate = self
// Since the session is new, this token has not been shared.
sharedTokenWithPeer = false
// If 'connectedPeer' exists, share the discovery token if needed.
if connectedPeer != nil && mpc != nil
if let myToken = session?.discoveryToken
print("Initializing...")
if !sharedTokenWithPeer
shareMyDiscoveryToken(token: myToken)
else
fatalError("Unable to get self discovery token, is this session invalidated?")
else
print("Discovering Peer...")
startupMPC()
currentDistanceDirectionState = .unknown
func session(_ session: NISession, didUpdate nearbyObjects: [NINearbyObject])
guard let peerToken = peerDiscoveryToken else
fatalError("don't have peer token")
// Find the right peer.
let peerObj = nearbyObjects.first (obj) -> Bool in
return obj.discoveryToken == peerToken
guard let nearbyObjectUpdate = peerObj else
return
func session(_ session: NISession, didRemove nearbyObjects: [NINearbyObject], reason: NINearbyObject.RemovalReason)
guard let peerToken = peerDiscoveryToken else
fatalError("don't have peer token")
// Find the right peer.
let peerObj = nearbyObjects.first (obj) -> Bool in
return obj.discoveryToken == peerToken
if peerObj == nil
return
switch reason
case .peerEnded:
// Peer stopped communicating, this session is finished, invalidate.
session.invalidate()
// Restart the sequence to see if the other side comes back.
startup()
case .timeout:
// Check the configuration is still valid and re-run the session.
if let config = session.configuration
session.run(config)
print("Peer Timeout")
default:
fatalError("Unknown and unhandled NINearbyObject.RemovalReason")
// Sharing and receiving discovery token via mpc mechanics
func startupMPC()
if mpc == nil
// Avoid any simulator instances from finding any actual devices.
#if targetEnvironment(simulator)
mpc = MPCSession(service: "nisample", identity: "com.example.apple-samplecode.simulator.peekaboo-nearbyinteraction", maxPeers: 7)
#else
mpc = MPCSession(service: "nisample", identity: "com.example.apple-samplecode.peekaboo-nearbyinteraction", maxPeers: 7)
#endif
mpc?.peerConnectedHandler = connectedToPeer
mpc?.peerDataHandler = dataReceivedHandler
mpc?.peerDisconnectedHandler = disconnectedFromPeer
mpc?.invalidate()
mpc?.start()
func connectedToPeer(peer: MCPeerID)
guard let myToken = session?.discoveryToken else
fatalError("Unexpectedly failed to initialize nearby interaction session.")
print(peer.displayName)
if connectedPeer.count > 1
//fatalError("Already connected to a peer.")
print(connectedPeer)
if !sharedTokenWithPeer
shareMyDiscoveryToken(token: myToken)
connectedPeer.append(peer)
peerDisplayName = peer.displayName
func disconnectedFromPeer(peer: MCPeerID)
if connectedPeer.contains(peer)
connectedPeer.removeAll(where: $0 == peer)
sharedTokenWithPeer = false
func dataReceivedHandler(data: Data, peer: MCPeerID)
guard let discoveryToken = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NIDiscoveryToken.self, from: data) else
fatalError("Unexpectedly failed to decode discovery token.")
peerDidShareDiscoveryToken(peer: peer, token: discoveryToken)
func shareMyDiscoveryToken(token: NIDiscoveryToken)
guard let encodedData = try? NSKeyedArchiver.archivedData(withRootObject: token, requiringSecureCoding: true) else
fatalError("Unexpectedly failed to encode discovery token.")
mpc?.sendDataToAllPeers(data: encodedData)
sharedTokenWithPeer = true
func peerDidShareDiscoveryToken(peer: MCPeerID, token: NIDiscoveryToken)
// Create an NI configuration
peerDiscoveryToken = token
let config = NINearbyPeerConfiguration(peerToken: token)
// Run the session
session?.run(config)
【问题讨论】:
【参考方案1】:从您提供的代码摘录来看,您只创建了 1 个NISession
。这不适用于超过 1 个同行。
您需要为每个对等设备创建一个NISession
对象。您可以将会话存储在字典中(他们在 WWDC 视频中推荐)。您可以使用 MCPeerID 作为密钥来识别对等设备。这对我有用。
【讨论】:
以上是关于如何使用 Apple 的 NearbyInteraction 框架连接多个设备(实现多个正在进行的会话)的主要内容,如果未能解决你的问题,请参考以下文章
如何配置 Mailgun 以与 Sign in with Apple 和 Apple 的中继服务一起使用?
如何在 ionic 3 应用程序中添加“使用 Apple 登录”?
如何使用 JavaScript 从 Apple Pay 获取与 Apple Pay 帐户关联的用户电子邮件地址