I'm working on a cocoa app for syncing data between two folders.
It have profiles (so you can have multiple setups)
It's possible to analyze data
It's possible to sync the data
Im a little confused. First of all i cant really see where to have a model? And how many controller would you suggest? 1 WindowController or AnalyzeController, SyncController etc.
Its quite a while since i have worked with MVC. I've read some articles but i'm missing concrete examples on how to divide it.
Best regards.
The data model handles the data and the abstract relationships between different pieces of the data. The controllers handle the concrete operations of a computer or human interface.
The key division is that the data model doesn't know where the data comes from and doesn't care. For example, it could model a folder and its contents but the actual information in the model could come from a real folder on a disk or it could come from completely made up plist file or it could come from a simulated UI of a folder. The data model doesn't care because it has no direct connection with concrete reality. It just holds an abstract description of the data.
The controllers by contrast are tied to a specific concrete interface. For example, if you have two folders, you would have specific controllers for each folder. Each controller would have concrete knowledge of the real world pathway to the folder as well as the mechanism for reading and writing to the folders. So, if one folder is on the local hard drive and another is remote, each controller would understand the difference. If you have a UI, then the UI would have its own controller.
The controllers job is to translate from the concrete reality to the abstract model. In this case, the controller would handle connecting to a remote server, scanning the folder and then converting that information to an abstract form it would hand off to the data model. However, the controller doesn't save an data and doesn't understand how the pieces of data relate to each other.
In the case of a syncing app, it would be the job of the data model to understand what files where in which folder and what files needed to be copied or updated and to where. It would then tell each controller which files to manipulate. However, the controller wouldn't know why each file was being manipulated.
The design goal is to create a data model that would model the folders and files regardless of where they reside, how they are concretely manipulated or even whether they actually exist at all. That way, you can easily add or remove interfaces just by adding or removing a controller. The controllers themselves are simple because they hold no data and no data manipulation logic.
Related
I'm working on a Vue app with Vuex state management using Type Script. I'm wondering where I should place my model classes. Currently I have them under "store" in a sub-directory "models". Now I have many more custom types used by the models and I'm not sure anymore whether the "store" directory is the right place. But on the other hand, the models are in a tight relationship with the state, right?
What is best-practice for this?
Short answer: put the "models" folder next to your "store" folder, not inside.
Long answer:
There are generally two strategies for organizing files:
Grouping by utility (eg. models, services, components etc.)
Grouping by domain category (eg. users, products, bookings etc.)
Whatever you choose there's a tradeoff.
The first strategy is most common. It prevents your project from getting many folders in your root folder, and it makes it easy to decide where to put new files. The drawback is that closely related files end up far apart, and as your codebase grows you will spend time looking for files that depend on each other.
The second keeps related files nicely together. Imagine for example a folder called Pets that contains a pet model, a pet component, a pet service and a unit test for that service. That makes navigating through Pet logic a lot easier. However, directories follow a tree structure while the domain model looks more like a graph and that can cause difficulties for properly organizing your files.
I find that people most often organize code by utility first, and by domain category second, but I'm not sure if I would call it best practice. The other way around has often worked out nicely for me as well.
If you organize by utility then you should avoid nesting them because it's almost never the case that one kind of utility uniquely belongs to another. Certainly models don't uniquely belong to a store. A component that depends on a model is just as tightly coupled to that model as a store. Therefore placing the "models" folder next to the "store" folder would make more sense.
It's more of a software design question, than strictly programming, so I'll paste UML diagrams instead of code for everyone's convenience.
Language is Java, so variables are implied references.
I'm writing an app, that helps edit a very simple data structure, that looks like this:
On my first trial run I've included all the drawing-related and optimization code into the data structure, that is, every Node knew how to draw itself and kept a reference to one of shared cached bitmaps. UML:
It was easy to add (fetch a corresponding bitmap and you're done) and remove (paint background color over previously mentioned bitmap). Performance-wise it was nice, but code-wise it was messy.
So on the next iteration I decided to split things, but I may have went to far and things got messy yet again:
Here data structure and its logic is completely separated, which is nice. I can easily load it from file or manipulate in some way before it needs to be drawn, but when it comes to drawing things get uncomfortable.
The classic way would be to change data then call invalidate() on drawing wrapper,but that's inefficient for many small changes. So to, say, delete 1 Tile Id have to either have Drawn representation be independent of Data and call deketeTile() for both separately, or funnel all commands to Data through Drawing class. Things get even messier when I try to add different drawing methods via Strategy pattern or somehow else. The horror:
What wis a clean efficient way to organize interactions with Model and View?
First, definitely decouple the app logic from UI. Make some model for your schematic. That will solve your trouble to unit test the app model, as you already said. Then I would try the Observer pattern. But given that a schematic can have lots and lots of graphical components (your Tiles), I would change the usual setup for notifying every observer when something changes in the model, to notifying only the corresponding GraphicalComponent (Tile), when a Component gets changed in the Model. Your UI asks Model to do things, and gets called back in some parts to update. This will be automatic, no duplicated calls, just the initial observer registry on GraphicalComponent creation.
I am wanting to pull down and cache notes, notebooks and tags from the Evernote service using their iOS SDK. Their SDK comes with a Store that returns an array of model objects matching a filtered criteria I set.
I want to take those models and use them as a Entity in Core Data. I understand that I can't, because they inherit from NSObject. So my question to all of you is what are the best practices I can employe when I model my entities based on the Evernote model objects? It is a real pain because every time they change something, I have to reflect the same changes in my entities. Is there a work around, or am I stuck building a bridge (so to speak)?.
Thanks,
Johnathon
Following my comment
I don't understand your question here. Just kick off a data import
each time models are returned from Evernote. Each model should be
designed through a Core Data entity.
and you reply on it.
Sorry, I'm not sure what you mean by importing. Bring down the objects
from Evernote then manually assign their object properties to my
entities? That will be a pain but is an option. There's a lot if
properties to copy.
With importing I mean that you should insert a managed object for each model returned from the results received data from Evernote.
This means that if Evernote returns a model that contains three properties, you shoul create an Entity that looks the same (or similar since it strictly depends on what you UI will be).
Here I suppose that you Core Data store is a cache. So you should apply synchronization stuff. Items should be inserted, updated or removed based on user. Synchronization is not easy to achieve but I can suggest you the following tutorials.
How To Synchronize Core Data with a Web Service – Part 1
How To Synchronize Core Data with a Web Service – Part 2
You could also take advantage of RestKit in this case, since it offers an integration with Core Data. In particular, it allows to maps NSObjects, for example returned from a JSON call, to a Core Data entity in a easy way. An example can be found at NSScrencast GitHub Repository. Note that I don't know how Evernote SDK works. So, this approach could not be useful.
But if you are new to RestKit and Core Data, I really suggest to stick with plain Core Data. It's already difficult as its own.
If you need something else let me know.
Update 1
I am going to be doing a synchronization for sure, so I assume I have
to map the Evernote object completely with a Managed Object. Since the
Evernote objects can contain data blobs representing video, pictures,
files etc, I will need to look at how to store that data in Core Data
as well.
In Core Data you need (this not a must but I really good advice) to store files (e.g. images) in the file system. Within an entity you should maintain only meta-informations (i.e. the path) of an image and through it retrieve the image later. This is not necessary for small data, but I think your binaries will be big in size.
Starting from iOS 5 there is a new flag called External Storage that do this for you based on heuristic algorithm.
If you specify that the value of a managed object attribute may be
stored as an external record, Core Data heuristically decides on a
per-value basis whether it should save the data directly in the
database or store a URI to a separate file that it manages for you.
About searching for binary file I really suggest to an attribute called, for example, tag. This will allow you to search images, videos, etc. Obviously when you save you need to associate that tag with the specified binary data. This is just an idea.
P.S. If you need further support I really suggest to open a new question on SO. This to have a self-contained question.
You probably wanna save the object as NSData. Since I don't know what object you're looking for to use, I can't really tell if it's suitable for this. To see if it is, you would have to check if the class adopts the NSCoding protocol.
More info on archiving could be found in Apple's documentation:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Archiving/Archiving.html
I am quite new to Core Data, and I'm trying to implement it into my relatively simple OS X application. My application takes some file URLs provided by the user, gets some more information about the files (like creation date, for example), and then stores the URLs for use later.
I am wanting to have those file URLs, and related data, stored in a 'central' location so I can access, modify, and change the order of them (order is really important) from any of the classes in my application (correct me if I'm wrong, but I think Core Data is ideal for this).
I have my Core Data Model setup in Xcode (it only has one Entity which has a couple of Attributes), I've create an NSManagedObject Subclass to match the Entity in the Model, and I'm using Bindings to tie the data to a TableView. However, like I said, I need to be able get at this data from any class in my application. I have been reading Apple's Documentation and a book with a section on Core Data, however I am both struggling to get my head around it, and am yet to come across a section that describes the needs I mentioned above.
Any help with this (even just a link to a useful article) would be very much appreciated.
Thanks in advance.
I'm trying to decide whether some application state, specifically the selected item in a list, should be stored in Core Data or NSUserDefaults.
Generally I believe that application preferences and state should persist in NSUserDefaults, and model-level data should persist elsewhere, say in Core Data. My model so far is:
Should the data be stored at all? If the user wouldn't reasonably expect it to be, then throw it out (for example, the cursor position is not saved in TextEdit)
NSUserDefaults:
If the application were multi-document, the setting would apply to all documents
It's conceivable that the data would be configured in preferences
Having the data outside of the model makes sense for testing (swapping several defaults with one model store)
Model-level
The data clearly belongs as an attribute of a model-level object
The data is sufficiently large that storing it in NSUserDefaults would cause performance problems
It would be difficult or time-intensive for the user to re-create the data (they would definitely consider the loss of this information "data loss")
I plan to store the sort order of some entities in Core Data. Without this information (i.e. a "sortIndex" or "order" attribute) each entity instance would have to be augmented with data from the user defaults.
However, storing state in the model seems like a slippery slope. If I store sort order then it also seems appropriate to store selection since they are both the state of a list. The selection data for my use case may actually be quite large. Specifically, the icons in one list depend on the selection in each of their sub-lists.
Does anyone have a hard line they draw with respect to NSUserDefaults vs. data model?
You didn't mention whether this is a document-based app (like say, TextEdit) or a library-based one (like say, AddressBook).
That may help you decide where such information should go: assume a document-based app. Assume its documents get placed under version-control (this is actually feasible when using Core Data's XML data store type). Open the app, change the doc's sort orders. Does this dirty the document? Would this change be worth a check-in? Would the change be valuable to other users of this repository?
Typically, sort orderings aren't valuable enough to warrant document-based storage (ala NSTableView's Auto Save Name in Interface Builder). But your app may place a priority on sorting (it sounds like it).
So, there is no hard-and-fast rule. But I think the idea of having a document under version control, potentially shared with others, provides a good intellectual framework to make your case for either side.
I agree with rentzsch, but another way to view it:
Is the selection part of the data or is it metadata? If metadata, is it metadata about a single document or is it state that should apply to any document that happens to be opened next?
Document-specific metadata might want to be stored as an extended attribute. For example, TextMate stores the selection for a document this way, much as BBEdit, MPW, and others used to store tab settings, window size, etc. as a resource in the resource fork. Metadata is considered optional and the document is intact if it is stripped away.
If the selection is an integral part of the data, then by all means store it in the data, using Core Data if you happen to swing that way.
And if it's not a document-based app, then NSUserDefaults is the simplest path since support for it is generally built into common NSView subclasses via bindings.
I personally don't have a hard line between saving preferences in the file itself or in NSUSerDefaults.
But I have always tended towards the obvious:
Application preferences = NSUSerDefaults
Document preferences = in the file itself
For selection state specifically, I would judge if keeping that is important enough to the user. If it is, and important enough to move with the document to another computer, I would keep it in the document itself.
If it isn't important (or applicable) I wouldn't bother with saving it at all.