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.
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)