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

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.

Related

Why does storing a reference to an NSManagedObject prevent it from updating?

This question is poorly phased but this can be better explained in code.
We have a Core Data Stack with private and main contexts as defined by Marcus Zarra here: http://martiancraft.com/blog/2015/03/core-data-stack/
We call a separate class to do a fetch request (main context) and return an array of NSManagedObjects:
NSArray *ourManagedObjects = [[Client sharedClient].coreDataManager fetchArrayForClass:[OurObject class] sortKey:#"name" ascending:YES];
We then do some processing and store a reference:
self.ourObjects = processedManagedObjects
Our view contains a UITableView and this data is used to populate it and that works just fine.
We change the data on our CMS, pull to refresh on the UITableView to trigger a sync (private context) and then call this same function to retrieve the updated data. However, the fetch request returns the exact same data as before even though when I check the sqlite db directly it contains the new data. To get the new values to display I have to reload the app.
I have discovered that if I don't assign the processedManagedObjects to self, the fetch request does indeed return the correct data, so it looks like holding a reference to the NSManagedObject stops it from getting new data from the main context. However I have no idea why that would be.
To clarify, we're pretty sure there's nothing wrong with our Core Data Stack, even when these managed objects are not being updated, other are being updated just fine, it's only this one where we store a local reference.
It sounds like what's going on is:
Managed objects don't automatically update themselves to reflect the latest data in the persistent store when changes are made via a different managed object context.
As a result, if you keep a reference to the objects, they keep whatever data they already had.
On the other hand if you don't keep a reference but instead re-fetch them, you get the new data because there was no managed object hanging around with its old data.
You have a few options:
You could keep the reference and have your context refresh the managed objects, using either the refresh(_, mergeChanges:) method or refreshAllObjects().
If it makes sense for your app, use an NSFetchedResultsController and use its delegate methods to be notified of changes.
Don't keep the reference.
The first is probably best-- refreshAllObjects() is probably what you want. Other options might be better based on other details of your app.
Try setting the shouldRefreshRefetchedObjects property of the fetch request to true. According to the documentation:
By default when you fetch objects, they maintain their current property values, even if the values in the persistent store have changed. Invoking this method with the parameter true means that when the fetch is executed, the property values of fetched objects are updated with the current values in the persistent store.

What are ways to store complex dynamic objects locally (iOS, swift)?

I have iOS app that takes data from the server as json and then serializes them into objects of different types. Types can be complicated, can contain subtypes, can inherit, so there is no any limitations. Another thing that makes everything even more complicated is some of types are stored as AnyObject? and only in run time they are being serialized into real types accordingly to the specific rules. Something like that:
class A {
var typeName: String?
var b: AnyObject?
}
Then when it's serialized it can be done something like that:
if let someClass = NSClassFromString(typeName) as? SomeGenericType.Type{
b = someClass.init()
}
Also querying should be done on all the data. Currently I'm trying to store all of them locally, then load into memory and query there from the code. I'm using User defaults, but they have some limitations, also I needed to provide custom coding to make it work, and each time when I add a new field it turned out that I missed something in coding and nothing works. So it's pain.
Ideally I would just do some magic command and all the objects are sent to local storage no matter how complicated they are. The same to extract them from this storage. Also, user change data so I can't just store primary Json. And I don't want to covert objects back to Jason as for it's pain too.
Any suggestions?
If you want to use sqlite then You can store whole object in one row! I means you can create table with 2 columns one is id and second is your dataobject(it's data type should be blob). Then convert your whole object into data. Then store in sqlite table and retrieve it as data then convert it to object when want to use. By this way your object will remains in same format as you asked
Firebase while meant for online synching and storage can also cache everything locally in case you are offline and perform query's against the local cache. It uses JSON.
CouchDB also has a mobile version for iOS.
Both of those are over kill if your dataset is small; you can just store it as a text file and read the JSON back in. See performance characteristics here. The graph is for a 7MB file so if you are significantly less than that your load time may be minimal.
NSKeyedArchiver.archivedData(withRootObject:) is great for storing custom objects as Data objects. The only thing you need to do to be able to use this is to make your custom objects conform to NSCoding. A great example can be found here:
Save custom objects into NSUserDefaults
Once you have the Data version of the object, it can easily be stored in UserDefaults, as a property in CoreData, or even in the app's keychain entries. Depending on your use case, sensitivity of data, and how much data you intend to store, you might want to use any number of storage methods. NSKeyedArchiver.archivedData(withRootObject:) allows you to pretty much use any of them.

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

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.

What is the best way to save data online from UITableView?

My application
UITableView has 200 rows
In edit mode each cell has two actions for eg: passAction and failAction
After editing i want to update the database with either 0 or 1 based on its selection
I am retrieving data from server as json and storing it as object
Which is Best?
a. Requesting the server on each time the action is called.
b. Storing it in the local database and sync on completing all rows.
c. Request the server once on completion and send the whole object as JSON.
Help me in choosing the best option of implementation I can do!
Correct me if I bypassed any rules of SO because this is my first question!
#Dan Beaulieu: No need to send all data to server after edit. First update your database and Just send data which was changed in your database.
So add one field like "sync" in your database table and updated field set sync = 1 during edit and get data from database which was set sync = 1 and send it to server.

Extract specific update from NSPersistentStoreCoordinator

I'm currently using iCloud and CoreData to sync data across my app, so every time notification fires, I update my local array of data. The problem I am running into is that my data set is getting large and I don't want to update the entire set of data every time there is a new notification.
Basically, I have an Entity called Photo, and every time the user makes an update to one Photo object on device A, it gets synced with iCloud, which then gets pushed to device B. The device receives the notification through:
persistentStoreDidImportUbiquitousContentChanges:
which looks like this:
notification.userInfo.description:
{
deleted = "{(\n)}";
inserted = "{(\n 0x17045c80 56E70CB19352/Photo/p8431>\n)}";
updated = "{(\n)}";
}
I'd like to grab that specific insertion, update, or deletion and apply it to my local array instead of iterating through the entire set of fetchedObjects.
I tried casting the insertion object to a Photo object, but that didn't work. Any thoughts on how to extract that info?
Thanks!
The objects in that notification are instances of NSManagedObjectID. You can use those with your NSManagedObjectContext to retrieve the managed objects. Use existingObjectWithID:error: (safe, potentially slow) or objectWithID: (fast, potentially less safe).
You probably don't need to do that, though. You can take that notification and pass it to mergeChangesFromContextDidSaveNotification: to merge any changes it contains. If you need to do manual merging, you can, but it's usually not needed.

Resources