Reputation: 93
I'm testing out Apple's Multiuser AR demo app with ARKit 2.0 that was introduced in WWDC 2018: Creating a multiuser AR experience.
The documentation says that after each device relocalizes to the same World Map
, only the information needed to recreate each user action is shared among devices (e.g. if the user taps on the screen and a 3D object appears, only that new object's ARAnchor
should be sent to other devices). For me, while it shows all the 3D characters that were placed by the sending device before it captured and sent a World Map, it doesn't show any objects that are added after the World Map has been sent. The error I'm getting says:
// can't decode data recieved from peer.
Has anyone had this issue and knows what it's about?
I haven't changed anything in the demo code.
Upvotes: 6
Views: 512
Reputation: 58113
In MultipeerConnectivity ARSession several peers share data among each other. But sent and received data must be, at first, archived and then unarchived using two instance methods of NSKeyedArchiver
and NSKeyedUnarchiver
classes:
func archive(worldMap: ARWorldMap) throws {
let data = try NSKeyedArchiver.archivedData(withRootObject: worldMap,
requiringSecureCoding: true)
try data.write(to: worldMapURL, options: [.atomic])
}
and:
func unarchive(worldMapData: Data) -> ARWorldMap? {
guard let unarchievedData = try? NSKeyedUnarchiver.unarchivedObject(ofClass: ARWorldMap.self,
from: worldMapData)
else { return nil }
return unarchievedData
}
Hence, if you get the following message in Xcode Console:
"can't decode data received from peer"
it means the error occurred while transferring or unarchiving a ARWorldMap data.
Upvotes: 0
Reputation: 41
I had the same trouble but I kind of solved it in this way.
(1)first create a variable to check if the world map has send.
var worldMapHasInited: Bool = false
(2)Then in func shareSession(_ button: UIButton) add this line to the end below
self.multipeerSession.sendToAllPeers(data)
self.worldMapHasInited = true
(3)And finally in func receivedData(_ data: Data, from peer: MCPeerID)
check if the world map has sent, if is sent, skip checking if the data contains world map or not.
if !worldMapHasInited {
if let worldMap = try NSKeyedUnarchiver.unarchivedObject(ofClass: ARWorldMap.self, from: data)
{
//....
// when received world map, set the receiver's
// worldMapHasInited to true
self.worldMapHasInited = true
}
}
else
if let anchor = try NSKeyedUnarchiver.unarchivedObject(ofClass: ARAnchor.self, from: data) {
// ...
}
This will directly check if the data contains anchor or not.
Upvotes: 0