Sharing NSDocument subclass between multiple NSWindowControllers - objective-c

I have a application that isn't currently a document-based application (because I thought it would be more trouble than its worth). However I've been thinking it may possibly be worth it now, but there is one issue I haven't worked out yet. Sharing NSDocument subclasses between multiple windows.
So do subclasses of NSDocument have to be tied to a single NSWindowController, or can I share these between multiple windows? The reason I ask is my applications files are likely to up 100MiB (or larger) and its also likely that a user will open the same file in more than one window. Also these files take a relatively long time to process, so allowing multiple windows access to the same NSDocument would be excellent. Also, the files are updated very quickly with lots of data, so synchronizing multiple instances of the same document would use a lot of CPU time.
Has anybody done this, or can it even be done with a Document-based application? Any advice on this topic is greatly appreciated.

You should be able to use the method - (void)addWindowController:(NSWindowController *)aController found in the NSDocument Class Reference to do just that. There will be a lot of logic to let it know where to send what data, but this will at least give you control over several window controllers linked to the same document

So far this is the best answer I've found, which doesn't directly answer the question, but deals with many of the same obstacles I'm facing. Hopefully someone else has a better, more detailed and direct answer for me.
http://www.cocoadev.com/index.pl?DocumentBasedAppWithOneWindowForAllDocuments

The Document architecture wil help you to manage multiple models - ie. if you want the user to have multiple models open simultaneously and be able to switch between them, it could be of benefit to you.
It doesn't stop you from doing anything, it doesn't make otherwise easy things difficult. Handling the Windows and GUI is still down to you, and if you are unsure how to structure this, it wont make any difference if you use a document or not.
If the contents of a window can change over time to represent different documents - what happens when many documents are open? This can be a difficult problem to solve, and i don't really mean from a technical point of view (changing a window's contents is as easy as window.contentView=newView, right?).
It sounds like you have many misconceptions about what the document architecture is and what it can do for you.

The default is each document has one dedicated windows controller. But you can override
- (void)makeWindowControllers
to create your own windows controller and add them to the document as Slev mentioned.

Related

Reasons not to create an outlet by connecting directly between code and storyboard?

I am following the fantastic Matt Neuburg iOS7 Programming Fundamentals book and have just gone through the section discussing various ways to create an outlet.
The very last one he explains is connecting directly between code and the storyboard (nib editor). All of the ones before that involve HUD popovers, engaging with the connections inspector directly and so on, and are generally more involved, having more steps to follow before an outlet is created.
I'm still not sure on why you would use one of these more involved ways to create an outlet? Is it safe to infer that they are more reliable in terms of knowing that the outlet is properly set up? And if so, how exactly do these other ways achieve this?
The reason I'm asking is that I'd like to get on top of one way of creating outlets and if the hard way is the best way I'd rather get used to it right from the off.
They are pretty much equivalent, and it's a good idea to know about all of them, because a lot depends on where you are working and what you are seeing when you start. (For example, you can draw from the destination to the source or from the source to the destination.)
The problem with the one that makes your code for you (using an assistant pane so that you are seeing the storyboard and the code simultaneously) is:
It takes a lot of space; it's not a very good approach on my small-screen 13-inch MacBook Pro, for example, because there really isn't room for that split pane arrangement.
You have to get out of the split pane arrangement later, so why get into it in the first place?
Most important: it works only in a limited range of situations. It works if what you're connecting to is the superview's view controller, but it doesn't work at all if you're connecting between one view and another.
So my advice remains, as implied by the book: be fluid in all ways of making / exploring outlets and actions! The more you know, the more comfortable and secure you'll be.

How to use Core-Data best in complex Apps

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.

iOS - updating user flow without app update

