MultipeerConnectivity MCPeerID不符合Codable

时间:2018-06-06 12:51:19

标签: ios json swift multipeer-connectivity

我正在编写一个简单的P2P聊天程序,到目前为止,我一直将MCPeerID的displayName属性存储为模型中的字符串,以确定将特定邮件发送给谁。在每次发送操作中,只要displayName与我模型中的字符串匹配,我就会搜索connectedPeers数组并将MCPeerID复制到接收者列表中。

在两个对等方具有相同名称的情况下,这可能会有问题。我也不满足于搜索每个发送。所以我试图在我的模型中直接使用MCPeerID。但是,Xcode抱怨MCPeerID不符合Encodable和Decodable,我不知道如何解决这个问题。

我的模型代表一个维护参与者列表的主题以及谁说出什么的日志。因此,我可以在新参与者加入时更新新参与者,并在添加新消息时更新现有参与者。我的模型如下所示:

import Foundation
import MultipeerConnectivity


class Task : Codable {
    var uuidStr: String = UUID().uuidString
    var topic : String
    var history : [String] = []
    var users : [MCPeerID] = []

    ...

    private enum CodingKeys: String, CodingKey {
        case uuidStr
        case topic
        case history
        case users
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(uuidStr, forKey: .uuidStr)
        try container.encode(topic, forKey: .topic)
        try container.encode(history, forKey: .history)
        try container.encode(users, forKey: .users)
    }

    ...

}

(我没有展示标准的init(),因为这不是问题所在。)

查看文档后,我看到一个带有签名MCPeerID.init?(coder: NSCoder)func encode(with: NSCoder)的方法,但我不确定如何指定NSCoder参数。有关如何序列化users属性的任何帮助将非常感激。

1 个答案:

答案 0 :(得分:1)

这里似乎有一些问题(p2p是一个复杂的主题):

1.识别用户(业务级别),

对等方名称MCPeerID(displayName:)不是对等方标识符,它只是针对人类观看者(例如,聊天室用户)。下面的要点3)显示了对等方在宣传其存在时如何包括其他用户信息的方式。

2.识别对等点(网络级别),

框架(MC)为您创建一个唯一的对等ID,并建议在应用程序启动(MCPeerID - official docs - example objetive-c using NSUserDefaults storage api)期间重复使用该应用程序(即,持久并重新加载)。

3.共享对等会话信息(会话级别)

在您的模型中,您正在序列化Task,很好(尽管没有提到什么格式,.xml,.plist,.json等),但是我不明白您为什么要序列化这些MCPeerID? 连接中的每个对等方都应重用自己的peerID,并且,可选地,如果他们希望向潜在的对等方宣传其他信息,则可以向字典提供有关对等方对象背后的业务用户的信息,例如:

byteArray[0] = byteArray[0].plus(byteToAdd).toByte()

MCNearbyServiceAdvertiser docs)。

4.分离关注点(数据级别)

我将框架(MC)与业务模型(任务,用户...)分开,像这样:

myAdvertiser = MCNearbyServiceAdvertiser(peer: reusableLocalPeerID, discoveryInfo: ["uuidStr" : "my-user-id-here"], serviceType: "my-tasks-app")

5.序列化

上面第2点的Apple示例显示了如何使用UserDefaults api序列化MCPeerID。

通常,当扩展Codable时,人们还希望在应用程序中的某处使用编码器(JSON,XML等), 将有问题的对象传递到此编码器的.encode(...)方法,例如:

class Task: Codable { var users: [User] ... }
class User: Codable { uid:String ...}
struct PeerRecord: { var peer:MCPeerID, var user_id:String, var name:String ... }
var foundPeers:[MCPeerID]
var connectedPeers:[String:PeerRecord] // e.g. ["a-user-id": PeerRecord(peer: ...)]