2016-05-13 7 views
0

私はparse serverを通してiosでチャットアプリケーションを作っています。私は、PFRelationを通じてユーザーとの関係が多岐にわたるMessageRoomコレクションを作成しました。今私は打たれている。ユーザーが新しい会話を開始するたびに、MessageRoomコレクションに新しいエントリを追加し、そのグループのメッセージにそのIDを使用します。しかし、私は以前の会話をフェッチしたいときは、5人のユーザー間の会話をしましょう、どのようにまったく同じ5人のユーザー(多かれ少なかれ)の関係にあるメッセージルームをどのようにクエリしますか?ParseのPFRelationがSwiftに全く同じ配列を含んでいるかどうかをチェックする方法

これは、メッセージルームの作成または取得に使用しているコードです。正しく動作していません。それは、新しいメッセージルームを最初に作成するのではなく、後者のユーザーに同じメッセージをフェッチすることで、毎回新しいメッセージングルームを作ります。

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もチェックしました。それは、新しいチャットを開始するたびに、ユーザーのobjectIdを昇順に連結し、将来の参照に使用され、チャットメッセージで外部キーとして使用されるgroupIdとして使用します。

プライベートチャットやグループチャットでは機能しますが、ユーザーがグループチャットを開始してこのチャットに新しいユーザーを追加する場合はどうなりますか?このユーザーIDを連結してグループIDを単純に変更すると、以前のグループIDを使用していた以前のメッセージはこのメッセージグループに表示されなくなります。

また、連結を介してgroupIDを作成するというこのアプローチが、より良い関係になっているのか、多対多関係が優れているのかを教えてください。

答えて

0

createOrGetMessageRoomの問題の1つは、findObjectsInBackgroundWithBlockで、非同期であることです。これは考慮していません。

これは、createOrGetMessageRoomが返された後、findObjectsInBackgroundWithBlock関数が応答時間が長いことを意味します。 したがって、関数の最初の行に作成する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) 
     } 
    } 
} 

使用法:私の心の中でDBスキーマは、あなたが3つのコレクション、_User、MessageRoomを持っている必要があり

YourClass.createOrGetMessageRoom([], description: "description") { messageRoom in 
    // Do something... 
} 
+0

こんにちは、それを指摘していただきありがとうございますが、問題は依然として続きます。それでも新しいメッセージを作成しています。すべてのメッセージに対応するルーム –

+0

'findObjectsInBackgroundWithBlock'の中にブレークポイントを追加して前進すると、どうなりますか? – paulvs

+0

0個のオブジェクトを与えています。しかし、containsAllObjectsInArrayをcontainsInに変更すると、オブジェクトが返されますが、これらに加えて他のユーザーもいるmessageRoomsも返されると思います。 –

0

、メッセージ。

MessageRoom:users、roomNameおよびその他の情報。

メッセージ:部屋(MessageRoomのポインタ)、MSG(コンテンツ)、送信者(_Userのポインタ)は、以下の

は、現在のすべてのユーザー関与messageRoomsを照会、あなたのアプリケーションでは擬似コード

です。

var query = new Parse.Query("MessageRoom") 
query.equalTo("users", currentUser); 
//other constraint, roomName, createdAt, limit ... 
query.find(...) 

を選択してから、getMessagesに使用します。

var query2 = new Parse.Query("Message"); 
query2.eqaulTo("room", roomObj); 
query2.include("sender"); 
query2.descending("createdAt"); 
query2.find(...) 
関連する問題