I'm using a sheet to ask the user some information for an operation that the application performs. The sheet has some 10 to 15 options (split into 4 tabs, so its a relatively clean UI) that the rest of the program needs to know before proceeding.
Right now, I have a separate window controller class for the sheet called SheetController. SheetController has a delegate property and the main controller, AppController, is set as the delegate.
When the user clicks OK in the sheet the delegate is notified and a method called didClickDone:(id)sender withParameters:(id)parameters is executed. parameter is a object that contains various properties from the sheet. My question is, is this a good approach to handling Sheets and returning data from them?
Secondly, one thing that bothers me is that the parameter is just a dead object - it only has accessor methods. It doesn't do any manipulation on them as its entire purpose is to 'carry' the data to the main controller, which in turn passes the information to the Model of the program. And, unless I'm missing something, shouldn't I just declare parameter to be a normal C struct? Or is there an advantage of using an object for this sort of purpose?
EDIT: Would a passing an NSDictionary be a good compromise? I could save the returned information with their keys in the dictionary and simply pass it.
Maybe I would not notify directly the controller from the push button event handler but
call another routine that encapsualates the logic on how the data have to be commited to the model.
Don't worry about the empty object. Is a common pattern to use it and is called DataTransferObject
Related
What's the best way to use Core Data if each document on disk corresponds to one Entity instance?
I have a data model file with one entity, and that entity has one attribute of name text and of type Text.
I have a Document.xib that has an NSObjectController that is set to 'Entity' mode and gets the managedObjectContext from the File's Owner. I have an NSTextField that is bound to the Object Controller for the Controller Key 'selection' and the Key Path 'text.' (This is just a test so I can figure out how Core Data works, but my eventual app will also only have one Entity instance per Document)
When I create a new document the textfield says 'No Selection' and is disabled.
I imagine that if I had a Table View or some other kind of way to select from among entity instances the selection would work but I don't nor do I want to. How can I hook up the NSObjectController to only have one Entity instance and to automatically 'select' it?
The intended behaviour is that I type something into the NSTextField, hit Save, close the document, re-open the document and the string in the textfield persists.
This is probably a really basic question but I can't find any tutorials or documents that would address this seemingly simple use case.
Ok, well I haven't figured it all out but my particular issue was being caused by the fact that nothing was being created. I switched out the NSObjectController for an NSArrayController, created an outlet for it in Document.m and added this to windowControllerDidLoadNib:
if (![self.arrayController selectedObjects]) {
[self.arrayController add:#""];
};
Now it seems to just manage the one Entity object.
I have read a lot about the patterns of sharing data between views .
I know how to use delegates,and segues to pass data(iOS), but i want to share a more deep question.
Lets say i have some tasks app, and each new task the user create, is an instance of a class called Task, that holds all the data on that task(date,text,etc) .
Now when in viewA, that shows the tasks list in a table, a user push a button to create a new task, hence has to create an object of Task class.
Than i take the user to viewB to edit the task, and maybe later to viewC .
A few options are possible, but for each i find some inconvenience.
viewA's controller is creating the Task new object,and pass it to b, than b to c, etc.
viewB's controller is creating the Task new object,than post a delegate to A,with task
It seems that the right option is 1 , but it has some problems such as that after view controller B edit the task, viewA's controller needs to reload the table with that new task- anyway, than, option 2, posting a delegate from b, seems more simple,so b is creating a Task object, than post delegate to the table in A to save it and also to reload the table with it .
Here the data is less capsulated .
Maybe i am completely wrong ,but i really try to understand how things should be done right .
Any thought will be helpful to me.
Or you could create a data model.
Consider having a TaskManager class that manages the list of tasks, creates them, and knows which one is currently selected (or most newly created). Either your TaskManager can be a singleton or can be accessed via your app delegate. Anything that needs to be done with a Task, the TaskManager handles.
That way, you make your view controllers more independent because they don't talk to each other but read and update the current state of the data model from the object that's responsible for it.
I have a core data 'ShoppingList' which contains 'Item' objects. I store a display order as an attribute of each item.
I would like to update the display order of all other items in the shopping list whenever an item is deleted. The code to do this is working fine when I use it in my view controller (from where the item is deleted), but since it is really related to the business objects and not the view, it would be better placed in either ShoppingList or Item.
Ideally, I would like it incorporated into the deletion of the item. So far I have tried the following:
1) Customize the standard Core Data generated ShoppingList.RemoveItemsObject (making sure to observe KVO before.after). What's strange about this way is that the item passed is stripped of its relationships to other core data entities before it gets to my code, which I need to process display orders correctly.
2) Customize Item.didTurnIntoFault. Same applies - but even attributes of the item are gone by this stage.
One answer would be to simply define a new method on ShoppingList that does my processing and then calls the original removeItemsObject. But I would prefer to know that whenever an item is removed, from anywhere, this is taken care of. This works nicely when I customize awakeFromInsert, for example - I know that whenever an item is created certain things are setup for me. But I'm surprised there's no equivalent for deletion.
Did you try to implement prepareForDeletion? Sounds like it's exactly what you're looking for.
The doc says:
You can implement this method to perform any operations required before the object is deleted, such as custom propagation before relationships are torn down, or reconfiguration of objects using key-value observing.
I'm using Core Data in my OS X application where I have some TableViews bound to NSArrayControllers. The problem I'm having is when I'm trying to populate a tableview in a sheet using an array controller where I don't want the contents to persist.
Here's how the app hangs together;
Window 1 - Shows a list of users in a table view and allows adding and removing users. Contents persist via Core Data bindings.
Window 2 - Shows a list of groups in a table view. A second table view shows a list of users that belong to the selected group. Contents persist via Core Data bindings. An 'add users' button invokes a sheet for adding users to the group.
Add Users sheet - This sheet shows a table view of users that are not already members of the selected group. Pressing the close button on the sheet adds the selected users to the selected group.
Ok, so the problem I'm having is with the array controller for the Add Users sheet. When I invoke the sheet I iterate through all users and add any to the array controller if they don't already exists in the group. When I close the sheet I try to clear down the array controller using removeObject: but this causes a "can't use this method with a ModelObjectContect."
Why do I need a MOC to remove items from the array controller? It's only for display purposes so I don't need it to persist. If I set the array controllers MOC to that of my app delegate, it physically deletes the users, which I obviously don't want. I just want to remove them from the table view of the sheet.
I thought the answer might be to create another MOC to use as a scratch-pad and not tie it to a persistent store, however this just gave me a different error when using removeObject:, something along the lines of "can't remove objects that exists in another MOC."
Why am I allowed to add object to an array controller but not remove them? In cases where you don't actually want the items physically removed are you supposed to access the the underlying "content", e.g. [arraycontroller content]? I've played with this but get strange display results as it seem to be playing with the array controller's content behind it's back. If I do this, is there a way to tell the array controller "by the way, I've been tinkering with you're content and you may need to get yourself together"?
It looks to me like you shouldn't be using array controllers without Core Data, but there is numerous comments in the documentation that suggests that it works with and without core data.
Yes, you can use an array controller without a Core Data Managed Object Context. But as you're storing NSManagedObject instances inside it, I think it tries to mark them for deletion when you removed them.
If you work with managed objects and don't want the contents of the array controller to be deleted on removal, you have to bind the array controller's content to another object's property with Cocoa Bindings.
But there is a simpler solution. I suggest you to set the managed object context of the array controller to your main MOC and use a predicate to filter its content.
[arrayController setPredicate:[NSPredicate predicateWithFormat:#"NONE groups == %#", group]];
Thus, there is not need to add or remove users from the array controller as all users that are already in the group will be hidden.
You can use them with and without core data, but an array controller either uses core data (entity backed), or it doesn't. I don't think you can use one with managed objects and not have a context.
I'm not clear why you are creating objects instead of just using a fetch request?
You don't say how you are adding the "missing" users but If this is just a basic list, you could consider creating an array of proxy objects (so you aren't touching the MOC) which you can junk when the sheet is done. You could use a non-core data array controller for this, or just (gasp!) not use bindings at all and do it the old fashioned way.
Why not use [arrayController setContent:nil]
a datacontext defined in a module(domain services ado.net ria)
a page having add/delete methods
whenever any method is executed, it is found that all the previous actions (NEW RECORD ADDITION and DELETION OF RECORDS) are carried out before the new action is carried out
normally
this behaviour is not prominent but
"when using break points and inspecting the values of the variables and table object to be added to context, it is clear that all the previous actions take place again.
edit
even when the datacotext. savechanges is called, even after that still all actions carried out on the datacontext repeat themseleves, when any new action is to be carried out
got the problem
was creating a new instance of the usercontrol every time, therefore all the instances did there work when asked to add record to context....
solution
just declare the instance of the usercontrol once in the constructor of the main page.
then use that declaration where ever needed.