将新属性添加到现有核心数据实体关系

mem*_*one 15 core-data objective-c nsfetchedresultscontroller nsmanagedobject ios

我不确定我对核心数据关系的理解是否有缺陷,因为我似乎无法实现我想要做的事情.

我创建了2个实体来管理应用程序上的聊天,以及用户和消息之间的一对多关系.因此,用户可以拥有许多消息,但消息只有您的用户(创建者).

在此输入图像描述

我正在尝试在ChatUser添加新消息时更新实体关系,从而建立ChatUserID和ID 之间的连接ChatMessage.我可以这样做,但是当我向现有消息添加新消息时会出现问题userId.当前正在尽管做到的就是增加一个额外的userId进入ChatUser,而不是只添加到现有的关系UserId.

NSManagedObjectContext *context = [self managedObjectContext];
NSError *error = nil;

// 4 . Get Timestamp for Rippll
float timestamp = @([[NSDate date] timeIntervalSince1970]).floatValue;
 NSString * jayID = @"eu-west-1:be6457ce-bac1-412d-9307-e375e52e22ff";

  NSString *message = @"Science string!";

// Create a new managed object
ChatUser *chatUserManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"ChatUser" inManagedObjectContext:context];
Chat *chatManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"ChatMessage" inManagedObjectContext:context];
Timeline *timelineManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"Timeline" inManagedObjectContext:context];

// 3 . Save Timeline
[timelineManagedObject setEvent:chatEvent];
[timelineManagedObject setTimestamp:[NSNumber numberWithFloat:timestamp]];
[timelineManagedObject setMeta:@""];
[timelineManagedObject setViewed:@NO];
[timelineManagedObject setEventID:jayID];

//Save UserMessage
[chatManagedObject setChatId:jayID];
[chatManagedObject setTimestamp:[NSNumber numberWithFloat:timestamp]];
[chatManagedObject setMessage:message];
[chatManagedObject setMedia:@""];

//Check if value exists
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"ChatUser"];
[request setPredicate:[NSPredicate predicateWithFormat:@"userId = %@", jayID]];
[request setFetchLimit:1];

NSArray *entities = [[context executeFetchRequest:request error:&error] mutableCopy];

if (entities.count == 0) {

    NSLog(@"GOOD TO ADD");
        // no matching object

    [chatUserManagedObject setUserId:jayID];

    //Create Relationship
    [chatUserManagedObject addChatObject:chatManagedObject];

} else {

    NSLog(@"IT EXISTS!");

    [chatManagedObject setChat:chatUserManagedObject];

}

// Save the object to persistent store
if (![context save:&error]) {
    NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
}
Run Code Online (Sandbox Code Playgroud)

jsz*_*ski 6

一旦从任一方向启动,Core Data将自动管理关系的另一端.您可以添加到ChatUserchat集合或设置ChatMessagechat使用的一个实例NSManagedObject,这一切,你必须做的.请注意,此过程不需要您管理外键,从而提取复杂性.如果它们可以帮助您与API进行交互,您仍然可以存储服务器端ID,但Core Data不需要它们.

我建议改变关系的一端,这样两者都不会被命名为同一个东西.考虑更新ChatUser的关系是messages或类似的.


Ami*_*wad 3

我认为@PangHoMing 是在正确的轨道上,但使用了Magical Records。让我们只用 CD​​ 来做:

\n\n

首先重命名关系。可能应该有一个名为(或)ChatMessage的 to-1 关系,并且应该有一个名为(或) 的 to-N 关系。它们应该是反比关系。userchatUserChatUsermessageschatMessages

\n\n

接下来,您应该在创建用户之前询问该用户是否存在。(否则您将创建虚拟用户。)您获得了它的代码:

\n\n
// Create message as you did\nChatMessage *message = \xe2\x80\xa6;\n\xe2\x80\xa6\n\n// The user will go here\nChatUser *user; // Do not use types in names unless conversion is subject of your code\n\n// Look for an existing one\nNSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"ChatUser"];\n[request setPredicate:[NSPredicate predicateWithFormat:@"userId = %@", jayID]];\n[request setFetchLimit:1];\n\nNSArray *entities = [[context executeFetchRequest:request error:&error] mutableCopy];\n\nif (entities.count == 0) \n{\n  // Only if there is none, create one  \n  user = [NSEntityDescription insertNewObjectForEntityForName:@"ChatUser" inManagedObjectContext:context];\n  // Set-up user\'s properties\n  \xe2\x80\xa6\n} \nelse \n{\n  // Use the existing one\n  user = entities[0];\n}\n\n[message setValue:user forKey:@"user"]; // message.user = user;\n
Run Code Online (Sandbox Code Playgroud)\n\n

正如其他人提到的,逆关系是由 CD 维持的。但是,如果这对您来说更具可读性,您可以使用逆关系来添加消息:

\n\n
[[user mutableSetValueForKey:@"messages"] addObject:message]; // [user addMessagesObject:message]\n
Run Code Online (Sandbox Code Playgroud)\n\n

这也将维持“原始”关系。

\n