CloudKit : How to handle account changes with local persistent store? - ios

In my application i have to maintain a local persistent store in sync with cloud kit private database. So I just wanted to know how can I handle account changes that may happen.
Confusion I have is as below:
say a set of records belong to user A now if user B log's in to the same phone I can do the following of the 2 things:
Ignore user and let data sync to B account too but that way A's data will get sync to B's private account too. Here the record change tag and all get a bit mess up since am saving CKRecord encoded fields to database.
I can maintain a user table and link each record to the user that is logged in that way user data will get separated. So should I maintain a user field along with all records ?
How can this be best handled even apart from above 2 things.

Of course in your local persistence store you could add the userID to personalize all records. An other mechanism is to remove all local data and fetch the users data when a change is detected. If you want to keep the users data on the device you could also create separate data stores for each user.
You can detect a changed login by adding the following code in your app delegate or root view controller:
NSNotificationCenter.defaultCenter().addObserverForName(NSUbiquityIdentityDidChangeNotification, object: nil, queue: nil) { _ in
/// remove local data and fetch user data
}
You should also refresh all user related data in memory and refresh the loaded views.

Related

Unable to detect a Delete on the server from the client

In my database, I have three entities: User, List and UserList (represents a many to many relationship between user and List). In my app, I have initialized SyncContext with StoreTrackingOptions.NotifyLocalAndServerOperations tracking option.
await Client.SyncContext.InitializeAsync(_store, StoreTrackingOptions.NotifyLocalAndServerOperations);
When my app is running for a given User, when I add a new List association for that user (by inserting a linkage record into UserList), I am able to detect this change:
var subscription = Client.EventManager.Subscribe<StoreOperationCompletedEvent>(async (storeEvent) => await StoreChangedEventHandler(storeEvent));
protected async Task StoreChangedEventHandler(StoreOperationCompletedEvent storeEvent) {..}
Now note that creating the linkage, will pull the UserList record for the User as well as the List record referenced by UserList.
When I delete this linkage record though, there is no notification of that coming to my client.
Questions: Is such notification (of deleted records) possible? If so, how do I make it happen?
I have solved this issue by enabling soft delete on the server (Azure Mobile Server SDK). By doing that, all soft-deleted records are pulled back to the client and I can filter them out for presentation. Works for me but may not work for everyone else.

How to store my data using at the end of my step in MVC?

I have a form using a Table of REQUEST Using IDRequest (int), TitleOfRequest
and other Table events which can have multiple events for the same request.
So the Table of events will include :
IDEVENTST,
IDRequest,
IDTypeofEvent,
DateStstrong textart,
DateEnd
Table of TYPEOfEvent : IdTypeOfEvent,TitleOfType
From my view to create a new record, the record will create at the final step, i want to make it in order
1 ) Enter a form with fields TitleOfRequest
And fields where the person can enter : DateStart and DateEnd, TypeOfEvent and a button to add, and load the temporary records in datatable.
My questions is : what is the best way to store this temporary data with MVC ? And refresh it in my view then at least to save in my database.
You could use [TempData] if you want to store data for the next request only.TempData allow us to persisting data for the duration of single subsequent request.
If data should be accessible between multiple requests, then use Session.
[Session] is able to store data much more long time, until user session is not expire.
Here is a good blogpost on this matter:
http://petermcintyre.com/2013/01/27/asp-net-mvc-data-persistence-choices/

Reflux store and actions flow logic: how to pass data from a store to another store

Is it Ok for a store to create an action to another store?
My data in store A always changing frequently, and i want to pass the data in store A to store B every time that my data in store A gets an update.
So I've made a listener in store A, on data change that's calling an handle function which "fire" an Action dataChange(this.data) (in store A) with the current data and store B gets the new data by onDataChange(data) every time the my data changed in store A.
So it's working, but i want to know if this is how i supposed to work with the data flow or there is more elegant way to do it.
In the Reflux philosophy, stores listening to other stores is an acceptable and supported pattern, just use the listenTo method in store B and listen to store A.

How to allow only one user to edit a Parse object?

I'm creating an app that allows co-workers to upload shifts (objects) to Parse that they need covered. I save all the shifts to a "Shifts" class (in the data browser). I want to restrict the ALC so that only the person who uploaded the shift/object can edit it (everyone can "read" it). Is there a way that I can create/upload that programmatically (rather than having to go into the Data Browser and add it manually)?
You can create a relationship between your Shifts and your existing _User table. If you add a shift, you can create a relationship to the _User table. Than, if you retrieve the info, you can check if the user who reads the record is also the one who created it by comparing the active PFUser.currentUser with the user from your shift.
//Initial safe
var user = PFUser.currentUser
var relation = user.relationForKey("shifts")
relation.addObject(yourShiftObject)
user.saveInBackground()
You can set the ACL on objects when you create them. The best would be to define a default ACL that allows the creating user to read and write the object while still allowing public read access.
Example taken from the documentation
var defaultACL = PFACL.ACL()
// Optionally enable public read access while disabling public write access.
defaultACL.setPublicReadAccess(true)
PFACL.setDefaultACL(defaultACL, withAccessForCurrentUser:true)
https://www.parse.com/docs/ios_guide#security-recommendations/iOS

How can I store user information in MVC between requests

I have an MVC2-site using Windows authentication.
When the user requests a page I pull some user information from the database. The class I retrieve is a Person class.
How can get this from the database when the user enters the site, and pick up the same class without touching the db on all subsequent page requests?
I must admit, I am pretty lost when it comes to session handling in ASP.net MVC.
You can store that kind of information in HttpContextBase.Session.
One option is to retrieve the Person object from your database on the first hit and store it in System.Web.HttpContext.Current.Cache, this will allow extremely fast access and your Person data will be temporarily stored in RAM on the web server.
But be careful: If you are storing significantly large amount of user data in this way, you could eat up a lot of memory. Nevertheless, this will be perfectly fine if you only need to cache a few thousand or so. Clearly, it depends upon how many users you expect to be using your app.
You could add like this:
private void CachePersonData (Person data, string storageKey)
{
if (HttpContext.Current.Cache[storageKey] == null)
{
HttpContext.Current.Cache.Add(storageKey,
data,
null,
Cache.NoAbsoluteExpiration,
TimeSpan.FromDays(1),
CacheItemPriority.High,
null);
}
}
... and retrieve like this:
// Grab data from the cache
Person p = HttpContext.Current.Cache[storageKey];
Don't forget that the object returned from the cache could be null, so you should check for this and load from the database as necessary (then cache).
First of all, if you are using a load balanced environment, I wouldn't recommend any solution that you try without storing it in a database, because it will eventually fail.
If you are not in a load balancing environment, you can use TempData to store your object and then retrieve it in the subsequent request.
HttpContext.Current.Session[key];

Resources