xcode4 obtaining value of textbox - objective-c

I am creating an applescript application in xcode 4 and am asking for some guidance. I have done a great deal of reading and scouring the internet but cannot find the answer I am looking for. I have a main window with a textbox and a button. I would like to be able to substitute hostname123 for the text in the textbox so that the command is: do shell script "sudo scutil --set HostName" & [Value of Textbox]. I have the button event set up so that the command will be executed on click. Can someone assist in obtaining the value of the textbox so that it can be used in the command?
on ButtonHandlerVolumeSetting0_(sender)
do shell script "sudo scutil --set HostName hostname123"
end ButtonHandlerVolumeSetting0_

First of all, I'm assuming this is in AppleScriptObjC, and not the older AppleScript Studio.
First, you need to make the AppleScript equivalent of an IBOutlet, which is an instance variable (or property) which references the text field and allows the Objective-C code (or AppleScript) to communicate with it. Toward the top of your AppleScript script, add a line like the following:
script MDAppDelegate
property parent : class "NSObject"
property hostNameTextField : missing value -- add this line
You'll then want to Control-drag from the instance of your script in the nib file to the text field in the window to "hook up" this outlet.
[UPDATE]: from the error message you're getting, it sounds like you haven't got this hostNameTextField connection set up properly in the nib file.
The MDAppDelegate blue cube icon in the nib file shown in the image below represents an instance of your AppleScript script that will be created at runtime when that nib file is loaded. You likely have already properly made the "connection" from your button to the blue AppleScript cube, which specifies that when you click the button, it should call the ButtonHandlerVolumeSetting0_() function (aka AppleScript handler). You now need to select your blue AppleScript cube instance like in the image below, and then right-click (or control-click) and drag from the blue cube to your input text field like I've shown.
When you let up on the mouse button, it should show a black popup panel with possible properties you can "hook up" to the text field. Select hostNameTextField.
Afterwards, when you select the blue AppleScript cube, in the Connections inspector in the right utility area, you can see the connections for the AppleScript script. Under Outlets, you'll see the hostNameTextField outlet and under Received Actions, you'll see ButtonHandlerVolumeSetting0_().
While the hostNameTextField property is set to an initial value of missing value in the AppleScript, (the AppleScript equivalent of Objective-C's nil), by making this connection in the nib file, at runtime, the value of hostNameTextField will be set to the NSTextField you specified. This will allow communication between the script and the object hierarchy that was archived into the nib file.
[END OF UPDATE]
An NSTextField inherits a method named stringValue from its superclass NSControl. This method returns the contents of the text field as an NSString (which equates to an AppleScript string). So inside the button click handler, you can get the string value as follows:
on ButtonHandlerVolumeSetting0_(sender)
set hostName to hostNameTextField's stringValue()
do shell script ("/usr/sbin/scutil --set HostName " & hostName) with administrator privileges
end ButtonHandlerVolumeSetting0_
When using do shell script, it's usually best to omit any inclusion of sudo from the script itself and to instead tack on the with administrator privileges qualifier. That signifies to AppleScript that you need to run the script with elevated privileges and it will handle showing the standard authentication dialog.

Related

Can I set a breakpoint condition over entire form?

When running a program I need to see every time a certain button is disabled and step through the code at that point.
If I set a breakpoint with a condition
(ex: only hit when button1.enabled=false) it will only hit in that specific place.
Is it possible to set a breakpoint on the entire program so that i can see when a condition changes across many forms and locations?
You can't set one breakpoint and have it apply to every line of the file, but you can set a breakpoint on the setter of Enabled and then filter it to a specific filter condition. That would give you the desired result. (Note, you might need to turn off "Just my code", see this question for more info)
Set a breakpoint using the "New Breakpoint At Function" as described here, though in Visual Studio 2013, I seem to need to use a slightly different notation:
Then set the breakpoint to funtion:
System.Windows.Forms.Control.Enabled
in C# or for VB.NET:
System.Windows.Forms.Control.set_Enabled(bool)
(You seem to need to use the class that actually defines the property, which in case of the Button class' Enabled property, is the Control class the Button inherits from.
Ignore the warning about it not being able to find the function (it does that for properties somehow), or uncheck the Intellisense lookup.
Now look up the breakpoint in the Breakpoints list and customize the condition so it breaks on the right button
Use the Name property (or any other filter that makes the breakpoint unique) to trigger when you need it to:
When it breaks, it will break in the sources of Control (if you have Framework Source Stepping enabled), which may be confusing. Use the Stack Trace window to find the location where the method was invoked exactly.
Another way of setting the breakpoint is through the Stacktrace window. Set a breakpoint on any line that has your property of interest on it. Launch the debugger and make it break on that line, now use "Step into Specific" to step into the property that you want to break on.
Use the "Stack" window to generate the breakpoint for you:
Since in your case you're looking to break on a function from the Microsoft .NET framework, there is another way. Enabled Framework Source Stepping.
Open the Visual Studio Debugger options and enable "Framework Source Stepping" and disable "Just My Code".
Then enable the Microsoft Symbol Servers in as instructed. Now load up your application under the debugger and wait for the symbol files to be downloaded.
set a break point anywhere in your code that is somehow related to System.Windows.Forms (The constructor of your MainForm for example) and rightclick any function from the "System.Windows.Forms" assembly to load the symbols for that assembly. This will allow you to step into the "Enabled" property and set a break point there.
A full tutorial can be found here:
http://blogs.msdn.com/b/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx

Changing class of object in XCode

I am trying to give an object in the interface builder a custom class. When typing in the class name in the Identity Inspector it automatically finishes the line as its already present in the dropdown list of available classes.
However after entering the class the page comes up with a padlock image and clears the class name.
What is the cause of this and how can I rectify it?
firstly, you must reload xcode
if it not work you must have subclass associate with it in IB
Create CustomClass:UITableViewCell then drop UITableViewCell to IB and then just type the name
If dropdown list not display, reload Xcode
Assuming you've specific the right IB object (e.g., a dynamic cell prototype, whose default class is UITableViewCell) and your custom class is defined correctly (as a subclass of UITableViewCell, itself), then I have a couple of thoughts of what you might try:
Sometimes exiting and restarting Xcode is often enough.
Also try selecting "Clean" from the "Build" menu (or press shift+command ⌘+K).
In the worst case scenario, sometimes you have to exit Xcode and delete the DerivedData folder and then restart Xcode. To find the derived data folder, press command ⌘+, (comma) and go to the last tab, "Locations", and click on the arrow next to the "Derived Data" folder:
Having pulled up that folder in Finder, quit Xcode, delete the contents of that DerivedData folder in Finder (after quitting Xcode), and then restart Xcode and try again.
I think I have found the solution (not sure if I have found a fix for the actual problem or just found a way around it)...
I changed the Lock dropdown setting to Nothing and it now allows me to set my own custom class to the Object in the file.
Whats strange is that the document lock was previously set to Inherit (Nothing) anyway so not sure what the difference is here.

NSToolbar looks different in Leopard and Snow Leopard

I have a Cocoa app I'm working on and I get a different result in appearance for the NSToolbar I am using for the main window.
Specifically, I'm using a search field as the last NSToolbarItem and, whereas under Snow Leopard it is displayed correctly:
it is cut under Leopard:
Looking at those two versions it appears that the spaces I put between the items are not respected under Leopard. I also saw that sometimes, after I make some update at the toolbar in Interface Builder, these changes are not mirrored in the running application even under Snow. I have to drag the default bar from the customizing menu in order to see them.
UPDATE
The reason for the NSToolbar not always mirroring what is in the .nib file resides in the autosave mechanism that was enabled for me, as NSGod suggested.
What can be the cause of this misbehavior?
Is there something about constraints, (minimum and maximum) sizes that I should have taken into account?
Feel free to point some documentation to me
UPDATE 2
Is there a way to programmatically introduce item and spaces into a NSToolbar or check the consistency (at run time) of those entered with Interface Builder?
While I do recall having a couple of oddities with search fields in NSToolbars, I've never seen the behavior where the right side of it is cut off.
Are the NSToolbarItems that are spaces the fixed one-unit space, or the flexible spaces?
"I also saw that sometimes, after I
make some update at the toolbar in
Interface Builder, these changes are
not mirrored in the running
application even under Snow. I have to
drag the default bar from the
customizing menu in order to see them."
You need to keep in mind that if you've enabled user customization and autosave behavior in the toolbar, then when the user explicitly makes a change, it will be saved to user defaults. If you then re-arrange your toolbar in IB and run the app, it's possible that the configuration saved in user defaults is overriding the default configuration you've specified in the nib file.
What I usually do is during testing, delete the prefs file for my app so changes can't be overridden. (FWIW, I usually use an AppleScript saved as an application that I keep in my Dock. It just runs a do shell script command which deletes the prefs file. Being a GUI-oriented type of person, it's easier for me to just click it to have it run right before debugging. This version of the script asks for the prefs file to delete, though it can also be customized: http://www.markdouma.com/developer/DeleteAppPrefs.zip. If you've never run it before, you get the choose file dialog, and the chosen file is saved as an alias inside the actual AppleScript, so you're not asked again. You can drag the icon onto AppleScript Editor to take a look at the script or change it).
Anyway, then, if I'm going to release a new version of an app that uses a new toolbar layout, and want to prevent the config from being overridden, I'll change the toolbar's identifier (or autosave name) to something like "docToolbar2.0".

View variable data while debugging in Objective-C

I come from a .Net world so I'm used to just hovering over a variable while debugging and seeing what its value is.
In Objective-C I am incredibly confused on how to do that.
If I hover over it, I get a small popup with lots of information...that doesn't help me at all.
For example, I have an object called "myServer" and it is an instance of a "Server" that I have created through CoreData. One of its properties is "root" which is a simple NSString.
I cannot for the LIFE of me figure out how to view what the value of [myServer root] is.
Can some please give me some advice on this?
In the gdb console, type
po [myServer root]
I like to use GDB from the command line. Open a terminal and type
gdb
attach <your process name>
(be sure your program was built with debugging symbols). Then, when your variable name is in scope (e.g. when you break somewhere relevant) type
po variableName
to view its contents.
Another nice way to deal with this is to log directly from a breakpoint.
To do this, create a breakpoint after the value you want to see has been set, then edit it. Add a breakpoint action of 'log', and put the expression you want logged within a pair of # symbols. Check the box to the right, ensuring that the breakpoint doesn't actually cause a stop. The value will be output to the debugger console on doing a run & debug.
Doing it this way you (a) don't clutter your source, (b) can dis/enable the breakpoint at will according to your immediate needs, and (c) don't need to stop execution.
This and other very handy xcode tips can be culled from Joar Wingfors' 'Debugging with Xcode' talk.

VB.NET call desktop application from 2 shortcuts - supply different parameters

I have a desktop application which reads files from a specified folder, then deposits the files to a folder in a third party document management system based on criteria that the user provides.
My question is:
is it possible to somehow provide different parameters to the code, depending on which shortcut of the application the user clicked on to start it up?
You can add command line parameters to a shortcut icon. Here's how you can do it in Windows:
On the Start Menu, navigate to Notepad.
Right click on Notepad and choose Send To > Desktop (Create Shortcut)
Right click on the newly-created desktop icon and choose Properties
Add your command line parameters to the Target text box.
For example, if you want notepad to open up the hosts file, this would be the content of Target property:
%SystemRoot%\system32\notepad.exe "C:\WINDOWS\system32\drivers\etc\hosts"
You can put pretty much anything into the Target property of a shortcut that you would put into a command line.
Yes.
The easiest way would be to have the shortcut pass those parameters in via the command line.
You could also use conditional compilation variables, and have 2 different .exes. You should be able to find samples of both approaches (command line and conditional compilation variable) in help.