Pointing in the right direction for an XCode 3 pref pane.
Hi all, I'm a novice as far as Cocoa is concerned having only just finished Aaron Hillegass' book on programming for OS X. It's been going fairly well until I actually wanted to apply the ideas to my own project! I've written a ruby command line utility that has a model stored in a plist file and I felt a prefpane would be a good solution for editing the Plist. I have some very basic questions that I'm fairly ashamed that I even have to ask, but I've scoured the web for prefpane based tutorials for XCode 3 without joy, so there's nothing for it but to go ahead and ask a stupid question. Having constructed a preference subclass with the appropiate outlets corresponding to those I've placed in the nib file, I'm getting an NSObject and setting it's class to the preference pane subclass with my outlets in it, but this seems to be giving me an unexpected choice of outlets when I'm trying to connect them. I was hoping to see the outlets broadcastIP, printers and servers. Instead I see _FirstKeyView, _InitialKeyView, _LastKeyView window and New Referencing Outlet. Am I supposed to use something other than an NSObject when it's a preference pane in order to make connections? Thank you very much, Adam Penny ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Pointing in the right direction for an XCode 3 pref pane.
Hi Nick, Yes, I've tried that and it gave me the little '+' symbol in green, which is always a good sign, but it proceed to do nothing. Here's my header file, just in case that's where the problem lies: #import @interface WopolPref : NSPreferencePane { IBOutlet NSTextField *broadcastIP; IBOutlet NSTableView *printerSpec; IBOutlet NSTableView *serverSpec; } - (void) mainViewDidLoad; @end I understand from Apple's docs on the subject that I'll also need an initWithBundle action as well, but I got the impression that this was enough just to get the outlets hooked up with IB. Thanks again, Adam On Oct20, 2008, at 1:59 AM, Nick Zitzmann wrote: On Oct 19, 2008, at 9:33 AM, Adam Penny wrote: Having constructed a preference subclass with the appropiate outlets corresponding to those I've placed in the nib file, I'm getting an NSObject and setting it's class to the preference pane subclass with my outlets in it, but this seems to be giving me an unexpected choice of outlets when I'm trying to connect them. I was hoping to see the outlets broadcastIP, printers and servers. Instead I see _FirstKeyView, _InitialKeyView, _LastKeyView window and New Referencing Outlet. Am I supposed to use something other than an NSObject when it's a preference pane in order to make connections? Have you tried manually loading the header into IB by dragging the file onto the nib window? IB is supposed to automatically loads headers, but sometimes it doesn't. Nick Zitzmann <http://www.chronosnet.com/> ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Pointing in the right direction for an XCode 3 pref pane.
Hi again, Sorry, in my naivité I had expected the drag and drop to do more, but having just created a new NSObject in IB and pointed at the wopolpref class I now discover that it dragging and dropping has done the trick. Thank you very much! Adam On Oct20, 2008, at 1:59 AM, Nick Zitzmann wrote: On Oct 19, 2008, at 9:33 AM, Adam Penny wrote: Having constructed a preference subclass with the appropiate outlets corresponding to those I've placed in the nib file, I'm getting an NSObject and setting it's class to the preference pane subclass with my outlets in it, but this seems to be giving me an unexpected choice of outlets when I'm trying to connect them. I was hoping to see the outlets broadcastIP, printers and servers. Instead I see _FirstKeyView, _InitialKeyView, _LastKeyView window and New Referencing Outlet. Am I supposed to use something other than an NSObject when it's a preference pane in order to make connections? Have you tried manually loading the header into IB by dragging the file onto the nib window? IB is supposed to automatically loads headers, but sometimes it doesn't. Nick Zitzmann <http://www.chronosnet.com/> ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Pointing in the right direction for an XCode 3 pref pane.
On Oct20, 2008, at 10:55 AM, Adam Penny wrote: Hi again, Sorry, in my naivité I had expected the drag and drop to do more, but having just created a new NSObject in IB and pointed at the wopolpref class I now discover that it dragging and dropping has done the trick. Thank you very much! Adam On Oct20, 2008, at 1:59 AM, Nick Zitzmann wrote: On Oct 19, 2008, at 9:33 AM, Adam Penny wrote: Having constructed a preference subclass with the appropiate outlets corresponding to those I've placed in the nib file, I'm getting an NSObject and setting it's class to the preference pane subclass with my outlets in it, but this seems to be giving me an unexpected choice of outlets when I'm trying to connect them. I was hoping to see the outlets broadcastIP, printers and servers. Instead I see _FirstKeyView, _InitialKeyView, _LastKeyView window and New Referencing Outlet. Am I supposed to use something other than an NSObject when it's a preference pane in order to make connections? Have you tried manually loading the header into IB by dragging the file onto the nib window? IB is supposed to automatically loads headers, but sometimes it doesn't. Nick Zitzmann <http://www.chronosnet.com/> Hi again everyone, Having made a bit of progress, I thought I'd go back and read the document at http://developer.apple.com/documentation/UserExperience/Conceptual/PreferencePanes/Tasks/Creation.html#/ /apple_ref/doc/uid/2709 carefully to make sure I'm dotting the i's and crossing the t's as far as structure and strategy is concerned. Wrt the above document I have a few things that I'd be grateful if somebody could clarify for me? The document mentions: 6)'In the Classes pane, select the NSPreferencePane class and create a subclass of it. Rename it to whatever you want. This is a global property within the preference application, so include a unique prefix in the name as described in Preventing Name Conflicts.' So in this case the class should be called UkCoPennynetWopolController? It went to say that you could have an extra header file with something like this in it to save a bit of time: #define SoundPref ComApplePreferenceSoundPref #define AlertController ComApplePreferenceSoundAlertController #define MicrophoneController ComApplePreferenceSoundMicrophoneController so presumably I should write for the above. #define WopolController UkCoPennynetWopolController and then refer to it in my code just as WopolController. Just to check, but does that extra definitions header need any frameworks imported into it, or the #define statements only? My final query is simply that I'm not sure what class to use for reading and writing the plist corresponding to my string and two dicts to and from /Library/Preferences/uk.co.pennynet.wopol.plist? I was going to use PropertyListSerialization, but scouting around I got the impression that this is a bit of a faux pas. Then I saw NSUserDefaults, which seems good, but not quite right either. So I'm a bit stuck on that bit. Thank you again. Adam ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
- (id)initWithBundle:(NSBundle *)bundle
Hi there, In a preference pane subclass, should the above method be treated as a replacement for the init method used in normal app controllers i.e. allocating any other objects that might be needed in the controller? Thanks, Adam ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Debugging preference pane
Hi there, Apparently I need to add System Preferences as an executable to my xcode project in order to debug my build. Can anyone tell me how to do this in XCode 3 please? I'll be debugging from ~/Library/ PreferencePanes/ Thanks, Adam ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Debugging preference pane
Thank you for that Nick, I now at least know my error message, although I am struggling to figure out what's wrong. And sorry about the wrong list, I'll bear that in mind in future. This is the my console message when the panel hangs: System Preferences[372:10b] [ valueForUndefinedKey:]: this class is not key value coding-compliant for the key host. I'm just baffled as as far as I can see I've mirrored the technique for bindings that worked when I did the bindings exercise in Hillegass' book for an NSTableView and an NSArrayController. Thank you all. Adam #import "printer.h" @implementation ADPPrinter - (id)init { [super init]; name = @"New Printer's Name"; server = @"ServerName.domain"; uri = @"URI to printer"; return self; } - (void)dealloc { [name release]; [server release]; [uri release]; [super dealloc]; } @synthesize name; @synthesize server; @synthesize uri; @end This is the class that it's talking about, which is the model class for an NSArrayController. On Oct23, 2008, at 9:52 PM, Nick Zitzmann wrote: On Oct 23, 2008, at 1:38 PM, Adam Penny wrote: Apparently I need to add System Preferences as an executable to my xcode project in order to debug my build. Can anyone tell me how to do this in XCode 3 please? I'll be debugging from ~/Library/ PreferencePanes/ This is more of a question for the xcode-users list, but the way I add custom executables is to go to the project's Targets tab[1], then choose Add -> New Custom Executable... in the contextual menu. Nick Zitzmann <http://www.chronosnet.com/> [1] if you're using the condensed view, if not, then just locate the executables in the project list ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Debugging preference pane
Nope, I've triple checked the bindings and they're fine, but I do have two table views in two different tab views in my prefpane window, could that be causing some issues with their respective array controllers getting mixed up? Adam ADPServer has the keys name mac ADPPrinter has the keys name host uri On Oct23, 2008, at 10:49 PM, Nick Zitzmann wrote: On Oct 23, 2008, at 2:36 PM, Adam Penny wrote: This is the my console message when the panel hangs: System Preferences[372:10b] [ valueForUndefinedKey:]: this class is not key value coding- compliant for the key host. That means something's trying to access the key "host", and the ADPPrinter class is not defining that key. So either you need to provide that key, or if this is in error, find out what's trying to access that key and get rid of it. Also, I strongly recommend setting a global breakpoint on objc_exception_throw[1]. Nick Zitzmann <http://www.chronosnet.com/> [1] assuming you're using Leopard or later; if not, then set a breakpoint on -[NSException raise] ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Debugging preference pane
Oh good grief, thank you very much. Right that problems fixed, but now I have this error when the pane first loads. Sorry, to keep asking what I imagine are pretty basic questions. I've been trying to get clues online, but to no avail. This is my error message: 2008-10-24 00:30:44.604 System Preferences[1164:10b] Tried to set an object of class NSCFArray for filter predicate of a controller [object class: printer, number of selected objects: 0] 2008-10-24 00:30:47.855 System Preferences[1164:10b] [NSPrefPaneBundle instantiatePrefPaneObject] (/Users/adam/Library/PreferencePanes/ Wopol.prefPane): should only be called once Here's my WopolPref.m file at the moment. #import "WopolPref.h" @implementation WopolPref - (id)initWithBundle:(NSBundle *)bundle { if (![super initWithBundle:bundle]) return nil; appID = CFSTR("uk.co.pennynet.Wopol"); servers=[[NSMutableArray alloc] init]; printers=[[NSMutableArray alloc] init]; broadcastIP= @"255.255.255.255"; return self; } - (void) mainViewDidLoad { CFPropertyListRef value; /*Initialise the broadcastIP textfield*/ value=CFPreferencesCopyAppValue( CFSTR("broadcastIP"), appID); if (value && CFGetTypeID(value) == CFStringGetTypeID()) [broadcastIP setStringValue:(NSString *)value]; else [broadcastIP setStringValue:(NSString *)@"255.255.255.255"]; /*Initialise the printers array*/ /*Initialise the servers array*/ /*release the value*/ if (value) CFRelease(value); } - (void) setPrinters:(NSMutableArray *)a; { //Method for adding a new printer, with connected server and printer URI to the printers dict if (a==printers) return; [a retain]; [printers release]; printers = a; } - (void) setServers:(NSMutableArray *)a; { //Method for adding a new server, with mac address to the servers dict if (a==servers) return; [a retain]; [servers release]; servers = a; } @end [NSPrefPaneBundle instantiatePrefPaneObject] 2008-10-24 00:30:44.604 System Preferences[1164:10b] Tried to set an object of class NSCFArray for filter predicate of a controller [object class: printer, number of selected objects: 0] 2008-10-24 00:30:47.855 System Preferences[1164:10b] [NSPrefPaneBundle instantiatePrefPaneObject] (/Users/adam/Library/PreferencePanes/ Wopol.prefPane): should only be called once On Oct23, 2008, at 11:18 PM, glenn andreas wrote: On Oct 23, 2008, at 4:10 PM, Adam Penny wrote: Nope, I've triple checked the bindings and they're fine, but I do have two table views in two different tab views in my prefpane window, could that be causing some issues with their respective array controllers getting mixed up? Adam ADPServer has the keys name mac ADPPrinter has the keys name host uri The source code you showed us had: @implementation ADPPrinter ... @synthesize name; @synthesize server; @synthesize uri; @end Note that the source says "server" and not "host" (which is what the runtime is looking for) Glenn Andreas [EMAIL PROTECTED] <http://www.gandreas.com/> wicked fun! Cardographer | the custom playing card designer ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Debugging preference pane
Hi Nick, hi Glen, Just a quick note to say that I've finally cracked the problem and thank you both very much for your help. For that last bit, I was binding my array to the filter predicate (no idea what it is)of the array controller where I should have been binding to the content array. Thanks again, Adam On Oct23, 2008, at 11:18 PM, glenn andreas wrote: On Oct 23, 2008, at 4:10 PM, Adam Penny wrote: Nope, I've triple checked the bindings and they're fine, but I do have two table views in two different tab views in my prefpane window, could that be causing some issues with their respective array controllers getting mixed up? Adam ADPServer has the keys name mac ADPPrinter has the keys name host uri The source code you showed us had: @implementation ADPPrinter ... @synthesize name; @synthesize server; @synthesize uri; @end Note that the source says "server" and not "host" (which is what the runtime is looking for) Glenn Andreas [EMAIL PROTECTED] <http://www.gandreas.com/> wicked fun! Cardographer | the custom playing card designer ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
CFPreferences and init.
Hi there, It's been a few days, actually been able to make some progress on my own for a change! I've set up my initWithBundle method like this: - (id)initWithBundle:(NSBundle *)bundle { if (![super initWithBundle:bundle]) return nil; appID = CFSTR("uk.co.pennynet.Wopol"); servers= (NSMutableArray *) CFPreferencesCopyAppValue( CFSTR("servers"), appID); printers= (NSMutableArray *) CFPreferencesCopyAppValue( CFSTR("printers"), appID); broadcastIP= @"255.255.255.255"; return self; } Happily, it's getting my preferences as expected and the bindings are filling them in in my table. However, I was a bit concerned because if it can't find the servers or printers keys in the plist then my NSMutableArray servers and printers won't be allocated and initialized and it'll knacker everything else up. I was thinking of doing something like this: servers=[[NSMutableArray alloc]init]; if ('servers' key is in the plist and it's an array) { NSArray *serversInPlist=(NSArray *) CFPreferencesCopyAppValue( CFSTR("servers"), appID); [servers addObjectsFromArray: serversInPlist]; [serversInPlist release]; } My question is how do I do the checks for the if clause? Thanks, Adam ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: CFPreferences and init.
Hi there, Thanks for your response Kyle. Based on that I did this in my -(id)initWithBundle method and tested it with and without a PList in the right place and it works: servers= [[NSMutableArray alloc] init]; CFPropertyListRef serversFromPlist=CFPreferencesCopyAppValue( CFSTR("servers"), appID); if (serversFromPlist && CFGetTypeID(serversFromPlist)==CFArrayGetTypeID()) { [servers addObjectsFromArray: serversFromPlist]; // Get warning here: passing argument 1 of addObjectsFromArray ignores qualifiers from target } printers= (NSMutableArray *) CFPreferencesCopyAppValue( CFSTR("printers"), appID); I think that the if clause protects the program from getting the wrong pointer types, but I don't feel right about letting this ride with a warning in it. Opinions? Thanks, Adam On Oct26, 2008, at 12:39 AM, Kyle Sluder wrote: On Sat, Oct 25, 2008 at 6:11 PM, Adam Penny <[EMAIL PROTECTED]> wrote: My question is how do I do the checks for the if clause? The documentation says that if the key doesn't exist, the function returns NULL. So then you just check to see if your servers variable is null. The documentation also mentions using CFGetTypeID to determine if a CFPropertyListRef is an array or some other type. And NSMutableArray is toll-free bridged to CFMutableArrayRef. So: servers = CFPreferencesCopyAppValue( CFSTR("servers"), appID); if(servers && CFGetTypeID(servers) == CFArrayGetTypeID()) { // woohoo! } --Kyle Sluder ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: CFPreferences and init.
On Oct26, 2008, at 1:12 PM, Jean-Daniel Dupas wrote: Le 26 oct. 08 à 13:02, Adam Penny a écrit : Hi there, Thanks for your response Kyle. Based on that I did this in my -(id)initWithBundle method and tested it with and without a PList in the right place and it works: servers= [[NSMutableArray alloc] init]; CFPropertyListRef serversFromPlist=CFPreferencesCopyAppValue( CFSTR("servers"), appID); if (serversFromPlist && CFGetTypeID(serversFromPlist)==CFArrayGetTypeID()) { [servers addObjectsFromArray: serversFromPlist]; // Get warning here: passing argument 1 of addObjectsFromArray ignores qualifiers from target } printers= (NSMutableArray *) CFPreferencesCopyAppValue( CFSTR("printers"), appID); I think that the if clause protects the program from getting the wrong pointer types, but I don't feel right about letting this ride with a warning in it. Opinions? So, tell the compiler that this is an NSArray: [servers addObjectsFromArray: (NSArray *)serversFromPlist]; Ah, thank you! Adam ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: CFPreferences and init.
Hello again, I was just trying to update the plist with CFPreferencesAppSynchronize(appID), where appID = CFSTR("uk.co.pennynet.Wopol") eventhoughthe CFPreferencesSetAppValue is definitely working. Currently my plist is in ~/Library/Preferences/ uk.co.pennynet.Wopol.plist and the control panel is in ~/Library/ PreferencePanes so I didn't think admin rights would be an issue, but I'm starting to think I haven't grasped something (again). How do I do this correctly? Thanks, Adam On Oct26, 2008, at 1:14 PM, Adam Penny wrote: On Oct26, 2008, at 1:12 PM, Jean-Daniel Dupas wrote: Le 26 oct. 08 à 13:02, Adam Penny a écrit : Hi there, Thanks for your response Kyle. Based on that I did this in my -(id)initWithBundle method and tested it with and without a PList in the right place and it works: servers= [[NSMutableArray alloc] init]; CFPropertyListRef serversFromPlist=CFPreferencesCopyAppValue( CFSTR("servers"), appID); if (serversFromPlist && CFGetTypeID(serversFromPlist)==CFArrayGetTypeID()) { [servers addObjectsFromArray: serversFromPlist]; // Get warning here: passing argument 1 of addObjectsFromArray ignores qualifiers from target } printers= (NSMutableArray *) CFPreferencesCopyAppValue( CFSTR("printers"), appID); I think that the if clause protects the program from getting the wrong pointer types, but I don't feel right about letting this ride with a warning in it. Opinions? So, tell the compiler that this is an NSArray: [servers addObjectsFromArray: (NSArray *)serversFromPlist]; Ah, thank you! Adam ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/adam%40pennynet.co.uk This email sent to [EMAIL PROTECTED] ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: CFPreferences and init.
Hi again, I got the CFPreferences synchronize app working but, I'm now having issues with CFPreferencesSetApp value for an array. This is my code for the method in question and it's used for the NSTableView bindings: - (void) setServers:(NSMutableArray *)a; { //Method for adding a new server, with mac address to the servers array if (a==servers) return; [a retain]; [servers release]; servers = a; NSArray *serversToCopy = [servers copy]; //Next line causes an exception when adding a row. if ([servers count]!=0) CFPreferencesSetAppValue(CFSTR("servers"), (NSArray *)serversToCopy, appID); else CFPreferencesSetAppValue(CFSTR("servers"), NULL, appID); else NSLog(@"It's zero!"); [self updatePrefs]; } It's building fine, but when I ran it I found that when I remove a row from the table then it will remove the row from the plist happily and without fuss. However, if I try to add a new row then I get an exception, EXC_BAD_EXCESS. I thought that maybe it was something to do with special characters in my array, but I tried removing them from the default values and no joy. The other thing that's confusing me is that what was an XML Plist that I did by hand like this: servers sname PennyG5.local mac 00:00:00:00:00:00 etc... has been transformed by the synchronization to this(!): bplist00Ó[broadcastIPWserversXprinters]192.168.1.254¡Ò TnameSmac^PennyMBP.local_00:1b:63:c4:aa:1c¢ Ó VserverSuri_&Brother_HL_1650_1670N_series___PennyG5_Gmdns://Brother %20HL-1650_1670N%20series%20%40%20PennyG5._ipp._tcp.localÓ _EPSON_AL_C900___PennyG5]PennyG5.local_6mdns://EPSON%20AL- C900%20%40%20PennyG5._ipp._tcp.local#,: I keep on rereading the documentation and scouting around for examples, but this class really is getting the better of me. Help! Adam On Oct26, 2008, at 1:12 PM, Jean-Daniel Dupas wrote: Le 26 oct. 08 à 13:02, Adam Penny a écrit : Hi there, Thanks for your response Kyle. Based on that I did this in my -(id)initWithBundle method and tested it with and without a PList in the right place and it works: servers= [[NSMutableArray alloc] init]; CFPropertyListRef serversFromPlist=CFPreferencesCopyAppValue( CFSTR("servers"), appID); if (serversFromPlist && CFGetTypeID(serversFromPlist)==CFArrayGetTypeID()) { [servers addObjectsFromArray: serversFromPlist]; // Get warning here: passing argument 1 of addObjectsFromArray ignores qualifiers from target } printers= (NSMutableArray *) CFPreferencesCopyAppValue( CFSTR("printers"), appID); I think that the if clause protects the program from getting the wrong pointer types, but I don't feel right about letting this ride with a warning in it. Opinions? So, tell the compiler that this is an NSArray: [servers addObjectsFromArray: (NSArray *)serversFromPlist]; Ah, thank you! Adam ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/adam %40pennynet.co.uk This email sent to [EMAIL PROTECTED] ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/adam%40pennynet.co.uk This email sent to [EMAIL PROTECTED] ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: CFPreferences and init.
On Oct26, 2008, at 10:40 PM, Kyle Sluder wrote: On Sun, Oct 26, 2008 at 4:12 PM, Adam Penny <[EMAIL PROTECTED]> wrote: This is my code for the method in question and it's used for the NSTableView bindings: Your code is rather disorganized. Particularly, your use of else clauses is confusing and prone to introducing logic errors. - (void) setServers:(NSMutableArray *)a; The Objective-C parser will allow you to have a semicolon at the end of a method implementation declaration spec. Don't do it, it's confusing. I'm also pretty sure that this behavior isn't documented anywhere. Also, you should be asking for an NSArray, not an NSMutableArray. By asking for an NSMutableArray, you are implicitly telling the caller that they may change the contents of the array from underneath you at any time. In a to-many relationship like this, it is almost guaranteed that this behavior is not what you want. I can see from the code you've written that having a mutable array is uneccesary. I get the gist the assertion you make, but I think I'd probably need to see an example to understand that properly, but as my head is spinning with what I'm doing already I'll just bow to your superior knowledge for the moment and avoid mutable arrays! { //Method for adding a new server, with mac address to the servers array if (a==servers) return; You don't want to do this. What are the odds that the NSArray object your caller is providing is the exact same instance as the one you already have? Just leave the condition out; it will never execute in practice anyway. [a retain]; [servers release]; servers = a; Instead of just assigning a to your ivar, use [a copy]. This goes in hand with the recommendation about the argument type above. You probably don't want to store an NSMutableArray, and if the caller has provided you an NSMutableArray, which is fine since the method just asks for an NSArray, you don't want the caller to mutate the collection your object is supposed to be tracking. If you really, *really* need your ivar to be mutable, use -mutableCopy instead of -copy. NSArray *serversToCopy = [servers copy]; This line is obsoleted if you follow my recommendation above. //Next line causes an exception when adding a row. if ([servers count]!=0) CFPreferencesSetAppValue(CFSTR("servers"), (NSArray *)serversToCopy, appID); else CFPreferencesSetAppValue(CFSTR("servers"), NULL, appID); else NSLog(@"It's zero!"); I don't know how this code can compile; that second else clause doesn't match up with any if statement. Is one of them commented out in your code? You're right, that doesn't compile at all, before I'd emailed I'd been trying some things in NSLog to see where things were going wrong, just hadn't deleted the old NSLog statement. Apologies for that. Where is appID coming from? Is it a constant NSString somewhere, like it should be? So here's how I'd rewrite your method (warning, code written in the compose window, YMMV): [snip] @end From what I had read on the web about the exception I was getting I had a feeling that it might be something to do with my memory management. There's some great tips in that code you wrote, thank you very much for taking the time to put it together, it's very much appreciated. I will sleep on it and try it out in the morning. The other thing that's confusing me is that what was an XML Plist that I did by hand like this: [...snip...] has been transformed by the synchronization to this(!): That's the binary plist representation. This will be transparent to well-behaved applications. Naughty ones will try to read the raw XML plist representation and fail, but ones that use the plist serialization API won't know the difference. So from that, do I gather that the binary is the preferred standard for plists? I'll probably show myself up to be barmy with my next revelation, but this preference panel actually started off to set the preferences for an automatically triggered Ruby command line script that I wrote for waking up hosts that share printers automatically when a print job is sent to the printer in question. I built that to read its preferences from an apple XML type plist file. At a future date, I'd like to rewrite that as an objective-c command line utility, but for the moment Is there any way I can coerce CFPreferences to synchronize as XML rather than binary? As the script will be the only thing referring to the plist for the moment I'm not too worried about other 'naughty' applications! :-) Take care, Adam ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests o
Re: CFPreferences and init.
On Oct27, 2008, at 12:46 AM, Adam R. Maxwell wrote: On Oct 26, 2008, at 4:23 PM, Adam Penny wrote: That's the binary plist representation. This will be transparent to well-behaved applications. Naughty ones will try to read the raw XML plist representation and fail, but ones that use the plist serialization API won't know the difference. So from that, do I gather that the binary is the preferred standard for plists? Presently it appears to be, but Apple has changed that in the past, so don't rely on it... I'll probably show myself up to be barmy with my next revelation, but this preference panel actually started off to set the preferences for an automatically triggered Ruby command line script that I wrote for waking up hosts that share printers automatically when a print job is sent to the printer in question. I built that to read its preferences from an apple XML type plist file. At a future date, I'd like to rewrite that as an objective-c command line utility, but for the moment Is there any way I can coerce CFPreferences to synchronize as XML rather than binary? As the script will be the only thing referring to the plist for the moment I'm not too worried about other 'naughty' applications! :-) A couple of suggestions that you may not have considered: 1) if you use /usr/bin/defaults in your Ruby script, you can read/ write the preference file and ignore the plist format. Wow, I've just had a quick glance at this and I really wish I'd come across this before. This looks like I could do the Ruby plist reading 10 times more easily than the way I'm doing it now. Thank you for the suggestion. 2) avoid the preference system entirely by writing your plist somewhere else, such as the Library/Application Support hierarchy. You can then read/write the plist using NSPropertyListSerialization, which allows you to specify XML format. Your first revelation has persuaded me to keep going with CFPreferences and as from what I've read and what Kyle and yourself have said my error probably means that I'm creating a zombie somewhere in the CFPreferencesSetAppValue for the array. Time to read that documents on accessor methods. Thank you again. Adam hth, Adam ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
CFPreferences and init: a possible reason?
Forgive me if I'm sounding like a broken record, but after a day experimenting with different approaches based on ideas that came up yesterday, I'm pretty confident that everything is sound as far as my controller class is concerned. I've been mulling this problem over and wanted to put my hypothesis forward for consideration by anyone with more experience, which is probably everyone else on this list. I am able to write The contents of my one NSTextField to the plist with CFPreferencesSetAppValue, it's writing the two arrays that is the sticking point. When I try to do CFPreferencesSetAppValue for the array(s) I get an EXC_BAD_ACCESS raised by the debugger. I got to wondering whether my problem might have something to do with the content of the array rather than the array itself. My NSArrayController is bound to a class Servers that initialises two NSStrings: name and mac which are inserted into the new index in the NSMutableArray and these are bound to the two columns of my NSTableView. I was just wondering whether my controller class necessarily knows anything about the two NSStrings in each row of the array, since it's the array controller that deals with formatting the rows for display in the NSTableView? Could not having the contents of the array declared in the preference controller itself be what's upsetting CFPreferences when I try to write the array? Just as a reminder here's my WopolPrefs.m as it stands now along with the server class. I'm not bothering to put the printers class as it's much the same principle as the server class anyway. I've put them at the end of the email as you've probably seen variations on it far too many times by now. The code isn't very tidy at the moment as I've been experimenting a lot, but it all works save the aforementioned issues. Thanks again, Adam ***Beginning of code** #import "WopolPref.h" @implementation WopolPref - (id)initWithBundle:(NSBundle *)bundle { if (![super initWithBundle:bundle]) return nil; appID = CFSTR("uk.co.pennynet.Wopol"); CFPropertyListRef serversFromPlist=CFPreferencesCopyAppValue( CFSTR("servers"), appID); if (serversFromPlist && CFGetTypeID(serversFromPlist)==CFArrayGetTypeID()) { servers=[[NSMutableArray alloc]initWithArray: (NSArray *)serversFromPlist]; CFRelease(serversFromPlist); } else servers= [[NSMutableArray alloc] init]; CFPropertyListRef printersFromPlist= CFPreferencesCopyAppValue( CFSTR("printers"), appID); if (printersFromPlist && CFGetTypeID(printersFromPlist)==CFArrayGetTypeID()) { printers=[[NSMutableArray alloc]initWithArray: (NSArray *)printersFromPlist]; CFRelease(printersFromPlist); } else printers= [[NSMutableArray alloc] init]; broadcastIP= @"255.255.255.255"; return self; } - (void) mainViewDidLoad { CFPropertyListRef value; /*Get value for the broadcastIP textfield*/ value=CFPreferencesCopyAppValue( CFSTR("broadcastIP"), appID); if (value && CFGetTypeID(value) == CFStringGetTypeID()) [broadcastIP setStringValue:(NSString *)value]; else [broadcastIP setStringValue:(NSString *)@"255.255.255.255"]; /*release the value*/ if (value) CFRelease(value); } - (void) setPrinters:(NSMutableArray *)newPrinters { //Not relevant } - (void) setServers:(NSMutableArray *)newServers; { //Method for adding a new server, with mac address to the servers dict if (newServers==servers) return; [newServers retain]; [servers release]; servers=newServers; /*if([servers count]!=0) CFPreferencesSetAppValue(CFSTR("servers"), (NSArray *)servers, appID); else CFPreferencesSetAppValue(CFSTR("servers"), NULL, appID); [self updatePrefs];*/ } - (void) updatePrefs; { CFPreferencesAppSynchronize(appID); } - (void)controlTextDidEndEditing: (NSNotification *)aNotification; { NSLog(@"TextField changed"); /* CFPreferencesSetAppValue(CFSTR("broadcastIP"), (NSString *) [broadcastIP stringValue], appID); [self updatePrefs];*/ } - (void)dealloc { [printers release]; [servers release]; [super dealloc]; } - (IBAction) toPlist:(id)sender { NSLog(@"Trying to write to Plist"); NSArray *serversToWrite=[[NSArray alloc]initWithArray:servers]; if([serversToWrite count]!=0) CFPreferencesSetAppValue(CFSTR("servers"), (NSArray *)serversToWrite, appID); else CFPreferencesSetAppValue(CFSTR("servers"), NULL, appID); [self updatePrefs]; [serversToWrite release]; NSLog(@"PList saved"); } @end end of code * The class that I mentioned that is bound to the servers array controller is: ***beginning of code //The .h: #import @interface Server : NSObject { NSString *n
How do I call a function when my preference pane bundle closes?
Hi there, I want to save preferences when the user either closes the preference pane window, clicks the show all button or quits system preferences. Can I just put the method call in the -(void)dealloc or is this a bad idea? Thanks, Adam ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: How do I call a function when my preference pane bundle closes?
Thank you Jamie and Jason. Jamie's email has just panicked me as I've been using CFPreferences rather than NSUserDefaults. It's a system preference pane and I understood that CFPreferences was the way to do this. The documents for CFPreferences kept on saying not to synchronize regularly, so I thought that when synching when the window closed would be a good option. That said, if I'm on the wrong track I can always change my strategy if there's a better way I missed? Adam On Oct29, 2008, at 5:38 PM, Jason Coco wrote: On Oct 29, 2008, at 12:22 , Adam Penny wrote: Hi there, I want to save preferences when the user either closes the preference pane window, clicks the show all button or quits system preferences. Can I just put the method call in the -(void)dealloc or is this a bad idea? This is a bad idea. -(void)dealloc may never be called. You should do this in your pref pane subclass in the -(void)didUnselect or - (void)willUnselect functions. J ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Number in NSString to int.
Hi there, I'm trying to process a MAC Address into Hex so I was going to do something like. NSArray *macArray=[[NSArray alloc] init]; macArray=[mac componentsSeparatedByString:@":"]; for (int i=0; i < [macArray count] ; i++) { //somehow need to get an int called dec from the number in the NSString then... NSString *hex=stringWithFormat:@"%x",dec; [macArray[i] autorelease]; macArray[i]=hex; } My main question is how to get an int from an NSString, but also, if you could have a look at the rest of the contents of the for loop I'd be grateful as I'm sure I'm making a pigs ear of the memory management there. Sort of had a feeling that it would be autorelease as I thought that the substrings in the array would be the responsibility of the array rather than me, but other than that I was a bit boggled. Thank you all. Adam ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Use PPPOE to load net
Actually, I just tried the link I mentioned and it didn't work. There's an example of how to do exactly what you want on this page though. http://developer.apple.com/releasenotes/AppleScript/RN-AppleScript/index.html Ad On Nov4, 2008, at 1:28 PM, Adam Penny wrote: Hey there, I get the impression that what he means is that he has an ADSL set up where you have to dial a PPPoE connection from the computer as opposed to an always on ADSL connection provided by a router. It looks like this has already been done with Applescript by someone else, which you can find here. http://mac.softlookup.com/download.asp?id=150480 If you really want to do it yourself though, I'd say using Applescript to talk to Network preferences is probably your best bet. Good luck, Adam On Nov4, 2008, at 11:53 AM, Uli Kusterer wrote: On 04.11.2008, at 03:04, Xianyu_Ge wrote: I am a beginner of cocoa program, I want to write an project that use PPPOE to automatic loading net, I don't know how to do it, can give me some help or sample, thank you very much. I don't quite understand what you are trying to achieve here ... ? There should be no need to 'load the net' or mess with 'PPPoE'. If you do any net access (e.g. using NSURL and NSURLRequest, or use sockets or whatever) the internet connection will automatically be established. Or is there something else you are trying to do? Can you provide more information? 'load the internet' really doesn't make sense. Are you trying to manually establish a special kind of TCP connection that MacOS doesn't support yet? Are you trying to DOWNload or UPload files from or to a particular server? Are you trying to display web pages ... ? 'load the internet' is really a tad too vague. Cheers, -- Uli Kusterer "The Witnesses of TeachText are everywhere..." http://www.zathras.de ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/adam %40pennynet.co.uk This email sent to [EMAIL PROTECTED] ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/adam%40pennynet.co.uk This email sent to [EMAIL PROTECTED] ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: Use PPPOE to load net
Hey there, I get the impression that what he means is that he has an ADSL set up where you have to dial a PPPoE connection from the computer as opposed to an always on ADSL connection provided by a router. It looks like this has already been done with Applescript by someone else, which you can find here. http://mac.softlookup.com/download.asp?id=150480 If you really want to do it yourself though, I'd say using Applescript to talk to Network preferences is probably your best bet. Good luck, Adam On Nov4, 2008, at 11:53 AM, Uli Kusterer wrote: On 04.11.2008, at 03:04, Xianyu_Ge wrote: I am a beginner of cocoa program, I want to write an project that use PPPOE to automatic loading net, I don't know how to do it, can give me some help or sample, thank you very much. I don't quite understand what you are trying to achieve here ... ? There should be no need to 'load the net' or mess with 'PPPoE'. If you do any net access (e.g. using NSURL and NSURLRequest, or use sockets or whatever) the internet connection will automatically be established. Or is there something else you are trying to do? Can you provide more information? 'load the internet' really doesn't make sense. Are you trying to manually establish a special kind of TCP connection that MacOS doesn't support yet? Are you trying to DOWNload or UPload files from or to a particular server? Are you trying to display web pages ... ? 'load the internet' is really a tad too vague. Cheers, -- Uli Kusterer "The Witnesses of TeachText are everywhere..." http://www.zathras.de ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/adam%40pennynet.co.uk This email sent to [EMAIL PROTECTED] ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]