Thank you, DTS, for your invaluable assistance. I tried to generate and execute an AppleScript directly from the app using NSAppleScript. This script sends Apple Events to a target application (Pages) to modify a document (with and without GUI Scripting). Although Xcode’s console might indicate that the target application isn’t open, it is actually open because non-GUI modifications are still applied correctly.
Here's a generic code:
class GenericAppleScriptRunner {
static func run(script: String) {
if let appleScript = NSAppleScript(source: script) {
var error: NSDictionary?
let output = appleScript.executeAndReturnError(&error)
if let error = error {
print("Error executing AppleScript: \(error)")
} else {
print("AppleScript executed successfully: \(output.stringValue ?? "")")
}
} else {
print("Unable to create NSAppleScript instance.")
}
}
}
let script = """
on robustReplace(theText, searchString, replacementString)
set AppleScript's text item delimiters to searchString
set textItems to every text item of theText
set AppleScript's text item delimiters to replacementString
set newText to textItems as string
set AppleScript's text item delimiters to ""
return newText
end robustReplace
tell application "Pages"
try
set docRef to document "SampleDocument"
on error errDoc
return "Error: " & errDoc
end try
set deletionTags to {"[DELETE_TAG]"}
try
set imagesList to images of docRef
repeat with i from (count of imagesList) to 1 by -1
set img to item i of imagesList
try
set imgDesc to description of img as string
on error
set imgDesc to ""
end try
repeat with tag in deletionTags
if imgDesc contains tag then
delete img
exit repeat
end if
end repeat
end repeat
on error errImages
end try
-- to clean some placeholders
try
set findText to "[FIND_TEXT]"
set replaceText to "[REPLACE_TEXT]"
set bodyText to body text of docRef as string
set newBodyText to my robustReplace(bodyText, findText, replaceText)
set body text of docRef to newBodyText
on error errReplace
end try
activate
end tell
-- Above is processed, below isn't
tell application "System Events"
tell process "Pages"
delay 0.2
keystroke "f" using {command down}
delay 0.2
keystroke "a" using {command down}
-- then follows the process to search & replace with GUI Scripting
end tell
end tell
tell application "Pages"
display dialog "Operation complete" buttons {"OK"} default button "OK"
end tell
"""
GenericAppleScriptRunner.run(script: script)
When I copy the real script to use it directly with ScriptEditor, it does work.
Topic:
App & System Services
SubTopic:
Automation & Scripting
Tags: