Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add new attribute to existing Core Data Entity Relationship

I'm not sure if my understanding of Core Data relationships is flawed as I can't seem to achieve what I want to do.

I have a 2 entities created to manage Chat on the app and a one-to-Many relationship between the users and the messages. So a user can have many messages but the messages have just you user (creator).

enter image description here

I am trying to update the ChatUser entity relationship when a new message is added whereby a connection between the ChatUser ID and the ChatMessage is established. I can do this but the issue arises when I go to add a new message to an existing userId. All that is currently being achieved though is adding an extra userId into ChatUser instead of adding only the relationship to the existing 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]);
}
like image 463
memyselfandmyiphone Avatar asked Apr 11 '15 23:04

memyselfandmyiphone


People also ask

How do I add fetch index elements in Core Data?

You'll see a small + button under Fetch Index Elements in the main editor – click that to add a new index element, then change its property from “Expression” to “name”. An indexed attribute is one that is optimized for fast searching.

What is Nsmanagedobjectcontext in Core Data?

An object space to manipulate and track changes to managed objects.


1 Answers

Core Data will automatically manage the other end of the relationship once you initiate it from either direction. You can either add to ChatUser's chat collection or set ChatMessage's chat with an instance of an NSManagedObject and that's all you have to do. Note that this process does not require you to manage foreign keys, that complexity is abstracted from you. You can still store server-side IDs if they help you interact with an API, but they are not required for Core Data.

I would recommend changing one end of the relationship so that both are not named the same thing. Consider updating ChatUser's relationship to be messages or something similar.

like image 171
jszumski Avatar answered Oct 20 '22 05:10

jszumski