I'm looking at designing and building out a system that would allow A/B testing of different flows in an iOS app (e.g. registration flow, log-in flow, purchasing flow).
A system that comes to mind initially looks like:
app pings server, server responds giving list of resources (which could include some links to xib files)
if the user does not have those xibs on disk, download them and save them to disk
when the view controller is presented, load from the xib if it has been downloaded (else default to the one the app was shipped with)
Does anyone have any thoughts on this idea or any insights on this system?
NOTE: I am not trying to implement a system where I can add new features. Right now, I'm focusing on changing flows, like the text and views a user will see. I'm not looking into a discussion of whether this violates the App Store rules, but if you would like to do so - go for it!
This is possible, but I don't know if I would download XIBs to the device. Seems a little risky to me.
Apple did a talk at WWDC 2010 where they address this exact issue, and they recommend building the interface using (more or less) Plists or JSON to describe the UI elements and their functions, and building up the views dynamically. It's well worth watching as it brings up a lot of smaller issues that aren't immediately obvious, but it requires a developer account to access it).
This would be an interesting system to use. I wonder if one could write a shell script to replace the old binary of an app with a new one. I know it would probably be more complicated then just that, but it would be cool to do. I would definitely use this for in house apps, or personal tools. Its to bad the apple wouldn't allow it, unless someone could secretly slip it past them :-)
I say go for it. You seem to have a pretty good idea of what you want to do and how you want to do it. Changing the UI based on responses from a server isn't uncommon, but I guess downloading xib files from the server is. I don't see why it wouldn't work though and I don't think it would be rejected by Apple, but you never know.

Documents and Nib files: What does apple mean by "Document"?

I don't understand how the term "Document" is used in objective-C and cocoa. When I build an Application, why do I have an "Document"? That makes no sense to me. I could have an Application like an Image Editor, wherein I can open like 100 Images at same time. So every Image is a Document and has its own Nib file? Can someone explain that term in a way that's humanly understandable? Best would be a lot of examples, I think.
From my ancient but still mostly relevant Cocoa NSFAQ (Not-so FAQ):
Q18
Why would I want a Document subclass?
A18
Because you have a central data model which needs an object to manage it.
In more detail, don't always think Document==File. The conceptual Document in most Mac applications may indeed map to a single file on disk but is also often a central object (Model in classic MVC design).
If you're using a database, the Document might manage the database connection and even end up saved as a file persisting that connection.
For your photo library, the Document might be singular, just containing some settings, or you may have multiple Documents corresponding to different layouts and filters as to which photos are visible.
There's no reason why you can't have more than one Document or even hundreds open if you want to go that way - the Document is a way to provide data to views and you can have hundreds of instances if you want.
Document-based, in terms of the Xcode templates, essentially means an NSDocument subclass. NSDocument and NSDocumentController provide an abstraction that makes it simpler to support multiple documents.
You are correct, you can hand-code it without NSDocument just fine. However, NSDocument does make it a bit easier.

How to convince my co-workers not to use datasets for enterprise development (.NET 2.0+)

