Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with a multiple-user database

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.

like image 762
Eyal Avatar asked May 02 '12 15:05

Eyal


People also ask

Can multiple users use database at the same time?

Share a single database In this method, the database file is stored on a shared network drive, and all users share the database file simultaneously. Some limitations include reliability and availability if there are multiple simultaneous users changing data since all database objects are shared.

How do you handle multiple users changing the same data?

This is usually done by letting the user know that this has happened and asking them to either reload the form and let them alter it again or to just go ahead and overwrite with your values. The secret is in the WHERE clause.

Why do we need multiple users in a database?

Multiple users can read and modify the data at the same time. Databases are searchable and sortable, so the data you need can be found quick and easily. The data structure is extendable and can be modified as requirements change.


1 Answers

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.

like image 179
jrturton Avatar answered Sep 22 '22 06:09

jrturton