First, thanks very much for the effort here. After a year of reading Cocoa tutorials, IB tutorials and Xcode 3 Unleashed I was very happy to find a simple guide that was current. Most of the tutorials I’ve found have been based on older versions of Xcode/IB and have been nearly useless.
I just finished going through part one with good results but one thing doesn’t work right. When I run the app, a window named “Window” pops up in front of the “PartOne” window. It’s empty, you cant type anything in it, but you can dismiss it or put it in the background.
Where is this coming from and how can I get rid of it?
I’m running 10.6.2 with Xcode 3.2.1 and IB 3.2.1(740).
Thanks,
Scott.
Model: MacBook Pro Intel Core Duo, Mac Mini Intel Core Duo
AppleScript: 2.3
Browser: Safari 531.21.10
Operating System: Mac OS X (10.6)
I believe that the tutorial assumes you know what cocoa is, what obj-c is, and what all these classes and parents mean. For a little old mac scripter (no pun intended) who just wants to run simple automations and create a GUI to connect his scripts into a nice interface.
All I wanted to do was learn how to take one script I have already made, and put it into this program and connect it to a button in the GUI. I finally figured it out after much puzzeling over what was necessary for this to happen.
AppleScript Studio assumes you are just a simple scripter and want to build a UI for your scripts. You can use it without any help. This new stuff AppleScript Objc assumes you are an XCode developer and you want to help your friends hook up their scripts into an GUI.
Anyway. thanks for the tutorial. But I think it might be appropriate to have smaller more specific tutorials on how to use the simplest most basic program (1 button connected to 1 script and nothing else) and then maybe build your way up as you add more and more controls to the program. Since the first tutorial includes how to use the strings and text areas and spends more time on them then the button (which was an afterthought) it made it difficult to determine exactly what is required to just simply have 1 button trigger to running a script.
A tip to all of you not knowing anything about Objective-C, C, inheritance and Xcode in particular, this is the guide which made me the programmer I’m now:
@fdenger - I have felt the same way on so many occasions when going through a programming book or a tutorial. When things are over your head there can be some anger toward the author because they are not explaining it in a way that you understand.
Things that you might consider about these particular tutorials.
They were not meant to be a comprehensive covering of AppleScriptObjC.
I put them together just weeks after Snow Leopard was released to give others an overview of the new framework because there was relatively no other documentation at that time.
The audience I was targeting was experienced AppleScript Studio users who just needed an overview to get started.
That being said, I want to reiterate that I understand your position. Programming is hard and it doesn’t make it any easier to learn when tutorials expect you to already have a good grasp on things before reading them. You may have better success reading chapter 30 of “Learn AppleScript, The Comprehensive Guide to scripting and Automation on Mac OS X, Third Edition”. I wrote that with a focus on more of a “ground up” approach. There are several example applications built during the chapter and the first one is a dialog attached to a button.
If you have specific questions then please post them to the forum. There are many wonderful people here who really go out of their way to help. And if you are serious about learning AppleScript, the best way is to start answering peoples questions on this forum. Myself and many others learned a lot about programming by doing this very thing.
Thanks for the reply. I was just wanting to post my feedback. I think your tutorial is good I just think if you can’t/don’t have time to wrap your head around objC its difficult to follow along.
I’m working on a little modification to my application now. I want the window to stay on top because its a utility app for users of our database application… Here’s my code (hopefully someone can tell me why it doesn’t work):
on activated_(sender)
tell class "NSWindow" of current application
sender's setLevel(3)
end tell
end activated_
I’m sure its an obvious problem but I read all about how to setLevel in objC and I think i have it in the right place in my main applescript file in my project. I am not getting any errors in the debugger so I am scratching my head…
Ok I did some research and figured out the answer to my question, after much playing around and searching. Here’s a good tutorial on the subject to access the window methods from Applescript ObjC. The basic idea is you need to make a property with a missing value, then connect the window to that property. Once you do that you have an object you can call all the window’s methods from. So for example:
property myWindow : missing value
on setTopLevel_(sender)
myWindow's setLevel(3)
end setTopLevel_
on setNormalLevel_(sender)
myWindow's setLevel(0)
end setNormalLevel_
So now go into IB and control-drag the window’s titlebar to App Delegate and select myWindow to connect to. Then take a button in your window and control-drag it to to the App Delegate and select setTopLevel: to connect to. Then connect another button to setNormalLevel: Then compile and run and you will see that by clicking the buttons you can set the window to “floating” (top) level and the other button sets it back to normal. Note: make sure you put this code inside your AppDelegate script in XCode after the parent property. Otherwise cocoa won’t know what your talking about.
Note that now that you have the window connected to the property “myWindow” you can access any of cocoa’s NSWindow’s methods by calling them like so:
Also as far as the most basic tutorial to just create 1 button in IB and connect it to just 1 function in applescript for the non-cocoa non-C programmer who doesn’t want nor care about C or ObjC or Cocoa, I wrote it down here:
I’ve tried to modify your example such that the “Set Text” button loads an rtf document from a file and displays it in the Text View. Here’s the crux of what I thought was a simple edit to the setTextViewFromTextField subroutine :
on setTextViewFromFile_(sender)
textView's readRTFDFromFile_(choose file with prompt "Select your subtitles file:" of type {"rtf"} without invisibles)
end setTextViewFromFile_
But this is throwing up an error as follows: -[NSButton readRTFDFromFile:]: unrecognized selector sent to instance
Which seems to suggest to my badly out of my depth cocoa-newbieness that textView is thinking it belongs to the NSButton class rather than the NSTextView class … clearly I’ve messed something up. Can you point me in the right direction so I can get where I’m trying to go.
Ultimately I’d like my little test app to read in and display an rtf file, then I would want to parse that file line by line and extract info for font, size and style, and to spit that out as an XML file. So far I have all that working via AppleScripting the TextEdit app (and then programmatically saving that out the parsed file as an XML) but as a next step I’d like to be able to skip the TextEdit step and do it in AppleScriptObjC, including importantly the displaying it part!
Greatly appreciate any help you can offer, especially what the heck is screwy in my logic in the above seemingly oversimplified code
Cheers
Andy
EDIT: So I think I realized the first of my errors above was in not correctly connecting the App Delegate to the NSTextView item in Interface Builder … having connected that up properly (I think) I’m now no longer getting the NSButton readRTFDFromFile:]: unrecognized selector error, but instead am now getting:
-[NSAppleEventDescriptor length]: unrecognized selector sent to instance
Bugger. Out of the frying pan and into the fire :rolleyes:
It depends very much on what you’re doing. For some things, AS will be too slow – but then for some things, Objective-C is too slow and people resort to straight C.
Can you give an example of when to use this Language as opposed to Objective C? I come from the windows world and this seems like what Microsoft did with .NET and CLR.
I prefer the syntax of Applescript because the Objective C syntax is foreign to me (Java/C#).
When should you use Applescript? Is this interpreted? Don’t you get compiled runtimes in the end?
The main use case is when you are using AppleScript already – so generally when you are scripting another app or apps. That’s not to say it can’t be used for stand-alone stuff, but that’s no really what it’s designed for, nor is it ideal for that.
Not really. It’s more about giving scripts that drive other apps access to Cocoa – mainly for UI, but as is the nature of such things, anything else that will help them.
If you know C, Objective-C syntax probably takes half-a-day at most to get the hang of. And you use a similar approach in AppleScriptObjC – the same goes for using the other bridges, for Python, Ruby, etc. Cocoa and Objective-C are closely entwined.
You get a mixture. The AS component is loaded at run-time – it depends very much on the dynamic nature of the Cocoa runtime.
on setTextViewFromTextField_(sender)
set textFieldValue to textField's stringValue()
if textFieldValue is not "" then
textView's setString_(textFieldValue)
beep
end if
end setTextViewFromTextField_
It worked with:
on setTextViewFromTextField_(sender)
set textFieldValue to textField's stringValue()
if textFieldValue's isEqualToString_("") then
else
textView's setString_(textFieldValue)
beep
end if
end setTextViewFromTextField_
but should be a more elegant/correct way to avoid else statement?
My favorite way to determine an empty string is the length method.
There’s no overhead and you can compare directly to an AppleScript integer value
on setTextViewFromTextField_(sender)
set textFieldValue to textField's stringValue()
if textFieldValue's |length|() is not 0 then
textView's setString_(textFieldValue)
beep
end
end setTextViewFromTextField_