您如何使用Parse在iOS上设计和管理消息传递应用程序的数据?
我已经考虑了一段时间了,我感到茫然......如何高效快速地访问数据!?我知道我在SQL和东西中的方式,但这不是SQL ...我需要一个建议如何将事物联系在一起并将应用程序用户与他/她发送的消息连接以及使用Parse后端从其他用户接收消息。为每个用户创建类?每次谈话?或者只是在一个类中通过发送者和接收者ID的所有内容?当课程有200,000个参赛作品时,这仍然会很快吗?这是我的主要问题......如何管理应用程序的这一部分!
我目前正在开发一款应用程序,但是当我几个月前开始使用时,我没有考虑到这一点,因为我想刚刚开始而不是创造一些我不知道要开始的障碍用。
为了清理问题,我开始学习iOS同时开始这个项目...我是一名具有强大C /汇编背景的计算机工程师,这个iPhone的东西最初有点烦人但我已经习惯了。
编辑---------------------------------------------- ------------------------
所以我在我的messageViewController中的ViewWillAppear中有这个代码,它将在对话中加载消息。
PFQuery *Conversations = [PFQuery queryWithClassName:@"Conversations"];
[Conversations whereKey:@"recipientsIds" containedIn:self.recipients];
[Conversations findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(@"Error loading conversations");
}else{
// if no conversations found, create one and set conv. ID
if (objects.count == 0) {
PFObject *conversation = [PFObject objectWithClassName:@"Conversations"];
[conversation setObject:self.recipients forKey:@"recipientsIds"];
[conversation setObject:@"" forKey:@"messageIds"];
[conversation saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
NSLog(@"Failed creating conversatin in bkgd");
}else{
self.conversationId = [conversation objectId];
}
}];
}else{
PFQuery *messages = [PFQuery queryWithClassName:@"Messages"];
messages.cachePolicy = kPFCachePolicyCacheThenNetwork;
//sender id is the phone operator
//[messages whereKey:@"senderId" equalTo:[[PFUser currentUser] objectId]];
//receiver id is the other user in the chat
[messages whereKey:@"objectId" containedIn:[objects valueForKey:@"messageIds"]];
[messages orderByAscending:@"createdAt"];
[messages findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error){
NSLog(@"debug %@, %@", error, [error description]);
}else{
// messages found and passed thru the objects paramter.
self.messages = objects;
//NSLog(@"messages: %@", self.messages);
[self.tableView reloadData];
// scroll the table view
[self.tableView setContentOffset:CGPointMake(0, self.tableView.contentSize.height - self.tableView.frame.size.height)];
//NSLog(@"number %lu", (unsigned long)[self.messages count]);
}
}];
}
}
}];
这将查看是否与收件人ID进行了对话。在加载此视图之前,电话运营商ID将添加到收件人ID中。如果对话记录没有退出,则上面的代码会成功插入对话记录。
为了在用户输入消息后保存消息,我有以下代码:
//[self hideShowKeyboard];
PFObject *webMessage = [PFObject objectWithClassName:@"Messages"];
NSString *timeStamp = [NSDateFormatter localizedStringFromDate:[NSDate date]
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterShortStyle];
//PFObject *sender = [PFObject objectWithClassName:@"Sender"];
//[sender setObject:self.recipients forKey:@"recipientIds"];
//[sender setObject:[[PFUser currentUser] objectId] forKey:@"senderId"];
//[sender setObject:[[PFUser currentUser] username] forKey:@"senderName"];
//[webMessage setObject:file forKey:@"file"];
//[webMessage setObject:fileType forKey:@"fileType"];
//[webMessage setObject:self.recipients forKey:@"recipientIds"];
[webMessage setObject:[[PFUser currentUser] objectId] forKey:@"senderId"];
[webMessage setObject:[[PFUser currentUser] username] forKey:@"senderName"];
//[webMessage setObject:[PFUser currentUser] [@"phone"] forKey:@"senderPhoneNumber"];
[webMessage setObject:timeStamp forKey:@"timeStamp"];
[webMessage setObject:self.inputText.text forKey:@"messageContent"];
//[webMessage setObject:self.senderName forKey:@"receiverName"];
//[webMessage setObject:self.senderId forKey:@"receiverId"];
[webMessage setObject:@"text" forKey:@"messageType"];
//[webMessage setObject:@"jon" forKey:@"receiverName"];
//[webMessage setObject:@"1234" forKey:@"receiverId"];
//[webMessage setObject:@"true" forKey:@"me"];
// store recip. Ids like we do in camera view. then we will nest a query call to update
//the conversation class with message ID where recipIds equal to what we have...
//recipIds will be same coz its in one coversation between two or group of users...
PFObject *conversation = [PFObject objectWithClassName:@"Conversations"];
[conversation setObject:self.recipients forKey:@"recipientsIds"];
[conversation setObject:[[PFUser currentUser] username] forKey:@"senderName"];
[conversation setObject:[[PFUser currentUser] objectId] forKey:@"senderId"];
// [sender saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
// if (error) {
// // show error
// }
// // else save is good.
// }];
self.inputText.text = @"";
[webMessage saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"An error occured while uploading the file. Please try again." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}else{
// success!
// Create the PFQuery
PFQuery *query = [PFQuery queryWithClassName:@"Conversations"];
// Retrieve the conversation by id
[query getObjectInBackgroundWithId:self.conversationId block:^(PFObject *pfObject, NSError *error) {
// Now let's update it
[pfObject setObject:[webMessage objectId] forKey:@"messageIds"];
[pfObject saveInBackground];
}];
[self viewWillAppear:false];
}
}];
请忽略评论代码......我有一个不好的评论和尝试的习惯,但最终我会在一切都完成后清理这些代码。
问题是,这个过程在会话类中创建了3个条目...... 我认为这是因为我正在尝试使用消息ID在对话类中更新相同的记录,并且在数据库中,对话类有三个条目,其中一个有消息ID ...我附上了一张图片.. 我不知道为什么我不理解这件事......我确信它比我想的更简单......
另外,如何在收件箱视图中加载对话以显示发件人姓名?我开始编写一个流程,但它尚未完成......我需要首先正确地获取对话和消息内容......
你能指出我正确的方向吗?我认为对话的插入是不正确的...为什么recipientIds只包含[]而没有任何内容?我在创建segue之前设置了self.recipients ...现在我正在处理创建新的消息进程...收件箱视图应该包含发件人的名字,我不确定如何去做...感谢您的帮助。
EDIT ---------------------------------------------- ---------------------- 修复了会话类问题......结果收件人ID空了......
现在的问题是更新会话记录以添加新消息ID时它只更新最后一个...它是字符串类型列而不是数组类型...我该怎么办?更新过程位于上面的第二个代码块中。
OMG这个东西不让我发布图像,直到我有10个声望...... Sheesh。EDIT ---------------------------------------------- -----------------------
所以我修复了另一个问题,但是当我尝试更新对话记录时,我现在遇到了这段代码的问题:
[query getObjectInBackgroundWithId:self.conversationId block:^(PFObject *pfObject, NSError *error) {
if(error){
NSLog(@"Error occured while getting conversation object");
}else{
// Now let's update it with some new data.
[pfObject setObject:self.messageIds forKey:@"messageIds"];
[pfObject saveInBackground];
}
}];
一旦进入第一行,就会抛出此错误:
由于未捕获的异常终止应用' NSInvalidArgumentException',原因:'无法对类型进行比较查询:__ NSArrayI'
self.conversationId是字符串类型!!不是阵列......抱怨哪个阵列!!我不明白......
在我的.h: @property(非原子的,强大的)NSString * conversationId; @property(非原子,强)NSMutableArray * messageIds;
有什么想法吗?
EDIT ---------------------------------------------- -----------------------------
我试图更新会话记录以将新邮件添加到messageIds列...
[webMessage saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"An error occured while uploading the file. Please try again." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}else{
// success!
// Create the PFQuery
PFQuery *query = [PFQuery queryWithClassName:@"Conversations"];
// Retrieve the conversation by id
[query getObjectInBackgroundWithId:self.conversationId block:^(PFObject *pfObject, NSError *error) {
if(error){
NSLog(@"Error occured while getting conversation object");
}else{
// Now let's update it with some new data.
[pfObject setObject:self.messageIds forKey:@"messageIds"];
[pfObject saveInBackground];
}
}];
[self viewWillAppear:false];
}
}];
EDIT ---------------------------------------------- -------------------------------
因为我认为因为messageIds列是字符串类型而不是数组而删除了Conversations类。现在我收到了这个错误:
错误域=解析代码= 120"无法完成操作。 (解析错误120。)" UserInfo = 0x110023400 {error = cache miss,code = 120}
我不知道这有什么不对...... 我想要做的就是使用新的消息对象ID更新对话记录。 我在网上看到很多人都在这样做,但我不知道为什么我会收到这个错误...没有进行保存...是否有某种方法来更新Parse中的行?
答案 0 :(得分:1)
即使现在已经很老了,本教程也应该让你开始: http://attila.tumblr.com/post/21180235691/ios-tutorial-creating-a-chat-room-using-parse-com
我建议创建一个包含每个对话对象的对话类。此外,每个消息的消息类。会话类包含一个列,该列是一个数组,其中包含指向会话中每条消息的指针。通过这种方式,使用消息列上的includeKey以A SINGLE QUERY方式获取对话中的所有消息将非常快。
答案 1 :(得分:0)
M5er ...尝试一下然后评论它们真的不是一件坏事!我做同样的事情。它允许我看到什么不起作用,并防止进入圈子。以后清理很容易......一遍又一遍地做同样的事情因为你不记得你做了什么......这会导致一些疯狂!