Everyone I work with is obsessed with the data-centric approach to enterprise development and hates the idea of using custom collections/objects. What is the best way to convince them otherwise?
Do it by example and tread lightly. Anything stronger will just alienate you from the rest of the team.
Remember to consider the possibility that they're onto something you've missed. Being part of a team means taking turns learning & teaching.
No single person has all the answers.
If you are working on legacy code (e.g., apps ported from .NET 1.x to 2.0 or 3.5) then it would be a bad idea to depart from datasets. Why change something that already works?
If you are, however, creating a new apps, there a few things that you can cite:
Appeal to experiencing pain in maintaining apps that stick with DataSets
Cite performance benefits for your new approach
Bait them with a good middle-ground. Move to .NET 3.5, and promote LINQ to SQL, for instance: while still sticking to data-driven architecture, is a huge, huge departure to string-indexed data sets, and enforces... voila! Custom collections -- in a manner that is hidden from them.
What is important is that whatever approach you use you remain consistent, and you are completely honest with the pros and cons of your approaches.
If all else fails (e.g., you have a development team that utterly refuses to budge from old practices and is skeptical of learning new things), this is a very, very clear sign that you've outgrown your team it's time to leave your company!
Remember to consider the possibility that they're onto something you've missed. Being part of a team means taking turns learning & teaching.
Seconded. The whole idea that "enterprise development" is somehow distinct from (and usually the implication is 'more important than') normal development really irks me.
If there really is a benefit for using some technology, then you'll need to come up with a considered list of all the pros and cons that would occur if you switched.
Present this list to your co workers along with explanations and examples for each one.
You have to be realistic when creating this list. You can't just say "Saves us lots of time!!! WIN!!" without addressing the fact that sometimes it is going to take MORE time, will require X months to come up to speed on the new tech, etc. You have to show concrete examples where it will save time, and exactly how.
Likewise you can't just skirt over the cons as if they don't matter, your co-workers will call you on it.
If you don't do these things, or come across as just pushing what you personally like, nobody is going to take you seriously, and you'll just get a reputation for being the guy who's full of enthusiasm and energy but has no idea about anything.
BTW. Look out for this particular con. It will trump everything, unless you have a lot of strong cases for all your other stuff:
Requires 12+ months work porting our existing code. You lose.
Of course, "it depends" on the situation. Sometimes DataSets or DataTables are more suited, like if it really is pretty light business logic, flat hierarchy of entities/records, or featuring some versioning capabilities.
Custom object collections shine when you want to implement a deep hierarchy/graph of objects that cannot be efficiently represented in flat 2D tables. What you can demonstrate is a large graph of objects and getting certain events to propagate down the correct branches without invoking inappropriate objects in other branches. That way it is not necessary to loop or Select through each and every DataTable just to get the child records.
For example, in a project I got involved in two and half years ago, there was a UI module that is supposed to display questions and answer controls in a single WinForms DataGrid (to be more specific, it was Infragistics' UltraGrid). Some more tricky requirements
The answer control for a question can be anything - text box, check box options, radio button options, drop-down lists, or even to pop up a custom dialog box that may pull more data from a web service.
Depending on what the user answered, it can trigger more sub-questions to appear directly under the parent question. If a different answer is given later, it should expose another set of sub-questions (if any) related to that answer.
The original implementation was written entirely in DataSets, DataTables, and arrays. The amount of looping through the hundreds of rows for multiple tables was purely mind-bending. It did not help the programmer came from a C++ background attempting to ref everything (hello, objects living in the heap use reference variables, like pointers!). Nobody, not even the originally programmer, could explain why the code is doing what it does. I came into the scene more than six months after this, and it was stil flooded with bugs. No wonder the 2nd-generation developer I took over from decided to quit.
Two months of tying to fix the chaotic mess, I took it upon myself to redesign the entire module into an object-oriented graph to solve this problem. yeap, complete with abstract classes (to render different answer control on a grid cell depending on question type), delegates and eventing. The end result was a 2D dataGrid binded to a deep hierarchy of questions, naturally sorted according to the parent-child arrangement. When a parent question's answer changed, it would raise an event to the children questions and they would automatically show/hide their rows in the grid according to the parent's answer. Only question objects down that path were affected. The UI responsiveness of this solution compared to the old method was by orders of magnitude.
Ironically, I wanted to post a question that was the exact opposite of this. Most of the programmers I've worked with have gone with the custom data objects/collections approach. It breaks my heart to watch someone with their SQL Server table definition open on one monitor, slowly typing up a matching row-wrapper class in Visual Studio in another monitor (complete with private properties and getters-setters for each column). It's especially painful if they're also prone to creating 60-column tables. I know there are ORM systems that can build these classes automagically, but I've seen the manual approach used much more frequently.
Engineering choices always involve trade-offs between the pros and cons of the available options. The DataSet-centric approach has its advantages (db-table-like in-memory representation of actual db data, classes written by people who know what they're doing, familiar to large pool of developers etc.), as do custom data objects (compile-type checking, users don't need to learn SQL etc.). If everyone else at your company is going the DataSet route, it's at least technically possible that DataSets are the best choice for what they're doing.
Datasets/tables aren't so bad are they?
Best advise I can give is to use it as much as you can in your own code, and hopefully through peer reviews and bugfixes, the other developers will see how code becomes more readable. (make sure to push the point when these occurrences happen).
Ultimately if the code works, then the rest is semantics is my view.
I guess you can trying selling the idea of O/R mapping and mapper tools. The benefit of treating rows as objects is pretty powerful.
I think you should focus on the performance. If you can create an application that shows the performance difference when using DataSets vs Custom Entities. Also, try to show them Domain Driven Design principles and how it fits with entity frameworks.
Don't make it a religion or faith discussion. Those are hard to win (and is not what you want anyway)
Don't frame it the way you just did in your question. The issue is not getting anyone to agree that this way or that way is the general way they should work. You should talk about how each one needs to think in order to make the right choice at any given time. give an example for when to use dataSet, and when not to.
I had developers using dataTables to store data they fetched from the database and then have business logic code using that dataTable... And I showed them how I reduced the time to load a page from taking 7 seconds of 100% CPU (on the web server) to not being able to see the CPU line move at all.. by changing the memory object from dataTable to Hash table.
So take an example or case that you thing is better implemented differently, and win that battle. Don't fight the a high level war...
If Interoperability is/will be a concern down the line, DataSet is definitely not the right direction to go in. You CAN expose DataSets/DataTables over a service but whether you SHOULD or is debatable. If you are talking .NET->.NET you're probably Ok, otherwise you are going to have a very unhappy client developer from the other side of the fence consuming your service
You can't convince them otherwise. Pick a smaller challenge or move to a different organization. If your manager respects you see if you can do a project in the domain-driven style as a sort of technology trial.
If you can profile, just Do it and profile. Datasets are heavier then a simple Collection<T>
DataReaders are faster then using Adapters...
Changing behavior in an objects is much easier than massaging a dataset
Anyway: Just Do It, ask for forgiveness not permission.
Most programmers don't like to stray out of their comfort zones (note that the intersection of the 'most programmers' set and the 'Stack Overflow' set is the probably the empty set). "If it worked before (or even just worked) then keep on doing it". The project I'm currently on required a lot of argument to get the older programmers to use XML/schemas/data sets instead of just CSV files (the previous version of the software used CSV's). It's not perfect, the schemas aren't robust enough at validating the data. But it's a step in the right direction. The code I develop uses OO abstractions on the data sets rather than passing data set objects around. Generally, it's best to teach by example, one small step at a time.
There is already some very good advice here but you'll still have a job to convince your colleagues if all you have to back you up is a few supportive comments on stackoverflow.
And, if they are as sceptical as they sound, you are going to need more ammo.
First, get a copy of Martin Fowler's "Patterns of Enterprise Architecture" which contains a detailed analysis of a variety of data access techniques.
Read it.
Then force them all to read it.
Job done.
data-centric means less code-complexity.
custom objects means potentially hundreds of additional objects to organize, maintain, and generally live with. It's also going to be a bit faster.
I think it's really a code-complexity vs performance question, which can be answered by the needs of your app.
Start small. Is there a utility app you can use to illustrate your point?
For instance, at a place where I worked, the main application had a complicated build process, involving changing config files, installing a service, etc.
So I wrote an app to automate the build process. It had a rudimentary WinForms UI. But since we were moving towards WPF, I changed it to a WPF UI, while keeping the WinForms UI as well, thanks to Model-View-Presenter. For those who weren't familiar with Model-View-Presenter, it was an easily-comprehensible example they could refer to.
Similarly, find something small where you can show them what a non-DataSet app would look like without having to make a major development investment.