We implemented AppIntents using EnumerableEntityQuery and @Dependency and we are receiving these crash reports:
AppIntents/AppDependencyManager.swift:120: Fatal error: AppDependency of type MyDependency.Type was not initialized prior to access. Dependency values can only be accessed inside of the intent perform flow and within types conforming to _SupportsAppDependencies unless the value of the dependency is manually set prior to access.
I can't post the stack because of the Developer Forums sensitive language filter :( but basically it's just a call to suggestedEntities of MyEntityQuery that calls the dependency getter and then it crashes.
My understanding was that when using @Dependency, the execution of the intent, or query of suggestedEntities in this case, would be delayed by the AppIntents framework until the dependency was added to the AppDependencyManager by me. At least that's what's happening in my tests. But in prod I'm having these crashes which I haven't been able to reproduce in dev yet.
Does anyone know if this is a bug or how can this be fixed? As a workaround, I can avoid using @Dependency and AppDependencyManager completely and make sure that all operations are async and delay the execution myself until the dependency is set. But I'd like to know if there's a better solution.
Thanks!
Automation & Scripting
RSS for tagLearn about scripting languages and automation frameworks available on the platform to automate repetitive tasks.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Here's my AppleScript:
tell application "Finder"
activate
open application file "Messages.app" of folder "Applications" of folder "System" of startup disk
end tell
I just need the step to send the message making the script automatically send the message which has already been created. This step opens the completed iMessage ready to send . I want to send it without and keyboard usage. All that is needed is the step to send
Topic:
App & System Services
SubTopic:
Automation & Scripting
Is there a way to create a data roaming or cellular profile or shortcut so that we can turn data off for certain sets of apps when we travel (and turn them all back on when we're back)?
I am developing an app that allows the user to ask it to process the clipboard contents and do something with it.
In developing a XC UI Test, I find the app stops while it waits for the user to give permission. That breaks the automation.
I tried:
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
let allowButton = springboard.buttons["Allow Paste"]
But that does not work. Is there a way to tell the framework to automatically give the test permission to access the Paste clipboard (or to allow me to write tests to grant this)?
Topic:
App & System Services
SubTopic:
Automation & Scripting
Tags:
Xcode
XCTest
Testing
Swift Testing
Hey Swift community!
I'm exploring building a macOS app that needs to monitor what's currently playing in music apps like Spotify and Apple Music (track info, playback position, play/pause state). I'm trying to figure out the most efficient architecture before diving in.
The Goal:
Monitor playback state across multiple music players to react to changes in real-time, ideally with minimal CPU overhead since this would run continuously in the background.
Approaches I'm Considering
AppleScript / ScriptingBridge
Distributed Notifications
Native Frameworks (Apple Music only)
What's the recommended way to do this on macOS?
Are distributed notifications reliable enough to avoid polling entirely?
Is there a performance difference between AppleScript and ScriptingBridge for IPC?
For Apple Music specifically, should I use MusicKit, MediaPlayer, or stick with AppleScript?
Are there other approaches I'm missing?
Topic:
App & System Services
SubTopic:
Automation & Scripting
Hello.
How to write this command correctly on a Macbook, in the script editor, so that I can click the "Run script" button and the script will give the result:
if there is no folder, then report that there is no folder,
if there is a folder, then report that the folder exists.
do shell script "test -d 'Users/user/Desktop/New folder'"
Now, if the folder exists, an empty string ("") is returned, if the folder does not exist, the script editor reports that an error has occurred.
In general, my task is to write a script that checks the existence of a folder.
how to register more than 10 shortcuts
Hi,
I am trying to make an app that uses Spotify's web API to play songs. For the web API to work, Spotify needs to be running, and my Mac has to be recognized as an active device. For my Mac to be recognized as an active device, I have to play a song for a very short amount of time (under a second).
I want to make my app automatically do that on launch. I already wrote the AppleScript in Automator, and it worked. It successfully launched Spotify, played a song for 0.5 seconds, then hid itself. After writing the code, I tried to implement it into my app to run on startup, but I ran into a problem. The app only started the Spotify app on my mac, and gave me an error that told me it wasn't running.
What do I do? Is this an issue with the permissions of the app, or something else? I have given the app the "Apple Events" entitlement.
This is the error I am getting. Note that the app opens Spotify, after which it gives me this.
Error: { NSAppleScriptErrorAppName = Spotify; NSAppleScriptErrorBriefMessage = "Application isn\U2019t running."; NSAppleScriptErrorMessage = "Spotify got an error: Application isn\U2019t running."; NSAppleScriptErrorNumber = "-600"; NSAppleScriptErrorRange = "NSRange: {31, 8}"; }
This is the function I am trying to use to do the actions with Spotify:
func runAppleScript() {
let appleScript = """
tell application "Spotify"
activate
if player state is not playing then
play track "spotify:track:5XSKC4d0y0DfcGbvDOiL93"
delay 1
pause
end if
end tell
tell application "System Events"
tell process "Spotify"
set frontmost to true
delay 1
keystroke "h" using {command down}
end tell
end tell
"""
var error: NSDictionary?
if let scriptObject = NSAppleScript(source: appleScript) {
scriptObject.executeAndReturnError(&error)
}
if let error = error {
print("Error: \(error)")
}
}
Any help is appreciated. Thank you in advance.
Topic:
App & System Services
SubTopic:
Automation & Scripting
We created a script .scpt that is run before an operation. the script use a login via Safari. almost always it works but sometimes not. if we log on the machine the script will work. do you have idea of the problems? Thanks
(Public dupe of FB16477656)
The Shortcuts app allows you to parameterise the input for an action using variables or allowing "Ask every time". This option DOES NOT show when conforming my AppEntity.defaultQuery Struct to EntityStringQuery:
But it DOES shows when confirming to EntityQuery:
As discussed on this forum post (or FB13253161) my AppEntity.defaultQuery HAS TO confirm to EntityStringQuery to allow for searching by String from Siri Voice input.
To summarise:
With EntityQuery:
My Intent looks like it supports variables via the Shortcuts app. But will end up in an endless loop because there is no entities(matching string: String) function.
This will allow me to choose an item via the Shorcuts.app UI
With EntityStringQuery:
My Intent does not support variables via the Shortcuts app.
I am not allows to choose an item via the Shorcuts.app UI.
Even weirder, if i set up the shortcut with using a build with EntityQuery and then do another build with EntityStringQuery it works as expected.
Code:
/*
Works with Siri to find a match, doesn't show "Ask every time"
*/
public struct WidgetStationQuery: EntityStringQuery {
public init() { }
public func entities(matching string: String) async throws -> [Station] {
let stations = [Station(id: "car", name: "car"), Station(id: "bike", name: "bike")]
return stations.filter { $0.id.lowercased() == string.lowercased() }
}
public func entities(for identifiers: [Station.ID]) async throws -> [Station] {
let stations = [Station(id: "car", name: "car"), Station(id: "bike", name: "bike")]
return stations.filter { identifiers.contains($0.id.lowercased()) }
}
public func suggestedEntities() async throws -> [Station] {
return [Station(id: "car", name: "car"), Station(id: "bike", name: "bike")]
}
public func defaultResult() async -> Station? {
try? await suggestedEntities().first
}
}
/*
DOES NOT work with Siri to find a match, but Shortcuts shows "Ask every time"
*/
public struct WidgetBrokenStationQuery: EntityQuery {
public init() { }
public func entities(matching string: String) async throws -> [Station] {
let stations = [Station(id: "car", name: "car"), Station(id: "bike", name: "bike")]
return stations.filter { $0.id.lowercased() == string.lowercased() }
}
public func entities(for identifiers: [Station.ID]) async throws -> [Station] {
let stations = [Station(id: "car", name: "car"), Station(id: "bike", name: "bike")]
return stations.filter { identifiers.contains($0.id.lowercased()) }
}
public func suggestedEntities() async throws -> [Station] {
return [Station(id: "car", name: "car"), Station(id: "bike", name: "bike")]
}
public func defaultResult() async -> Station? {
try? await suggestedEntities().first
}
}```
Topic:
App & System Services
SubTopic:
Automation & Scripting
Tags:
Siri and Voice
Shortcuts
Intents
App Intents
We are trying to open an application "xyz.app" It worked fine until 15.1.1 versions. But facing issues with 15.2 and 15.3
The application is working fine when we navigate to xyz.app/Contents/MacOS/ and run applet in this directory. But the error "Not authorized to send Apple events to Terminal" occurs when we are trying to open the app directly.
We have tried with all the available solutions like giving full disk access to terminal and application, adding my application to automation in privacy and security tabs in settings.
Any help would be appreciated.
Thanks!
Hi everyone,
I'm trying to use Automator to batch process PDF files. I have hundreds of academic journal article PDFs whose page sizes vary from 5x7 inches to A4 format (8.27 x 11.69 inches). I want to scale all the PDFs to US Letter size (8.5 x 11.0 inches) such that smaller originals remain 100% scale but are centered on the larger page and larger originals are scaled down to fit the page.
Manually opening a PDF in Preview.app, scaling it to US Letter paper, and using the Save as PDF option is producing the desired output for me. I captured my workflow using the Watch Me Do action in Automator, then adjusted it into the following AppleScript.
-- a Get Specified Finder Items action to specify the input PDFs precedes this script
on run {input, parameters}
repeat with filePath in input
-- Open the file in Preview
tell application "Preview"
open filePath
activate
end tell
-- Give Preview some time to open the file
delay 2.0
-- Press ⌘P
set timeoutSeconds to 0.25
set uiScript to "keystroke \"p\" using command down"
my doWithTimeout(uiScript, timeoutSeconds)
-- Click the “Scale to Fit:” radio button.
delay 2.0
set timeoutSeconds to 2.0
set uiScript to "click radio button \"Scale to Fit:\" of radio group 1 of group 1 of group 2 of scroll area 2 of splitter group 1 of sheet 1 of window 1 of application process \"Preview\""
my doWithTimeout(uiScript, timeoutSeconds)
-- Click the “<fill in title>” menu button.
delay 4.0
set timeoutSeconds to 2.000000
set uiScript to "click menu button 1 of group 2 of splitter group 1 of sheet 1 of window 1 of application process \"Preview\""
my doWithTimeout( uiScript, timeoutSeconds )
-- Save as PDF…
delay 2.0
set timeoutSeconds to 2.0
set uiScript to "click menu item 2 of menu 1 of splitter group 1 of sheet 1 of window 1 of application process \"Preview\""
my doWithTimeout(uiScript, timeoutSeconds)
-- Click the “Save” button.
delay 8.0
set timeoutSeconds to 2.0
set uiScript to "click UI Element \"Save\" of sheet 1 of sheet 1 of window 1 of application process \"Preview\""
my doWithTimeout(uiScript, timeoutSeconds)
-- Press ⌘W to close the file
delay 0.25
set timeoutSeconds to 2.0
set uiScript to "keystroke \"w\" using command down"
my doWithTimeout(uiScript, timeoutSeconds)
end repeat
return input
end run
on doWithTimeout(uiScript, timeoutSeconds)
set endDate to (current date) + timeoutSeconds
repeat
try
run script "tell application \"System Events\"
" & uiScript & "
end tell"
exit repeat
on error errorMessage
if ((current date) > endDate) then
error "Can not " & uiScript
end if
end try
end repeat
end doWithTimeout
My problem arises at the Save as PDF step. When this action runs, I see the PDF menu pop open:
but the Save as PDF... menu item doesn't get clicked. Instead, I get an error:
Can anyone advise on how to overcome this error?
So Recently I’ve been making shortcuts and I noticed that I can prompt chatgpt with shortcuts to add extra functionality, I like this idea but there is 1 flaw with it and that is there is no ability to remove chats automatically, I suppose this would be fine except every time the shortcut is run it creates a new chat, usually I would have made it to remove the chat after the shortcut is finished, but since I can’t the chats would pile up as there is no way of getting rid of them automatically and it would be tedious to manually delete all the chats.
also sorry if I chose the wrong topic and subtopic, I couldn’t find a topic about shortcuts
Sometimes, during Recovery, when choosing "Options"
I'm presented with the Language chooser
before going into the Recovery options.
Other times the process moves directly into Recovery options, without any language choice.
I'm running in recovery mode, after completing a fresh installation of macOS (including setting a language) and fully shutting down the OS via the menu.
This happens seemingly randomly, which affects the ability to automate the process.
So far I've only seen it on macOS 15.
Is there some logic to why this language chooser pops up, and any way I can make it consistent (in either direction)?
I'm currently trying to use the new @UnionValue macro.
From what I understood, it allows multiple types for a parameter.
I created the following enum:
@UnionValue
enum IntentDuration {
case int(Int)
case duration(Measurement<UnitDuration>)
}
Then, I tried to use it in the following AppIntent:
struct MyIntent: AppIntent {
static let title: LocalizedStringResource = "intent.title"
static let description = IntentDescription("intent.description")
static let openAppWhenRun: Bool = true
@Parameter var duration: IntentDuration
@Dependency
private var appManager: AppManager
@MainActor
func perform() async throws -> some IntentResult {
// My action
return .result()
}
}
However, I get the following error from Xcode at the @Parameter line:
'init()' is unavailable
Did I wrongly understand how this works? Is there another way to accept multiple types for a parameter?
I didn't manage to find any docs on this.
Hello,
Relatively new to AppleScripts in current gen (I've used it back in 2010s) and would like some help if someone can point me in the right direction.
Is AppleScript the best/only way to interact with Notes application? (I'm on Sequioa)
1.1 I've tried to use LLM to generate a Swift app, but it still calls out to AppleScripts, so I'm wondering if I'm missing something.
1.2 If I'm going down a rabbit hole, I'd like to stop since I want to finish this quick task and move on and or fall deeply in love with AppleScripts... whichever comes first.
Is There a better way to write notes? Script Editor is still a minimal IDE, I'd love to find something that will do some auto completion/suggestions because the documentation in the Script Editor is still a tad weak. (I'm used to interpreted languages like bash, ruby, etc...) where if I don't understand something I just dig into the code instead of turse documentation that just exposes public end points and does not tell you much more :(
My problem: I'd like to set up a cron that periodically checks my notes, and cleans up the shared notes. Basically it's a shared set of notes that have checklist on it and cleans up. (weekly chores etc...) I want to read the notes, find out which ones have been marked checked. Reset the ones that are done, leave unfinished ones alone and reset the old ones.
This is how far I've gotten:
let appleScript = """```
tell application "Notes"
set targetNote to note "\Test" of default account
return body of targetNote
end tell
That works like a charm, Kind of dumb because I rather use and ID of the note not the name :(
It returns the following
<div><b><span style=\\"font-size: 24px\\">Test</span></b></div>
<div><br></div>
<ul>
<li> Not Done</li>
<li>Done</li>
<li>Not Done yet</li>
</ul>
<div><br></div>
<div>Single line</div>
Which is a good start!
Issues:
There is no way to tell which Item is marked "Checked" and which one is not :(
Any helps is greatly appreciated!
I wrote an AppleScript that takes a bunch of scanned jpegs with systematically named filenames and transfers information from the filename into the date and time fields. That all works fine, but I've got many more scans to do and I'd like to augment the script to include a progress meter because it takes a long time to run on e.g. 1000 photos.
I've found basic progress meter examples online that involves commands like:
set progress total steps to theImageCount
set progress completed steps to 0
set progress description to "Processing Images..."
set progress additional description to "Preparing to process."
and they run OK in a separate dummy test case, however I'm getting syntax errors for such commands in my renaming script because (I think) they're inside a
tell application "Photos"
wrapper and it looks like Photos doesn't like those commands.
A progress meter (in any AppleScript) should be a straightforward thing i.e. I can clearly define a total number of steps and I can clearly define the step number I'm currently on. I just want to display something like:
I'd even be OK with just implementing something like:
display dialog "blah blah"
but that needs to be manually dismissed with each iteration of the loop, so that's no good. I also tried:
display notification "blah blah"
but that yields hundreds of notification boxes at the top right of my screen, so that's also impractical.
I was even thinking maybe I could call some generic system progress meter with all the right variables via a "do shell script" command (although I have no idea how to do that). Something surely must be possible, but I just can't figure it out :-(. Could some kind soul please help me out. Thanks.
Topic:
App & System Services
SubTopic:
Automation & Scripting
I'm unable to fix syntax errors when using folders such as “greg’s folder"
error "86:87: syntax error: Expected “"” but found unknown token. (-2741)" number 1
i’ve created an apple script to run python tool to extract “.rpa” files. the script works well except to selecting games that are in a folder with “‘".
any ideas to properly to this?
thank you.
-- Function to escape special characters in POSIX paths for safe shell execution
on escapePOSIXPath(originalPath)
set AppleScript's text item delimiters to "'"
set pathParts to text items of originalPath
set AppleScript's text item delimiters to "'\\''"
set escapedPath to pathParts as text
set AppleScript's text item delimiters to "" -- Reset delimiters
-- Wrap in single quotes
return "'" & escapedPath & "'"
end escapePOSIXPath
-- Get the current app's POSIX path
set currentAppPath to POSIX path of (path to me)
-- Construct the expected path for rpatool.py
set scriptPath to currentAppPath & "Contents/Resources/Scripts/rpatool.py"
-- Check if rpatool.py exists
set scriptExists to do shell script "test -e " & quoted form of scriptPath & " && echo true || echo false"
if scriptExists is "false" then
-- Ask user to select the rpatool.py file
display dialog "rpatool.py was not found. Please select its location."
set rpaToolFile to choose file with prompt "Select the rpatool.py script" of type {"public.python-script"}
set scriptPath to POSIX path of rpaToolFile
end if
-- Escape the path for safe execution
set scriptPath to escapePOSIXPath(scriptPath)
-- Prompt user to select the game application
set appFile to choose file with prompt "Select the Game app with RPA files" of type {"com.apple.application"}
set appPath to POSIX path of appFile
set gameFolderPath to appPath & "/Contents/Resources/autorun/game"
-- Check if the 'game' folder exists
set gameFolderExists to do shell script "test -d " & quoted form of gameFolderPath & " && echo true || echo false"
if gameFolderExists is "false" then
display dialog "The 'game' folder was not found in the selected app's directory. Exiting..."
return
end if
-- Find all .rpa files in the game folder
set fileList to paragraphs of (do shell script "find " & quoted form of gameFolderPath & " -name '*.rpa' -type f")
-- Check if .rpa files exist
if fileList is {} then
display dialog "No .rpa files found in the 'game' folder. Exiting..."
return
end if
-- Open Terminal and change directory
set firstCommand to "cd " & quoted form of gameFolderPath
do shell script "osascript -e " & quoted form of ("tell application \"Terminal\" to do script \"" & firstCommand & "\"")
-- Process each .rpa file in Terminal
display dialog "Extraction will start in Terminal and will process " & (count of fileList) & " .rpa files."
repeat with aFile in fileList
set aFile to escapePOSIXPath(aFile)
set extractionCommand to "python3 " & scriptPath & " -x " & aFile
-- Execute in Terminal
try
do shell script "osascript -e " & quoted form of ("tell application \"Terminal\" to do script \"" & extractionCommand & "\" in front window")
delay 0.5
do shell script "osascript -e " & quoted form of "tell application \"Terminal\" to activate"
on error errMsg
display dialog "Error executing command: " & errMsg
end try
end repeat
Test Run with error:
tell current application
path to current application
--> alias "Macintosh HD:Users:Greg:Downloads:Ren'Py:RPA Extractor Mac 2.9.scpt"
do shell script "test -e '/Users/Greg/Downloads/Ren'\\''Py/RPA Extractor Mac 2.9.scptContents/Resources/Scripts/rpatool.py' && echo true || echo false"
--> "false"
end tell
tell application "Script Editor"
display dialog "rpatool.py was not found. Please select its location."
--> {button returned:"OK"}
choose file with prompt "Select the rpatool.py script" of type {"public.python-script"}
--> alias "Macintosh HD:Users:Greg:Downloads:Ren'Py:Test Game:rpatool.py"
choose file with prompt "Select the Game app with RPA files" of type {"com.apple.application"}
--> alias "Macintosh HD:Users:Greg:Downloads:Ren'Py:Test Game:Test Game.app:"
end tell
tell current application
do shell script "test -d '/Users/Greg/Downloads/Ren'\\''Py/Test Game/Test Game.app//Contents/Resources/autorun/game' && echo true || echo false"
--> "true"
do shell script "find '/Users/Greg/Downloads/Ren'\\''Py/Test Game/Test Game.app//Contents/Resources/autorun/game' -name '*.rpa' -type f"
--> "/Users/Greg/Downloads/Ren'Py/Test Game/Test Game.app//Contents/Resources/autorun/game/code.rpa
/Users/Greg/Downloads/Ren'Py/Test Game/Test Game.app//Contents/Resources/autorun/game/fonts.rpa
/Users/Greg/Downloads/Ren'Py/Test Game/Test Game.app//Contents/Resources/autorun/game/sounds.rpa"
do shell script "osascript -e 'tell application \"Terminal\" to do script \"cd '\\''/Users/Greg/Downloads/Ren'\\''\\'\\'''\\''Py/Test Game/Test Game.app//Contents/Resources/autorun/game'\\''\"'"
--> error "73:74: syntax error: Expected “\"” but found unknown token. (-2741)" number 1
Result:
error "73:74: syntax error: Expected “\"” but found unknown token. (-2741)" number 1
On iOS 18, I'm trying to index documents in Spotlight using the new combination of AppIntents+IndexedEntity.
However, I don't seem to be able to index the textContent of the document. Only the displayName seems to be indexed.
As recommended, I start with the defaultAttributeSet:
/// I call this function to index in Spotlight
static func indexInSpotlight(document: Document) async {
do {
if let entity = document.toEntity {
try await CSSearchableIndex.default().indexAppEntities([entity])
}
} catch {
DLog("Spotlight: could not index document: \(document.name ?? "")")
}
}
/// This is the corresponding IndexedEntity with the attributeSet
@available(iOS 18, *)
extension DocumentEntity {
var attributeSet: CSSearchableItemAttributeSet {
let attributeSet = defaultAttributeSet
attributeSet.title = title
attributeSet.displayName = title
attributeSet.textContent = docContent
attributeSet.thumbnailData = thumbnailData
attributeSet.kind = "document"
attributeSet.creator = Constants.APP_NAME
return attributeSet
}
}
How can I have more that the displayName to be indexed? Thanks :-)
Hi all,
I'm developing a sandboxed Mac OS app that generates and compiles AppleScript files to automate tasks in Pages (and other iWork apps). The app creates an AppleScript file and writes it to the NSApplicationScriptsDirectory (i.e., ~/Library/Application Scripts/com.example.app), then compiles and executes it via NSUserAppleScriptTask.
On Mac OS Ventura, however, I get the following error in the console when trying to write the file:
[PagesModifier] Error creating or compiling the script: You are not allowed to save the file "PagesModifier_...applescript" in the folder "com.example.app"
Here are my current entitlements:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array/>
<key>com.apple.security.automation.apple-events</key>
<array>
<string>com.apple.iWork.Pages</string>
<string>com.apple.iWork.Numbers</string>
<string>com.apple.iWork.Keynote</string>
</array>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.scripting-targets</key>
<dict>
<key>com.apple.iWork.Keynote</key>
<array>
<string>com.apple.iWork.Keynote</string>
</array>
<key>com.apple.iWork.Numbers</key>
<array>
<string>com.apple.iWork.Numbers</string>
</array>
<key>com.apple.iWork.Pages</key>
<array>
<string>com.apple.iWork.Pages</string>
</array>
</dict>
<key>com.apple.security.temporary-exception.apple-events</key>
<array>
<string>com.apple.iWork.Pages</string>
<string>com.apple.iWork.Numbers</string>
<string>com.apple.iWork.Keynote</string>
</array>
<key>com.apple.security.temporary-exception.files.home-relative-path.read-write</key>
<array>
<string>Library/Application Scripts/com.example.app</string>
</array>
</dict>
</plist>
I suspect the issue might be due to sandbox restrictions on dynamically creating or modifying the Application Scripts directory on Ventura. Has anyone experienced something similar or have any suggestions on how to work around this?
Thanks in advance for your help!
Topic:
App & System Services
SubTopic:
Automation & Scripting
Tags:
Entitlements
Scripting
AppleScript
App Sandbox