I posted this in the AppleScript category because it is meant for scripters that don’t use Xcode as well as those who do use Xcode. This pertains to anyone who uses ASObj-C. Posting it in “AppleScript Xcode” would not reach most of the people I am am sending this to. This is a post about getting around Xcode as far as coding goes.
I have been thinking a long time on how to make ASObj-C more accessible to AppleScript users. Xcode itself can build an entire application that can be modified in a delegate. But Xcode is such a pain to work with.
I have two ways in mind. One does not involve Xcode at all and the second involves very little in Xcode and the rest in Script Debugger. For both ways all the scripting (coding) would be done in Script debugger.
I have something working right now for a very small part done in Xcode with the rest Script Debugger. I have included the Xcode project in this post. For this method Xcode is for the most part used to make an Application and the real work goes on inside Script Debugger.
I created a fully functioning text editor that loads, saves and edits rtf files in Xcode. Just to give you an idea how powerful Xcode can be I included all the code used to create the editor in this post. All the code is in the script CustomDocument and all of it is ASObj-C. As you can see it doesn’t take much code. Xcode give default objects and the only coding needed is when you want to change something (what is called over ridding). In this example only 3 things are done. It overrides one thing (windowNibName()) and adds 2 things (on dataOfType:typeName |error|:outError and readFromData:theData ofType:typeName |error|:outError). All the rest of the functionality of the text editor come automatically from Xcode with no programming or scripting.
I should point out the scripter doesn’t have to modify the CustomDocument script object in any way to get things to work. I only show it so you can see how little it takes it create a shell. This means for me it is quicker and easier to create shells. This is all early stuff and I am hoping for feed back from other scripters about what could be done to improve the process. Perhaps even the minimal user connection to Xcode can be eliminated and Xcode can work quietly in the background.
The way I envisioned this working is you go to Xcode open the project file that contains an already complete text editor, open the file to work on in Xcode and then select “open with external editor” and the script will open in “Script Debugger” as long as that is what your default AppleScript browser is set to. Then you work on it in SD, save it (saving it in SD actually save it to the Xcode project) and then go to Xcode and click the run button to see if it works. When it does work you create an application and that’s it.
I have been testing this out for a while and I think it’s ready to use.
The second method involves leaving things not completely done in the Xcode project. The missing pieces would be customized and placed in a file that can be edited in Script Debugger and then connected to to the Xcode project later. I’ve got this to works but problems have come up here and there so it is not ready to show.
But in either case I would make a bunch of different kind os shells and the scripts could fill in what they wanted to. I have working and tested code to dynamically creates the menus for the application without using Xcode. I took over an applet, deleted it menus, create new menus and hook in handlers for the new menu items and this worked with no problem. The code is currently not as user friendly as I would like but after I clean it up a bit I can post it.
I uploaded a zip file called “Other files.zip” This contains 2 files that go inside the Xcode project but can have all the work done on them in Script Debugger. This files CustomDelegate.applescript and CustomDocument.applescript. CustomDocument.applescript doesn’t need to be modified but I put it in the zip archive so you could see what it looked like. I also uploaded a zip file of the entire Xcode project which in this case is very small. CustomDelegate.applescript and the CustomDocument.applescript are the same in both of these archives. Currently CustomDelegate.applescript does not have anything in the the file. But I included a blank file because it will be part later when the app is customized.
I am open to suggestions and advice. I think it’s time that AppleScripters should have access to this more advanced stuff. Apple is never going to make Xcode more accessible for scripters so I thought it was time that AppleScripters made it more accessible.
Bill Kopp
script CustomDocument
property parent : class "NSDocument"
property myTextView : missing value
property attributedStringToLoadIntoTextView : missing value
on init()
continue init()
return me
end init
on windowNibName()
NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
return "CustomDocument"
end windowNibName
on dataOfType:typeName |error|:outError
set theData to missing value
set entireLength to myTextView's |string|'s |length|
set range to (current application's NSMakeRange(0, entireLength))
set theData to myTextView's RTFFromRange:range
set succeeded to (theData is not missing value)
if not succeeded and outError is not missing value then
set contents of outError to current application's NSError's errorWithDomain:(current application's NSCocoaErrorDomain) code:(current application's NSFileWriteUnknownError) userInfo:(missing value)
end if
return theData
end dataOfType:|error|:
on readFromData:theData ofType:typeName |error|:outError
set attributedStringToLoadIntoTextView to current application's NSAttributedString's alloc's initWithRTF:theData documentAttributes:(missing value)
set succeeded to (attributedStringToLoadIntoTextView is not missing value)
if not succeeded and outError is not missing value then
set contents of outError to current application's NSError's errorWithDomain:(current application's NSCocoaErrorDomain) code:(current application's NSFileReadUnknownError) userInfo:(missing value)
end if
return succeeded
end readFromData:ofType:|error|:
on windowControllerDidLoadNib:aController
continue windowControllerDidLoadNib:aController
if attributedStringToLoadIntoTextView is not missing value then
set theTextStorage to myTextView's textStorage
theTextStorage's setAttributedString:attributedStringToLoadIntoTextView
set attributedStringToLoadIntoTextView to missing value
end if
end windowControllerDidLoadNib:
on autosavesInPlace()
return true
end autosavesInPlace
end script
Text editor.zip (40.0 KB)
Other files.zip (2.6 KB)