我正在编写一个简单的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
属性的任何帮助将非常感激。
答案 0 :(得分:1)
这里似乎有一些问题(p2p是一个复杂的主题):
对等方名称MCPeerID(displayName:)不是对等方标识符,它只是针对人类观看者(例如,聊天室用户)。下面的要点3)显示了对等方在宣传其存在时如何包括其他用户信息的方式。
框架(MC)为您创建一个唯一的对等ID,并建议在应用程序启动(MCPeerID - official docs - example objetive-c using NSUserDefaults storage api)期间重复使用该应用程序(即,持久并重新加载)。
在您的模型中,您正在序列化Task,很好(尽管没有提到什么格式,.xml,.plist,.json等),但是我不明白您为什么要序列化这些MCPeerID? 连接中的每个对等方都应重用自己的peerID,并且,可选地,如果他们希望向潜在的对等方宣传其他信息,则可以向字典提供有关对等方对象背后的业务用户的信息,例如:
byteArray[0] = byteArray[0].plus(byteToAdd).toByte()
(MCNearbyServiceAdvertiser docs)。
我将框架(MC)与业务模型(任务,用户...)分开,像这样:
myAdvertiser = MCNearbyServiceAdvertiser(peer: reusableLocalPeerID, discoveryInfo: ["uuidStr" : "my-user-id-here"], serviceType: "my-tasks-app")
上面第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: ...)]