I am building a social app that has a chatView. Message is an entity. On the usersViewController (rootViewController), I want to just display the number of unread messages from each user. But on the chatView, I want to show the messages sent between me and the selected user.
How should I fetch the messages from Core Data?
Is there a way to fetch them all into an NSMutableDictionary 开发者_C百科with userIds as keys, each pointing to an NSMutableArray of Message entities? Or, would I have to fetch all the Messages and then iterate through them with Objective-C to arrange them as described?
Either way, should I load them all upfront in the appDelegate? Or, should I only load the messages for the specific conversation upon viewing the corresponding chatView?
To get the unread counts, should I iterate through the fetched Message entities to make an NSMutableDictionary of userID keys pointing to count values? Or, should I make a predicate that acts like a SQL sum query grouped by userId (Is that even possible with Core Data?)?
Should I create a model, call it
UnreadMessageCount
, that stores the number of unread messages that I have from each user and a reference to theUser
model? I want to have all the unread messages on the first page of the app, so this would make that query faster. But receiving messages would be slower because I would not only have to add it to the Message model but also I would have to increment the count for that user in the UnreadMessageCount model. Also, the data would sort of be duplicated. Also, I'll only make the query for all message counts once per application launch, but i'll make queries to update the unread message count every time I receive a new message and am not on the chatView page with that user.
Please fill me in on iPhone memory management & Core Data possibilites and performance. And also please give your opinion on the best way to engineer this.
Thanks!
Matt
To get the message count, I would ask the managed object context for the count of messages given a certain fetch request, for example, to count the messages for a certain user:
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Message" inManagedObjectContext:context];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"user == %@", user];
[request setPredicate:predicate];
NSInteger count = [context countForFetchRequest:request error:nil];
Here I'm assuming that the Message
entity has a user
relationship.
To get the actual messages for that same user, I would just replace the last line for:
NSArray *messages = [context executeFetchRequest:request error:nil];
iPhone generally does a great job managing resources when you use CoreData (especially simple structures as in your example). So to answer your questions, this is what I think you should do:
- You will need fetch all users, then iterate through them and create dictionary keys that will point at
messages
property of each of theuser
entities - You shouldn't, use
NSFetchedResultsController
instead, it efficiently loads entities that are requested and does all the required prefetching for optimized display in table views - the answer above is probably the way to go when it comes to counts. Creating proper indices on your entities will make it lightning fast.
精彩评论