I've successfully implemented a NSDocument class in my Cocoa App which is also able to save data properly. But I have problems when it's about opening files.
This is my basic setup:
NSDocument MyFile ==xib File=> MyFile.xib
NSObject FileClass as processing class
FileClass is a class that compresses/decompresses files and is connected to the window's textfield in MyFile.xib. Saving is done via the default NSNotificationCenter. The data needs to be processed in this class because it does not contain raw NSStrings.
Let's say I have three documents that need to opened I have three NSDocument instances that now send their data via the NSNotificationsCenter. Because I have three NSDocuments I have three windows and three FileClass instances. Now it's just luck if the correct FileClass receives the data because I have no possibility to filter whether the received data is proposed for this window. A random FileClass now processes the file and sets the text of its associated Text View. So Window 1 could show the data that were thought to be shown in Window 3.
The data flow:
NSDocument => readFromData => NSNotificationCenter => random FileClass => associated TextView.
To narrow it down: How do I route the data to its correct window and how/where do I include FileClass in this construct?
Thanks in advance!
Paul
It's an indication for a major design flaw if you have to force your document data through the notification center to your viewing classes. Why do you have to do that? What issues are you trying to circumvent?
Related
In a Dolphin smalltalk treeview I'd like to use a custom icon, depending on the state of the item displayed, (differente state, different icon)
How can I do that ?
I cannot really understand how to use a "my" icon.
I've create a class "connection", with an instance variable "connected"
and two class methods "connectedIcon and unconnectedIcon that returns icon images.
Then an instance function "icon" that returns one or the other image based on the connection state.
I can add instances of this class to a tree view and see the name of the connections.
But how to show my Icons ?
I tried to sustitute the getImageBlock of my presenter view with the following expression [:obj | obj icon] but it doesn't work.
(nothing seems to happen).
this is made in my presenter initialize :
initialize
super initialize.
treePresenter view getImageBlock: [:obj | obj icon]
what's wrong with it ?
best regards
Maurizio
When you are editing a TreeView, one of the properties is getImageBlock. By default it is not really a block but another object that understands the message #'value:' (the class IconicListAbstract). You can replace this property with a code block (or other object that understands #'value:') and answer the image you want displayed.
In Microsoft Windows, icons are typically stored in a DLL. You should be able to use an icon explorer or editing tool to see the icons in a dll. For example, get IconExplorer from http://www.mitec.cz/iconex.html and try opening DolphinDR7.dll. Do the icons and numbers match what you see when you return a number in your application?
To determine (or override) the resource library used, see SessionManager>>#'defaultResLibPath'.
Typically, the getImageBlock is set using the property editor in the GUI editor, but setting it through code can work as well.
Wonderful Dolphin Smalltalk!
I had two problems
1) how and where to modify the getImageBlock method of my Treepresenter.
2) where to put the icons ad how to get the imageindex of each icon.
This is the solution :
1) it's not needed.
The treeview sends an #iconImageIndex" message to my model
this is handled by the default method (in the Object class) that send to my object the message #icon
and to the result of this message (an icon) the message #iconIndex.
This message is understood from the icon that answers with its own iconIndex.
So the only method I need to impement is #icon in my class Connection
that I implemented as follows:
icon
opened ifTrue: [^Connection connectedIcon] ifFalse: [^Connection unconnectedIcon]
In the class itself the two icons are imported in the image by evaluating the createIconMethod,
as explained in the blog article 'Beauty with less Beast'.
So my problems are solved.
Thanks to all.
Maurizio.
I have an app where the user should be able to create template settings files, to save and choose from a popup list. These settings will be applied to configure an export of an item.
I just don't know how to best approach the problem of saving and restoring the saved settings.
To add to my problem is the fact that there are many different exporting methods, each with different setting types.
To explain:
User configures the settings they want for export method A, he/she saves these settings and here i want to write them to disk in a plist file.
The the user configures another set of settings for export method B, he/she saves these settings and i want to write these to disk aswell.
I have used NSSharedUsersDefaultsController to bind all interface elements and test bindings, but i don't want to keep all settings in the application plist. Also, I don't know if there is a good way of importing/exporting using that technique when i'm using different subset of settings. If there was a good way of binding to sub-dictionaries then that could work, but I have not been able to make that work.
I could create a Class for each export method and bind the settings to an NSObjectController, and then manually create an import and export method but that felt clunky.
NSDictionaryController and NSArrayController only seem to be made for TableViews and that kind of data display, not single user interface elements, at least from what i've been able to test.
So, is there a good way to create an export/import functionality while still using cocoa bindings, or do i have to create my own methods for that?
Any examples or pointers in the right direction is appreciated.
A simple and suggest way of saving not critical / not secure settings is:
[NSUserDefaults standardUserDefaults]
You can access it like a dictionary with getObject: and setObject:
How would you solve this? When the app starts, four objects of a class are created. These objects have names you know because you named them yourself. From a viewController you can access these objects and call a method (which they all got) which creates a UILocalNotification. (So in the end you've got four notifications running.)
Two questions:
How do you name the notifications (differently)? As far as I know is it not possible to access the object name to use the string as name when creating the notification? (Which would be the best solution?)
When the notifications are fired, how do you access/cancel them from another viewController when you don't know the names?
Thank you!
Set tags for all objects, and set same tags for notifications, they generate.
I have some NSManagedObject subclass in my app, and I'm trying to understand when and how to save changes.
I will try to explain myself, for example class A is NSManagedObject subclass.
During app life cycle I do:
App launched
...
Create an instance of class A
...
Change some properties of A instance
...
App go to background
...
App becomes active again
...
Change some more properties of A instance
...
App terminates
When do I need to call [context save:] ??
Do I call it after every change in A instance? Or maybe I call it only when app go to background?
Should I call it after creation or deletion of any A instance?
A nice approach is place UIManagedDocument in your AppDelegate. Then you can call [context save] whenever some change occurs in the app (like a crash). The order I like to follow is something like:
Create UIManagedDocument object (in application did load or wherever)
and assign it to a property
Setup the document (check whether it exist on disk or is already open, etc.. and respond accordingly)
Pass the UIManagedObjectContext to the initial UIViewController in your app (from there you can pass the context to other view controllers)
UIManaged document will save the context for you.
Take a look at the UIManagedDocument documentation to configure persistent store options (you send an NSDictionary of options to your UIManagedDocument instance, see the first example through the link below).
UIManagedDocument documentation:
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIManagedDocument_Class/Reference/Reference.html
Also see the CoreData lecture and demo (lectures 13 and 14) of the iPhone and iPad application development course with Paul Hegarty available free on iTunesU (Fall 2011).
The data will not be saved to the persistent store until you call save. So, it depends on what you want in your app. If you want it to be able to recover the last value it ever had, then you should save after each modification.
Easy change is to just save after making modifications.
You could do something a bit more fancy, like only save after some set amount of time, so many changes are grouped together... and catch any event that will put your app in the background and then save...
But, that's what UIManagedDocument does automatically for you, so you could just use that instead.
Depending on the amount of changes that you make and the volume of data that needs to be saved with each change, yo can choose to save a little or a lot. If you are just saving a string or a number or a bool, then go ahead and call save: on your context as soon as the changes were made.
If it is a lot of data, you may want to coalasce your changes and then save it on a background queue so that you are not blocking the main queue. This way you are not waiting to go to the background to perform your saves.
Tim
Long time reader, first time poster here.
I'm creating a test app that creates a NSURLConnection and then displays the result on an UILabel.
I am presently using a Notification Center observer, which fires a notification from within connectionDidFinishLoading to wait for the connection to complete successfully, before I look for the result.
However, what I am struggling to conceptualize is where to store the response data so that I can access it from my View Controller and post the result to the UILabel. (Or from anywhere other than an instance of my Connection Class, for that matter.)
I don't want to post directly to the UILabel from connectionDidFinishLoading. I need a way to decide what I will do with the response later - so my Connection Class stays generalized.
I need a better way to save the response data somewhere, where I can reference it after the instance of the Connection Class has terminated.
Ideally, it should be somewhere that I can have multiple instances of the Connection Class open, and access each response in turn as I need them. This eliminates the potential to just create a variable in my View Controller or somewhere else more global and dump the response to it.
Any ideas on what design patterns could/should be used here would be greatly appreciated!
My suggestions for you to start with are :
Make a singleton class. I will have a property NSDictionary * info or NSArray *infoList; You will have acces to the same data from wherever the app. Update the property, post the notification, access the property from the viewController.
Store the info into a plist/file. Serialize the information, or save plain stream. Whatever you like.Thus after you finish writing to the file, post the notification, read from the file from anyplace within the app.
In both cases if you want multiple connections i suggest going for the factory design Pattern.