Embed a bash shell script in an AppleScriptObjC application with Xcode - xcode

I have attempted to follow the instructions on this post but I am falling short of understanding how some of the posters instructions work.
I want to be able to package the app with a prewritten bash script and then execute it, but don't follow from Step 4 onwards.
Post writes:
4. Also in your AppleScriptObjC script, add the following where appropriate:
property pathToResources : "NSString" -- works if added before script command
5. Where appropriate, also add the following in your AppleScriptObjC script:
set yourScript to pathToResources & "/yourScriptFile.sh"
-- gives the complete unix path
-- if needed, you can convert this to the Apple style path:
set yourScriptPath to (((yourScript as text) as POSIX file) as alias)`
6. As an aside, you could then open the file for read using
tell application "Finder"
open yourScriptPath
end tell
Questions:
Where do I add the line:
property pathToResources : "NSString"
Do I add which of the following, and where?
set yourScript to pathToResources & "/yourScriptFile.sh"
OR
set yourScriptPath to (((yourScript as text) as POSIX file) as alias)
How is it possible to execute the script itself? The mention As an aside, you could then open the file for read using only covers the Apple style path, it does not cover using the aforementioned style.
Can anyone shed a bit more light on this for me, or post a static copy of a AppDelegate.applescript file that shows how the original poster required the base code to be used? I have tried his method and looked across the internet for the past 3 weeks to no avail. I don't want to have to convert all my code for specific tools from bash scripts into AppleScript, as this would take a lot of work.
I only need to know how to reference to the script file (for example myBashScript.sh) in my app, which would reside in the application and be included by Xcode at time of compilation.

I think you should use the command path to resource <specifiedResource>.
See Standard Additions, path to resource.
You could set it by set myVariableName to path to resource "myBashScript.sh" or just use the command instead of your property so it points always to the right place (a user could move your app while running... lol).
ADDITION:
I did it that way in my AppleScript-Application:
on run_scriptfile(this_scriptfile)
try
set the script_file to path to resource this_scriptfile
return (run script script_file)
end try
return false
end run_scriptfile
Whenever I want to run a script that is bundled within my app I do this:
if my run_scriptfile("TestScript.scpt") is false then error number -128
run_scriptfile(this_scriptfile) returns true when everything worked.

I ended up bringing all the information together and now have a solution.
This takes into consideration the following facts:
firstScript = variable name that points to a script called scriptNumberOne.sh
scriptNumberOne.sh = the script that I have embedded into my application to run
ButtonHandlerRunScript_ = the name of the Received Action in Xcode
pathToResources = variable that points to the internal Resources folder of my application, regardless of it's current location
Using this information, below is a copy of a vanilla AppDelegate.applescript in my AppleScriptObjC Xcode project:
script AppDelegate
property parent : class "NSObject"
property pathToResources : "NSString"
on applicationWillFinishLaunching_(aNotification)
set pathToResources to (current application's class "NSBundle"'s mainBundle()'s resourcePath()) as string
end applicationWillFinishLaunching_
on ButtonHandlerRunScript_(sender)
set firstScript to pathToResources & "/scriptNumberOne.sh"
do shell script firstScript
end ButtonHandlerRunScript_
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
return current application's NSTerminateNow
end applicationShouldTerminate_
end script

Related

Change the variable in a workflow from a separate workflow

I have two workflows and I need to pass a value generated in one workflow to another workflow.
In my first workflow, I have an AppleScript which returns a number I want to put into a second workflow which I call from the first workflow like so:
My second workflow (Create Class in iStudiez) has a variable 'Class Number' which I want to change when I call it from my first workflow with the return value of the AppleScript pictured above.
Since you are using Automator and AppleScript in Automator, and you have not posted any actual code, it's difficult to give you an exact answer of what you're looking for.
There may be an easier solution but the solution I came up with was to create one script which will save a variable into a new script file (which will automatically be created on your desktop with the name of “Stored_Variable.scpt”. The second script loads the value of the variable stored in the “Stored_Variable.scpt” file.
Simply paste the code from this first script, directly into the code which contains the variable you want to copy. Be sure to paste the code after the code which sets the value of the variable you want copied.
-- Comment Out This Next Line Before
-- Placing This Code Into Your Script
-- Which Contains The Variable You Want Copied
set originalVariable to (path to desktop) -- Testing Purposes Only
-- Replace "originalVariable" with the
-- Name Of Your Actual Variable You Want To Pass
-- To The Next Script
set saveThisVariable to originalVariable
storeTheVariable()
-- The Following Code Belongs At The Very Bottom Of Your Script
on storeTheVariable()
set storedVariabeFileLocation to (path to desktop as text) & "Stored_Variable.scpt"
----------------------
script theVariable
set saveThisVariable to saveThisVariable
end script
----------------------
store script theVariable in ¬
file storedVariabeFileLocation with replacing
end storeTheVariable
Place this is second code inside the code of your AppleScript in which you are trying to retrieve the variable stored from the first AppleScript code
-- Gets The Variable Which Was Previously Stored
-- From The Other Applescript And Stores It In A
-- New Variable... getVariableNow
set getVariableNow to run loadTheVariable
-- -----------------------------------
-- Place Whatever Commands Here, That You Will Be Using
-- The New Variable... getVariableNow with
-- -----------------------------------
-- The Following Code Belongs At The Very Bottom Of Your Script
script loadTheVariable
property storedVariabeFileLocation : (path to desktop as text) & "Stored_Variable.scpt"
property theRetrievedVariable : missing value
on getStoredVariable()
set theScript to load script file storedVariabeFileLocation
set theRetrievedVariable to saveThisVariable of (theVariable of theScript)
end getStoredVariable
set theRetrievedVariable to loadTheVariable's getStoredVariable()
end script

Reference external script file

I'd like to implement this script (also listed below) as a separate file. How do I formulate the reference to it as a POSIX path?
tell application "ASObjC Runner"
activate
set chooserResult to run the script {chooseFilesOrFolders} with response
-- the above line would have to reference something like RemoteVolume/test.scpt
end tell
The referenced script itself existing as separate file "test.scpt":
script chooseFilesOrFolders
tell current application's NSOpenPanel's openPanel()
setTitle_("Choose Files or Folders") -- window title, default is "Open"
setPrompt_("Choose") -- button name, default is "Open"
setCanChooseFiles_(true)
setCanChooseDirectories_(true)
setAllowsMultipleSelection_(true) -- remove if you only want a single file/folder
get its runModal() as integer -- show the panel
if result is current application's NSFileHandlingPanelCancelButton then error number -128 -- cancelled
return URLs() as list
end tell
end script
You must use the fFinder path for your script test.scpt, and then call the library using "load script file" command:
In your test.scpt file :
On ChooseFilesOrFolders
-- all your script lines here
return URLs() as list -- to send back result of your sub routine
end ChooseFileOrFolders
In your main script :
Set Script_Lib to "HD:Users:me:Desktop:test.scpt" -- the complete path to your text script.
Set My_Lib to (load script file Script_Lib)
-- insert here you main script lines, and when you want to call the function :
tell My_Lib to Set chooserResult to ChooseFilesOrFolders
-- Here, chooserResult will contain the list returned from test script
Also note that your script "test can also contains many other subroutines which can be called as fonctions in your main script.
I hope it helps.

Fixing a filemaker script with Embeded Applescript and Global Field

With a great deal of help from #Chuck I have written this filemaker script which is supposed to find related PDF attachments in container fields and export them to a temporary folder then trigger an applescript which will open & print the documents using adobe acrobat.
Unfortunately the script will not work and although I have used script debugger and tried to follow advice I am still having difficulty. Any assistance in telling me exactly where I'm going wrong would be appreciated.
Go to Related Record [Show only related records; From table: “Attachments”; Using layout: “Attachements Report" (Attachments); New window]
Enter Find Mode []
Constrain Found Set [Restore]
Sort Records [Restore; No dialog]
#
#After finding the related attachments and constraining them to the specific type we rename and export them to the desktop
#
Go to Record/Request/Page [First]
Loop
Set Variable [SPath; Value:"fi|emac:" & Get ( TemporaryPath ) & Attachments::Record number &"-' & Attachment Type List 2::Prefix_z & Lien::Lien_lD_z]
Set Variable [SASPath; Valuei"/' & Substitute( SPath; "filemac:" & Cet( SystemDrive )1 )]
Set Field [Attachments::g_app|escript_parameter; $ASPath]
Export Field Contents [Attachments::file_c; “SPath"]
Perform AppleScript ['set _pdf_path to contents of cell "g_applescript_parameter" of current layout batchprint(_pdf_path) on batchprint(mycurrentfile) tell application ‘Adobe Acrobat Pro" activate —- bring up acrobat open alias mycurrentfile “'_*]
Go to Record/Request/Page [Next; Exit after last]
End Loop
Close Window [Current Window]
Using Script Debugger I get the following errors...
On Script Step, Export Field - Error: “ "(VARIABLE FILE NAME).. could not be created on this disk. use a different name make more room on the disk.
On Perform AppleScript Step: Error: Object not found & Error: Unknown Error: -1728
Is this being executed on the server (via a schedule) or on the client computer?
Have you verified that the directory permissions are actually set correctly in the temporary path?
Have you tried using Get ( DocumentsPath ) instead of the temporary path, just to verify?

what is the correct path to the iMovie Projects folder to use in an AppleScript

I'm working on a simple AppleScript to make a copy of an iMovie project file. I have added this property to the script:
property iMovieProjects : alias (home directory of (system info) as string) & "Movies:iMovie Projects"
This gives me the error
File alias Macintosh HD:Users:my user name:Movies:iMovie Projects of wasn't found
What's the correct path? I tried iMovie Project.localized but that doesn't work either.
Try this, looks like you need to use the Finder. Also i added a little simplification on getting the home path.
property iMovieProjects : ""
tell application "Finder" to set iMovieProjects to alias ((home as string) & "Movies:iMovie Projects")
EDIT: Heres a one line solution that does not use the Finder, based on ideas from mklement0 & regulus6633
property iMovieProjects : alias ((path to movies folder as text) & "iMovie Projects.localized")
It appears this folder is some kind of special bundle type folder and thats why we were needing the finder to parse it correctly. Using its full .localized name resolves it.
UPDATE: As adamh discovered, the reason for the alias error is because the real name of the folder is "iMovie Projects.localized". Get info on the folder and you will see it.
I would add that an easier method to get to a folder is using the "path to" command. Using that you can get to virtually every known folder. In your case we can get directly to the Movies folder. You can look in the applescript dictionary of the standard additions to see all of the folders it knows. As such I would reference that folder as follows.
set iMovieProjects to alias ((path to movies folder as text) & "iMovie Projects.localized:")
Finally you'll notice that I did not use a property for iMovieProjects. That's because when you compile a script a property will hard-code the path into the script... meaning that the script will only work for this particular user. If the script is used by another user it will still point to the Movies folder of the person at compile time. Thus we don't use a property and the script will work for any user.
Good luck.
Update2 (thanks, #adamh): Even though the iMovie projects folder name appears as "iMovie Projects" in Finder in English-language locales, the actual - locale-independent - name is "iMovie Projects.localized". (If you want to refer to the folder by its localized name, prefix the set command with tell application "Finder", as in #adamh's answer's first snippet.)
You simply need to change how you parenthesize - the string to pass to alias must be built in its entirety inside parentheses:
property iMovieProjects : ""
set iMovieProjects to alias ( ¬
(home directory of (system info) as string) & "Movies:iMovie Projects.localized" ¬
)
Update1: #regulus6633 makes the excellent point that you shouldn't initialize a property with a specific user's path, as it will get compiled into the script. Thus, the above snippet initializes the property to an empty string and then assigns a value dynamically - which will then reflect the current user's path - in a separate set ... to statement.
Your original statement inadvertently creates a list with 2 elements, whose first element is a an alias of your home directory and whose second element is the string "Movies:iMovie Projects".
Simplified version with the path to command demonstrated in #regulus6633's answer (the same need to parenthesize applies):
property iMovieProjects : ""
set iMovieProjects to alias ( ¬
(path to movies folder as text) & "iMovie Projects.localized" ¬
)

list subfolders using applescript

This is my first applescript. I thought I'd do something simple like navigating to a folder using a path and listing the subfolders...Unfortunately, I can't figure it out :-)
Here is what I've tried so far:
The first try:
tell application "Finder"
set the_folder to POSIX path of "Users:MyName:Doc"
log the_folder
set folder_list to every item of folder the_folder
log folder_list
end tell
This produces an error:
"Finder got an error: Can't get folder "/Users/MyName/Doc".
Could someone please:
1. Explain to me what I'm doing wrong.
2. Provide an example that works.
Thanks in advance.
btw the folder does exist on my machine...
UPDATE: Oops! It appears that I have given you the wrong information so I will give you the correct information.
The command POSIX path of requires a complete alias reference. By that I mean supplying the full file reference (i.e. <your_disk_name>:Users:<your_user_name>:somefolder:). Make sure that if you're referring to a folder that you end the reference with a colon (i.e. Macintosh HD:Users:). An improved version would look like this:
tell application "Finder"
set the_folder to (POSIX path of ("<your_disk_name>:Users:<your_user_name>:Doc:") as alias) as alias
set folder_list to every item of the_folder
end tell
OPTIONAL
To coerce a POSIX path (i.e. /Users/<your_user_name>/somefolder) back into an alias, two conversions are needed.
Conversion 1: The first step is to convert the reference into a file reference. To do this, place the words as POSIX file after the reference, like so:
"/Users/<your_user_name>/somefolder" as POSIX file
This code procudes a file reference in this form: file "<your_disk_name>:Users:<your_user_name>:somefolder:"
Conversion 2: Add a second coercion, as alias, to the end of the reference...
"/Users/<your_user_name>/somefolder" as POSIX file as alias
This code produces an actual alias reference: alias "<your_disk_name>:Users:<your_user_name>:somefolder:
If you have any questions, just ask. :)
Posix paths are paths you use at the command line and are "/" delimited. Applescript paths are ":" separated so just use those. Try this script to see what the path should look like...
set folderPath to (choose folder) as text

Resources