解析关系的麻烦

时间:2014-07-17 08:14:13

标签: ios parse-platform

// Posts a message to the backend database
- (void)postMessage:(NSString *)message
{
    // return right away if message is nil or all whitespace
    if (!message || ![[message stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]) {
    return;
    }


    // Create new Message object and set relationships
    PFObject *postedMessage = [PFObject objectWithClassName:@"Message"];
    postedMessage[@"text"] = message;

    PFRelation *tagRelation = [postedMessage relationForKey:@"tags"];

    NSMutableArray *tags = [self generateTagsFromMessage:message];
    NSLog(@"Number of Tags Found: %lu", (unsigned long)[tags count]);

    [PFObject saveAllInBackground:tags block:^(BOOL succeeded, NSError *error) {
        for (PFObject *tag in tags) {
      //      [tagRelation addObject:tag];
            NSLog(@"%@", tag[@"text"]);
            [tag setObject:postedMessage forKey:@"message"];
        }
    }];

    [postedMessage saveInBackground]
}

我使用Parse作为我的应用程序的后端,但是在创建一对多关系时遇到了莫名其妙的困难。

我们的想法是让用户可以使用标签将消息发布到数据库,数据库将Messages存储为一个类,将Tags存储为另一个类。 Message类有一个"标签"用于存储消息中所有标记的字段,Tag类具有"消息"用于存储标记的父消息的字段。我以为我遵循了如何在Parse中创建一对多关系的教程,但无论我在Parse中看不到数据浏览器上的关系。

我尝试通过简单地将postingMessage设置为newTag的消息字段,并通过为消息的tags字段创建PFRelation *并为其添加标签来尝试获得工作关系。它都不起作用。

有人知道我的问题可能是什么吗?

谢谢!

修改

具体地说,问题是对象之间没有形成关系。通过检查数据浏览器,我可以看到"标签"消息的关系字段和"消息"运行此代码后,Tag的关系字段保持空白。

3 个答案:

答案 0 :(得分:4)

上述代码存在的问题是,您要同时创建两个新对象并同时触发后台保存。

要使其工作,您需要先保存关系的一面,然后创建新对象,关联它们并保存它们(在块中)。

在你的情况下你有一个来自多个标签的消息,所以创建消息并保存它,然后在保存块中创建标签,将它们添加到消息中并重新保存消息(它将走在树上寻找变化并保存新标签。)

// Create new Message object
PFObject *postedMessage = [PFObject objectWithClassName:@"Message"];
postedMessage[@"text"] = message;

[postedMessage saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
    // message saved, now create tags with link to message
    PFRelation *tagRelation = [postedMessage relationForKey:@"tags"];

    NSMutableArray *tags = [self generateTagsFromMessage:message];
    NSLog(@"Number of Tags Found: %lu", (unsigned long)[tags count]);
    for (PFObject *tag in tags) {
        NSLog(@"%@", tag[@"text"]);
        [tag setObject:postedMessage forKey:@"message"];
    }

    // now save the tags
    [PFObject saveAllInBackground:tags block:^(BOOL succeeded, NSError *error) {
        // now add the relationships
        for (PFObject *tag in tags) {
            [tagRelation addObject:tag];
        }
        // and save
        [postedMessage saveInBackground];
    }];
}];

答案 1 :(得分:1)

您的代码几乎是正确的,但您错过了一些细节。请参阅下面重写的代码的工作版本。但首先,请阅读Parse中的示例。

Parse iOS documentation看看这个例子,他们在两个对象之间设置指针关系;一对一的关系。

  

在创建关系之前,两个对象都不能有objectId。

// Create the post
PFObject *myPost = [PFObject objectWithClassName:@"Post"];
myPost[@"title"] = @"I'm Hungry";
myPost[@"content"] = @"Where should we go for lunch?";

// Create the comment
PFObject *myComment = [PFObject objectWithClassName:@"Comment"];
myComment[@"content"] = @"Let's do Sushirrito.";

// Add a relation between the Post and Comment
myComment[@"parent"] = myPost;

// This will save both myPost and myComment
[myComment saveInBackground];

您正在寻找的是一对多关系指针数组,其中列出了here并在下面复制以便于参考。

  

在创建关系之前,一个对象必须具有objectId

// Create Post
PFObject *newPost = [PFObject objectWithClassName:@"Post"]; 

