为啥通过 Multipeer Connectivity 发送的字符串在接收端会出现乱码?

Posted

技术标签:

【中文标题】为啥通过 Multipeer Connectivity 发送的字符串在接收端会出现乱码?【英文标题】:Why are strings sent via Multipeer Connectivity garbled on the receiving end?为什么通过 Multipeer Connectivity 发送的字符串在接收端会出现乱码? 【发布时间】:2018-10-16 14:59:16 【问题描述】:

我正在开发一个增强现实应用程序,在该应用程序中,多个用户可以连接并查看相同的虚拟内容。我正在使用 Apple 的 Multipeer Connectivity 框架进行通信,但在两个连接的对等方之间发送和接收字符串时遇到问题。

这个想法是当一个 SCNNode 被添加到用户的虚拟空间时,Multipeer 将通过对等网络发送节点在 3D 空间中的位置、颜色和大小,接收节点可以添加相同的内容到他们的空间。

我这样构建字符串:

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) 
    let nodeColor = node.geometry?.firstMaterial?.diffuse.contents
    let nodePosition = node.position
    let dataString = "x: \(nodePosition.x) y: \(nodePosition.y) z: \(nodePosition.z) color: \(nodeColor!) radius: \(sphereRadius)"
    let dataToSend = dataString.data(using: .utf8)
    MultiPeer.instance.send(data: dataToSend!)


这是发送数据的函数:

public func send(data: Data)
    if isConnected 
        do 
            let item = try NSKeyedArchiver.archivedData(withRootObject: data, requiringSecureCoding: true)
            try session.send(item, toPeers: session.connectedPeers, with: MCSessionSendDataMode.reliable)
         catch let error 
            printDebug(error.localizedDescription)
        
    


在接收端:

public func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) 
    let incomingString = String(decoding: data, as: UTF8.self)
    print(incomingString)


我通过发送字符串测试了代码,这是其中三个字符串在接收端的输出:

Troot�#-27:@����bplist00�X$versionX$objectsY$archiverT$top:-0.04734481 z: -0.019065317 color: UIExtendedSRGBColorSpace 1 0 0 1 radius: 0.01_NSKeyedArchiver�

Troot�#-27:@����bplist00�X$versionX$objectsY$archiverT$topIExtendedSRGBColorSpace 1 0 0 1 radius: 0.01_NSKeyedArchiver�

Troot�#-27:@����bplist00� X$versionX$objectsY$archiverT$top\277\275U$nullOax: 0.01673067 y: -0.048672535 z: -0.02221658 color: UIExtendedSRGBColorSpace 1 0 0 1 radius: 0.01_NSKeyedArchiver�

很明显,字符串正在被发送和接收,但并非没有额外的字符和符号。 任何意见表示赞赏,谢谢!

更新:Martin R. 指出我没有使用 NSKeyedUnarchiver 来解码字符串。我已经更新了我的代码以使用它:

let receivedData = data
let receivedString = String(data: receivedData, encoding: .utf8)
print("Received data \(String(describing: receivedString))")


do 
    let unarchiver = try NSKeyedUnarchiver(forReadingFrom: receivedData)
    let decodedString = unarchiver.decodeData()
    print("Decoded string: \(String(describing: decodedString))")
catch let error 
    print(error.localizedDescription)

字符串不再乱码,但它是 nil。在解码之前是这样,所以对端接收到的字符串是 nil。

【问题讨论】:

想一想:如果发送方使用 NSKeyedArchiver 来打包数据,那么接收方必须使用 NSKeyedUnarchiver 来解包。 @MartinR 谢谢,我不敢相信我错过了!但是,现在我收到一个 nil 字符串,而不是乱码。我更新了我的问题。 【参考方案1】:

@Martin R. 通过使用 NSKeyedUnarchiver 解压缩数据的建议解决了添加符号的问题。之后,我发现接收端的字符串为零。改变

do 
    let unarchiver = try NSKeyedUnarchiver(forReadingFrom: receivedData)
    let decodedString = unarchiver.decodeData()
    print("Decoded string: \(String(describing: decodedString))")
catch let error 
    print(error.localizedDescription)

do 
    let decodedString = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(receivedData)
    print("Decoded string: \(String(describing: decodedString))")
catch let error 
    print(error.localizedDescription)

修复了问题,现在可以正确发送和接收字符串。

【讨论】:

以上是关于为啥通过 Multipeer Connectivity 发送的字符串在接收端会出现乱码?的主要内容,如果未能解决你的问题,请参考以下文章

无法通过 Multipeer Connectivity 连接蓝牙

通过 Multipeer Connectivity 发送 MPMediaItem

我可以通过 iOS Multipeer Connectivity 发送多大的消息?

通过 Multipeer Framework 临时同步两个客户端

iOS8 AVAudioEngine如何通过Multipeer Connectivity发送麦克风数据?

iOS 7:通过 wi-fi 或对等 wi-fi 使用 Multipeer Connectivity 连接设备