MultipeerConnectivity data Convert to Dictionary

I have a variable in Dictionary type. How can I change the data on the Section Function to Dictionary?

Stringdata in the Section function shows the same value in both variables? I have to separate these values. How can I do that ?

ViewModel

Code Block
@Published var dictionaryValues:[String: String] = ["word":"","answer":""]

Random Word Session Func
Code Block
func randomWordSession() {
        guard let word = dictionaryValues["word"]?.data(using: .utf8) else { return }
        guard let pears = session?.connectedPeers else { return }
        do {
            try session?.send(word, toPeers: pears, with: .reliable)
        } catch {
            print(error.localizedDescription)
        }
    }

Answer Session

Code Block
func answerSession() {
        guard let answer = dictionaryValues["answer"]?.data(using: .utf8) else { return }
        guard let peers = session?.connectedPeers else { return }
        do {
            try session?.send(answer, toPeers: peers, with: .reliable)
        } catch {
            print(error.localizedDescription)
        }
    }

Session Func

Code Block
func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
        if let stringData = String(data: data, encoding: .utf8) {
            DispatchQueue.main.async {
                self.dictionaryValues["word"] = stringData
                self.dictionaryValues["answer"] = stringData
            }
        }
    }

Answered by workingdogintokyo in 671362022
Yes, as I said, you have to encode/decode this. Try this:

Code Block
extension Encodable {
func encode(with encoder: JSONEncoder = JSONEncoder()) throws -> Data {
return try encoder.encode(self)
}
}
extension Decodable {
static func decode(with decoder: JSONDecoder = JSONDecoder(), from data: Data) throws -> Self {
return try decoder.decode(Self.self, from: data)
}
}
func randomWordSession() {
guard let word = try? MyMessage(type: 0, data: dictionaryValues["word"] ?? "").encode() else { return }
...
}
func answerSession() {
guard let answer = try? MyMessage(type: 1, data: dictionaryValues["answer"] ?? "").encode() else { return }
...
}

Instead of sending a String I would send a message (MyMessage) where
you can include a type, for example:

Code Block
public struct MyMessage: Codable {
var type: Int // 0=word, 1=answer
var data: String // the string value
public init(type: Int, data: String) {
self.type = type
self.data = data
}
}


You will have to encode/decode this, then you can find what type of message you received:

Code Block
func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
if let response = try? MyMessage.decode(from: data) {
DispatchQueue.main.async {
if response.type == 0 {
self.dictionaryValues["word"] = response.data
} else {
self.dictionaryValues["answer"] = response.data
}
}
} else {
// deal with no data
}
}

I get an error while decoding.

Code Block
Error: Type 'MyMessage' has no member 'decode'

Accepted Answer
Yes, as I said, you have to encode/decode this. Try this:

Code Block
extension Encodable {
func encode(with encoder: JSONEncoder = JSONEncoder()) throws -> Data {
return try encoder.encode(self)
}
}
extension Decodable {
static func decode(with decoder: JSONDecoder = JSONDecoder(), from data: Data) throws -> Self {
return try decoder.decode(Self.self, from: data)
}
}
func randomWordSession() {
guard let word = try? MyMessage(type: 0, data: dictionaryValues["word"] ?? "").encode() else { return }
...
}
func answerSession() {
guard let answer = try? MyMessage(type: 1, data: dictionaryValues["answer"] ?? "").encode() else { return }
...
}

MultipeerConnectivity data Convert to Dictionary
 
 
Q