// Set text content
[newPost setObject:[textView text] forKey:@"textContent"];  

// Create relationship
[newPost setObject:[PFUser currentUser] forKey:@"author"];  

// Save the new post
[newPost saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
    if (!error) {
       // Dismiss the NewPostViewController and show the BlogTableViewController
       [self dismissModalViewControllerAnimated:YES];
    }
}];

或者您正在寻找使用PFRelation对象的一对多关系,因为; "您不需要立即下载关系中的所有对象。这允许PFRelation扩展到比PFObject方法的NSArray更多的对象。 。如果您正在寻找这种方法,那么您重新编写的代码将起作用。

  

创建关系之前,objectId上必须有一个对象

// Create new Message object and set relationships
PFObject *postedMessage = [PFObject objectWithClassName:@"TestClass"];
postedMessage[@"text"] = @"Hello World";

//example tags into array
PFObject *tag1 = [PFObject objectWithClassName:@"Tag"];
PFObject *tag2 = [PFObject objectWithClassName:@"Tag"];
PFObject *tag3 = [PFObject objectWithClassName:@"Tag"];
PFObject *tag4 = [PFObject objectWithClassName:@"Tag"];
NSArray *tags = [NSArray arrayWithObjects:tag1, tag2, tag3, tag4, nil];

//iterate the tags, add pointer for each
for (PFObject *tag in tags) {

    //create a new tag-to-message pointer
    [tag setObject:postedMessage forKey:@"message"];
}

//save all the tags and save the postedMessage
[PFObject saveAllInBackground:tags block:^(BOOL succeeded, NSError *error) {

    if (!error) {
        NSLog(@"created new postedMessage w/o relations :%@", postedMessage);
        NSLog(@"saved tags with pointers :%@", tags);

        PFRelation *tagRelation = [postedMessage relationForKey:@"tags"];

        //iterate the tags, add relation for each
        for (PFObject *tag in tags) {

            //create a new postedMessage-to-tag relationship
            [tagRelation addObject:tag];
        }
        //update the postedMessage
        [postedMessage saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {

            if (!error) {
                NSLog(@"updated postedMessage with relations :%@", postedMessage);
            }
        }];

    }

}];

编辑:添加我写的代码;这可以像你期望的那样工作。一旦你的人际关系发挥作用,你将会遇到一件使用浏览器的事情,那就是找不到的对象"从非直接相关的对象单击对象关系时出错。更好的解释方法是引用您下面的示例。

我创建了一条消息通知与用户之间的关系 - 从您喜欢的任何方向考虑它。当我使用CoreData中的浏览器访问此关系数据并单击“用户通知关系”列时,我将转到用户通知。然而;当我点击任何消息关系列时,我收到了"未找到的对象"错误信息。这是预期的行为,从逻辑上说它是有道理的。用户对象并不关心其通知包含哪些消息,就像消息如何关心用户是谁一样。当User对象在通知上调用delete时,自动清理将删除消息,而User对象无需担心它们。当一个对象没有引用指针并调用自动清理时,该对象将被删除。

- (void)addNotificationWithData:(NSDictionary*)userInfo withCompletionHandler:(void(^)(BOOL isFinished))completionHandler {

    PFObject *notification = [PFObject objectWithClassName:@"Notification"];

    PFObject *msg = [PFObject objectWithClassName:@"Message"];

    [msg saveEventually:^(BOOL succeeded, NSError *error) {

        if (!error) {
            PFRelation *notification_to_message = [notification relationForKey:@"messages"];
            [notification_to_message addObject:msg];

            [notification saveEventually:^(BOOL succeeded, NSError *error) {

                if (!error) {

                    PFRelation *user_to_notification = [[PFUser currentUser]relationForKey:@"notifications"];
                    [user_to_notification addObject:notification];

                    [[PFUser currentUser]saveEventually:^(BOOL succeeded, NSError *error) {

                        if (!error) {
                            //add the notication to the notification(s)
                            [notifications addObject:notification];

                            NSLog(@"the current notifications are :%@", notifications);
                            //call the completion handler
                            if (completionHandler) {
                                completionHandler(YES);
                            }
                        }
                    }];
                }
            }];    
        }
    }];
}

答案 2 :(得分:0)

您已注释掉addObject调用以将对象添加到关系中。您需要取消注释该行才能将对象实际添加到关系中。