How to use Core-Data best in complex Apps - objective-c

I am a Mac App Dev and have some questions about how to use Core-Data correctly.
I have multiple TableViews and they are all playing around with the same data (which I want to save persistently with Core-Data). I know the central part of Core-Data which I have to work with - NSManagedObjectContext and I know how to create NSManagedObjects and save/edit/delete these in the persistent store.
But actually I'm wondering about how to organize all that together with multiple ViewControllers,Views,Tables,.. efficiently and without merge conflicts. I've read about some approaches for that: one was by passing the context down from the delegate through every layer of your code. Somebody else suggests to create a singleton-class, let's call it DatabaseManager, which holds the NSManagedObjectContext instance and you go and ask it from there. (I especially like this approach, don't know why.) Or just ask the delegate every time with [[NSApplication sharedApplication] delegate], does this have any disadvantages?
Okay, a lot of questions here but that was only about the How. Now I want to know about your recommendations of where I should actually do all interaction with the managedObjectsContext. (to be in compliance with MVC and don't mess up my code and make it more complicated than it has to be..)
Should I save stuff to Core-Data in my NSTableViewDelegate/-DataSource Classes directly or just fire up an Notification for someone else?
Should I implement some instance methods for my Model-Objects (like -(void)saveInstanceToDatabase,..) to encapsulate Core-Data-Interaction?
Ok thanks in advance for all the brave guys who read until this point and give me some kind of response :D I always appreciate code-examples!

After years of working with Core Data... I've come to the conclusion it's not very good. There are some serious flaws in it's design that can only be solved properly by abstracting the whole thing away.
I recommend implementing your own model for manage objects, which uses core data underneath but does not ever expose it.
Your views and controllers and application delegate and all of that should not ever touch core data at all. They should talk to a series of classes you create yourself, which has been custom tailored for your particular application.
That object layer can use core data underneath, or it might use something else like FMDB or NSCoding or even just plain old NSData objects (this is the fastest option, if you need extremely high performance with large amounts of data, especially when combined with features like NSDataReadingMappedIfSafe).
Start with Core Data. Look at the other options if you have problems. Having your own layer on top means you can easily abandon it in future. And many developers have chosen to move away from Core Data shortly after their app ships to the public. Often due to unsolvable bugs or performance issues.

Related

MVC design pattern with multiple classes in iOS

I'm trying to improve the structure of my development, and stripping back to the very beginning while learning Swift. This is not language dependent though (the edit is not appropriate).
Something has been troubling me for sometime, and I hope someone can take the time to help me.
I'm making a simple game where questions are stored in a binary tree, so am creating a class for the binary tree (BinaryTree.swift).
My ViewController will take care of interactions with the interface (buttons etc.)
I need to also create the business logic for the game (which question should be returned, keeping score etc.). The logic for this type of game is trivial, but I need to understand principles before I scale up to larger projects.
Problem
Is it reasonable to create a class in a separate file solely for the game logic (GameLogic.swift), as I'm concerned that it is not a reasonable way to structure this app.
In all honesty, it is up to the developer to choose how they structure their data. The MVC, or Model View Controller model is still alive and well but I choose not to use it. Without a who lot of information on what exactly would go into GameLogic.swift, I would say go ahead and try it. Maybe another developer with more experience than me can give you another idea!

Better to not use Core Data for ease of thread safety?

I have an app that is currently built on Core Data and has multiple threads with multiple NSManagedObjectContexts. It's a music app so there is always stuff running on the background threads that needs to not interfere with the main thread and vice versa.
So far I've been slowly chipping away at all sorts of deadlock & thread safety issues, but frankly I'm hitting a wall in trying to keep MOCs in sync and have them not block threads, and nothing access entities that have been deleted etc.
My question is this:
If I were to ditch Core Data and just create some custom NSObjects to keep track of properties would that make these kind of issues simpler? Is it possible to access the NSObjects from multiple threads (without causing deadlock etc) so that I wouldn't have to maintain several copies and sync them? Or will I still face similar challenges?
I'm pretty new to objective-c so i'm really looking for the easier solution rather than the most sophisticated. Any links to good designs patterns for this sort of thing also appreciated!
Rephrasing the question: "Would we be better off ditching a framework where the engineers, whose sole focus is on creating said framework, have spent countless hours working on that framework's concurrency model to instead roll our own concurrency model, starting from scratch?"
Concurrency is hard.
Rolling your own means tackling all the problems that Core Data has tackled already (including accessing state from multiple threads without deadlocking and/or requiring many copies of the data) and then adding on whatever unique twists you need for your app. The team that wrote Core Data has thought quite deeply about the subject, to the point that there is an entire set of documentation devoted to it (with the APIs to back it).
So, certainly, there is quite likely a concurrency model that would be highly specific to your application that would be considerably more efficient than using Core Data, but you are going to end up re-inventing the persistency patterns Core Data currently offers you and you'll need to engineer said concurrency model from the ground up.
So, no, there is no easy way out.
Given that it is a music app, I can fully appreciate how difficult the concurrency issues can be. Latency is obviously a huge issue. You'll need to ask a more specific architectural/design question to really glean much insight beyond the above.
For example, what granularity of data are you persisting via Core Data and what is the frequency of change of said data? Is the model of said data relatively optimal? Etc.etcetc...
Or, with a concrete example:
Say you have a Note class that describes a note to be played. Say that note has properties like pitch, volume, duration, instrument, etc...
Now, imagine your background thread needs to set pitch and duration.
Without thread synchronization of some kind, how would the consuming thread know that the editing thread is done editing?

Multi User Core Data w/ XPC

Howdie,
This is my first post, so if this has been answered somewhere please forgive me (I did search).
Problem:
I have a Cocoa app that needs to share a single Core Data database among multiple user accounts on the system.
Idea:
I would create a daemon to handle requests from the users (to cross user privilege boundaries) to save/retrieve the data from Core Data. Create a shared Managed Object Context that is used in the application and pass that MOC to the daemon through NSXPCConnection. The daemon will have a fully realized Core Data Stack. I can then set the MOC that was created in the app to be a child of the MOC that was created by the daemon. Hit save and I'm done?
Question:
Would this even work? Is this just a dumb idea? What are the other solutions? NSManagedObjectContext conforms to the NSCoder protocol, but in order to use it with XPC I have to subclass it and make it conform to the NSSecureCoding protocol? Would I also just need to make sure my ManagedObject subclasses conform to NSSecureCoder protocol to use with NSXPConnection? I suppose I can ditch the context all together and just send the managed objects.
I'm assuming NSXPCConnection copys objects instead of using pointers? Is this correct?
Also, I'd probably have to keep performance in mind as the objects are coded/ decoded as fully realized objects and not faulted. Is this correct?
Thank you in advance for your help.
Maybe it works. ;-)
But there are some special problems you have to deal with. To make a long story short: I think that it would be better to use an incremental store doing this. But its documentation is close to poor.
We implemented something like this for syncing. And we have to implement this for networking. (That is, what you want to do.) Here are the problems:
A.
Moving around the context won't help. The context contains a subset of the store objects. Which one is in the context is random to the app programmer. (Inserted and changed objects will live there, but not changed, not inserted objects can be there and can go away.)
B.
You can of course move around the store. Since it is on the hard disk, this would be easier, if you have access to that location, where it is stored. You can use an XPC service for that.
Doing so has the problem that you do not know, what one user changed. You only get the whole store. In contrast an incremental store knows the specific changes through the save request.
C.
"Different users" means that you have conflicts. This is "unnatural" to Core Data. Is is a graph modeller and being that, it is not "connection based". It opens a document, owns it, changes it, stores it, and closes it. As every document it is typically not owned by two or more apps (including two running instances of one app) at one time. There is no real good mechanism for working on a store simultaneously. So you have to handle that yourself. It is probably easier to handle that on the level of the incremental store than on a level build on top of it.
What you want to do is not that easy, if you do not make assumptions you can make in your special case. (For example having a locking mechanism on a higher level.)
My 0,05 $.

