iOS和Parse.com后端

时间:2014-06-26 03:53:33

标签: ios iphone parse-platform

您如何使用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中的行?

2 个答案:

答案 0 :(得分:1)

即使现在已经很老了,本教程也应该让你开始: http://attila.tumblr.com/post/21180235691/ios-tutorial-creating-a-chat-room-using-parse-com

我建议创建一个包含每个对话对象的对话类。此外,每个消息的消息类。会话类包含一个列,该列是一个数组,其中包含指向会话中每条消息的指针。通过这种方式,使用消息列上的includeKey以A SINGLE QUERY方式获取对话中的所有消息将非常快。

答案 1 :(得分:0)

M5er ...尝试一下然后评论它们真的不是一件坏事!我做同样的事情。它允许我看到什么不起作用,并防止进入圈子。以后清理很容易......一遍又一遍地做同样的事情因为你不记得你做了什么......这会导致一些疯狂!