// 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的关系字段保持空白。
答案 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
调用以将对象添加到关系中。您需要取消注释该行才能将对象实际添加到关系中。