我正在通过解析服务器在ios中进行聊天应用程序。我创建了一个MessageRoom集合,它通过PFRelation与用户有很多关系。现在我很震惊。每当用户开始新的对话时,我都会在MessageRoom集合中添加新条目,并在该组的消息中使用其id。但是当我想要获取之前的对话时,让我们说5个用户之间的对话,我将如何查询与其关系中具有完全相同的5个用户(不多或少)的messageRoom?
这是我用来创建或获取Message Room的代码。它无法正常工作。它的作用是不是第一次创建一个新的messageRoom而是为后一个用户提取相同的内容,而是每次都建立一个新的消息室。
class func createOrGetMessageRoom(users:[PFUser], description:String)->PFObject{
var returnMessageRoom:PFObject = PFObject(className: PF_MESSAGE_ROOM_CLASS_NAME);
let users = users.sort(increasingIDs)
let query:PFQuery = PFQuery(className: PF_MESSAGE_ROOM_CLASS_NAME)
query.whereKey(PF_MESSAGE_ROOM_USERS, containsAllObjectsInArray : users)
query.findObjectsInBackgroundWithBlock{(objects, error )->Void in
if error == nil {
if objects?.count == 0 {
let messageRoom = PFObject(className: PF_MESSAGE_ROOM_CLASS_NAME)
messageRoom[PF_MESSAGE_ROOM_DESCRIPTION] = description
messageRoom[PF_MESSAGE_ROOM_LAST_USER] = PFUser.currentUser()
messageRoom[PF_MESSAGE_ROOM_LAST_MESSAGE] = ""
messageRoom[PF_MESSAGE_ROOM_COUNTER] = 0
messageRoom[PF_MESSAGE_ROOM_UPDATE_TIME] = NSDate()
let messageUsers = messageRoom.relationForKey(PF_MESSAGE_ROOM_USERS)
for user in users {
messageUsers.addObject(user)
}
messageRoom.saveInBackgroundWithBlock{(success,error)->Void in
if error == nil {
returnMessageRoom = messageRoom
}
}
}else{
returnMessageRoom = objects![0]
}
}else{
print("Message.createMessage Erorr");
print(error)
}
}
return returnMessageRoom
}
class func increasingIDs(user1: PFUser, user2: PFUser) -> Bool {
return user1.objectId < user2.objectId
}
我还检查了this application。它的作用是每当它开始一个新的聊天时,它按升序连接用户的objectIds并将其用作groupId,用于将来的引用并在聊天消息中用作外键。
它可以在私人聊天和群聊中使用,但是如果用户已经开始群聊,并且想要在此聊天中添加新用户,会发生什么?如果我们通过连接此用户ID来简单地更改组ID,则使用旧组ID的先前消息将不再出现在此消息组中。
还告诉我,这种通过串联制作groupID的方法是否更好,或者很多很多关系更好?
答案 0 :(得分:0)
您的功能createOrGetMessageRoom
存在的一个问题是,findObjectsInBackgroundWithBlock
异步,而您并未将其考虑在内。
这意味着findObjectsInBackgroundWithBlock
函数在createOrGetMessageRoom
返回后很长时间才会收到回复。
因此,您在函数第一行创建的PFObject
始终会返回 - 您的函数不会等待findObjectsInBackgroundWithBlock
返回MessageRoom。
要解决此问题,请让代码采取如下回调:
class func createOrGetMessageRoom(users:[PFUser], description:String, callback: (PFObject? -> Void)) {
let users = users.sort(increasingIDs)
let query:PFQuery = PFQuery(className: PF_MESSAGE_ROOM_CLASS_NAME)
query.whereKey(PF_MESSAGE_ROOM_USERS, containsAllObjectsInArray : users)
query.findObjectsInBackgroundWithBlock{(objects, error )->Void in
if error == nil {
if objects?.count == 0 {
let messageRoom = PFObject(className: PF_MESSAGE_ROOM_CLASS_NAME)
messageRoom[PF_MESSAGE_ROOM_DESCRIPTION] = description
messageRoom[PF_MESSAGE_ROOM_LAST_USER] = PFUser.currentUser()
messageRoom[PF_MESSAGE_ROOM_LAST_MESSAGE] = ""
messageRoom[PF_MESSAGE_ROOM_COUNTER] = 0
messageRoom[PF_MESSAGE_ROOM_UPDATE_TIME] = NSDate()
let messageUsers = messageRoom.relationForKey(PF_MESSAGE_ROOM_USERS)
for user in users {
messageUsers.addObject(user)
}
messageRoom.saveInBackgroundWithBlock{(success,error)->Void in
if error == nil {
callback(messageRoom)
}
callback(nil)
}
}else{
callback(objects![0])
}
}else{
print("Message.createMessage Erorr");
print(error)
callback(nil)
}
}
}
用法:
YourClass.createOrGetMessageRoom([], description: "description") { messageRoom in
// Do something...
}
答案 1 :(得分:0)
在我看来,db模式应该有3个集合,_User,MessageRoom和Message。
MessageRoom:users,roomName和其他信息。
消息:房间(MessageRoom的指针),消息(内容),发件人(_User指针)
下面是伪代码
在您的应用中,查询当前涉及的所有用户messageRooms。
var query = new Parse.Query("MessageRoom")
query.equalTo("users", currentUser);
//other constraint, roomName, createdAt, limit ...
query.find(...)
选择一个messageRoom对象,然后将其用于getMessages。
var query2 = new Parse.Query("Message");
query2.eqaulTo("room", roomObj);
query2.include("sender");
query2.descending("createdAt");
query2.find(...)