Abstracting Core Data from the rest of the app (MVCS pattern)?

I'm working on an app that is basically a client for a server-side REST API.
The app relies heavily on server-data (kind of like Facebook does).
In my app I have an ServerAPI class that manages all interaction with the server. It basically acts as the "Store" in the "Model-View-Controller-Store" pattern. The rest of the app uses a singleton instance of this class to access data.
So for example if one of my view controllers needs a list of Articles, it would call:
[[ServerAPI sharedAPI] fetchArticlesWithCompletion:^(NSArray *articles){
// Do something with the new articles.
}];
This way the app doesn't care how the articles are fetched. For all it knows, they were fetched from a local file and not a server.
This is all fine and well.
The problem now is I'd like to add some sort of caching. After looking around it sounds like Core Data might be the best tool for the job (but I'm definitely open to other suggestions).
I found AFIncrementalStore (NSIncrementalStore subclass for AFNetworking) which looks promising. But from my (currently limited) understanding of NSIncrementalStore, the app (view controllers) still interact directly with NSFetchRequests and MOCs to fetch data.
I'd like to keep my current API (ServerAPI singleton) and simply plug in Core Data "behind the scenes" so that the rest of the app remains unaware of the details. Basically the app shouldn't know that data is cached, or how it is cached, it should just request data and get data.
So my question is, what's a good strategy for implementing this? Has anyone done something like this before? Is it worth the effort? I understand that Core Data is itself a way of abstracting stores, so having a second layer of abstraction might be overkill. But I keep thinking of the case where if one day I decide to use NSCoding instead of Core Data to store objects to disk. I generally don't like having all my classes know about implementation details (in this case using core data vs not using core data).
I'm a little torn on what approach is best. I don't want to invest too much time into a solution that might not make sense in the long run.
Generally does it make sense to use Core Data APIs directly in code? Or is it best to abstract away all these details behind a custom DataManager that handles both server and local data.
Thoughts?
Personally, I'd use RestKit as the bridge between the RESTful API and Core Data. I would use Core Data and I wouldn't be thinking that changing to NSCoding might be a good idea in the future (that's a really very unlikely scenario). Core Data offers you a lot of options for storage, searching and memory management. Getting the same features from another store is going to be a lot of effort or a similar level of dependency.
Either way, you have 2 options - hide the cache or don't.
If you hide it, the side effect would be that you'd really need to call the completion block twice (first for the cache hit, second for the server response). How easy that will be depends on what you're doing. The issue would be that you wouldn't be able to leverage all of the search and memory management features of your cache (like only loading pages of data from the store and loading more as the user scrolls through a list).
If you don't hide it, yes you would use fetch requests and MOCs. Probably via NSFetchedResultsController. The impact is relatively low IMHO and the benefits are large (like the automatic page management). Now your structure is - view controllers watch the 'cache' for data (the ServerAPI owns the MOC so it still mediates the store), they can get existing data immediately and if they decide new data is required they call the ServerAPI. The ServerAPI works exactly as it does now (with the completion block) and the completion block is either used as a trigger to update the UI activity indication or as the actual source of data if needs be.
As you can probably tell, I wouldn't hesitate in using Core Data and allowing its features to be used in my view controllers. The part I'm interested in shielding the rest of the code from is the server API, not the local data cache.

How should Web Applications Interfaces be designed?

I am building a web application and have been told that using object oriented programming paradigms affects the performance of the application.
I am looking for input and recommendations about design choices that come from moving from One Giant Function to a Object-Oriented Programming Interface.
In order to be more specific: If a Web Application used OOP and created objects that live for a very short time period. Would the performance hit of creating objects on the server justify using a more functional ( I am thinking static functions here ) design.
Wow, big question, but in short (and comment if you want more info) OOP code/practises (ideally well written at that) will give you far more maintainability, testability and joy to code in that OGF coding.
As for the speed arguement, that really is only an issue if you are really trying to squeeze every possible last ounce of CPU out of a server thats going to get hammered. In which case you are problably doing something wrong and need to think about better/more servers or you work for NASA or are doing it for a dare.
I dont know about performance but it definitely makes it easier to maintain.
I am looking for input and
recommendations about design choices
that come from moving from One Giant
Function to a Object-Oriented
Programming Interface.
as David suggested, answering the above will require lot of pages.
Perhaps you should be looking at frameworks. They make some design choices for you.
The most popular way of designing a web app with OOD/OOP is to use the Model-View-Controller pattern. To summarise the 3 main participants:
Model - I'm the stuff in the problem domain that you're manipulating.
View - I'm responsible for drawing and managing what you see in the browser. In web apps, this often means setting up a html template and pushing name-value pairs out into it.
Controller - I'm responsible for handling requests that come in from the web and working out what to do with them and arranging with the other objects to get that work done.
Start with the controller...
Views and Controllers often come in pairs. The controller accepts the HTTP request, works out what needs doing - and it either does it (if the work is trivial) or delegates the work to another object to do. Typically it find the view that's to be used and gives it to the object that's doing the actual work to write output into.
What I've described here corresponds with what you'd expect to find in something like Ruby on Rails.
Making lots of objects that you use once is certainly a concern - but I wouldn't worry about that aspect of performance up front. Proper virtual machines know how to manage short-lived objects. There's plenty of things you can do to speed up a web app - and I would start by sacrificing the benefit of clear organization for a speed up that might not even be the most important optimization...
MVC isn't the only way to go, there are other patterns like Model-View-Presenter and some really unusual approaches like continuation servers (e.g. Seaside) - which reuse the same objects between HTTP requests...
Yes. When doing an OO approach to web app development (using Seaside) I can deliver functionality so much faster that I have sufficient time to think about how to deliver the right amount of performance.