Question

My app is like a lot of apps -- it has a login screen where the user enters a username and password, and a login button My app also uses Core Data to save most of the user's business objects, that of course are user-specific.

I also have a sign out button to enable switching users. This does not happen a lot, but it's still necessary).

Now if a different user logs in, I need to fetch his specific data. But how do I do it?
I don't want to delete a user's database when he signs out, I want to save it even if other users log in from the device.

The only thing I can think about is to add an "ownerId" attribute to every Entity I save via Core Data, and use this attribute as a predicate when I fetch objects.
But that just seems too messy.

Was it helpful?

Solution

iOS doesn't really have a concept of multiple users so the "login" would be limited in scope to your app. The simplest solution would be to use a different filename for the persistent store for each user. This is only derived in one place (wherever you set up your core data stack) so it would be pretty straightforward to implement.

In the standard core data template, the persistent store location is set inside the persistentStoreCoordinator method of the application delegate. It is this line:

 NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"coreDataTemplate.sqlite"];

This basically means that the data will be stored in a sqlite database file in the documents directory, and the file will be called coreDataTemplate.sqlite.

Assuming that before this code is executed point you have made the user log on, and checked their user ID against some list and come up with a unique identifier for them. Further assume the identifier has been stored in user defaults.

Change the line above to:

NSString *userIdentifier = [[NSUserDefaults standardUserDefaults] stringForKey:@"loggedOnUserID"];     
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:[NSString stringWithFormat:@"%@_coreDataTemplate.sqlite",userIdentifier]];

This will now give you a unique file name for your user.

If you change users, then you will need to save the current managed object context, then set the persistent store coordinator and the managed object context of the app delegate back to nil. When they are re-accesed, it will be under the new user ID.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top