In the Swift function at the end of this post, I use Scripting Bridge to have Finder delete a path. The variable result
is a SBObject
returned by the delete()
function. I know that result
somehow contains the new path of the deleted item in the trash folder, but I don't know how to nicely extract it as a single String
.
If I print(String(describing: result))
, I get output like:
<SBObject @0x0123456789ab: <class 'appf'> "AppName.app" of <class 'cfol'> ".Trash" of <class 'cfol'> "user" of <class 'cfol'> "Users" of startupDisk of application "Finder" (822)>
Is there any way to obtain the String
"/Users/user/.Trash/AppName.app"
from result
without having to perform string parsing on the above output?
The Finder*
types in the code below are from https://github.com/tingraldi/SwiftScripting/blob/master/Frameworks/FinderScripting/FinderScripting/Finder.swift
func trash(path: String) throws {
guard let finder: FinderApplication = SBApplication(bundleIdentifier: "com.apple.finder") else {
throw runtimeError("Failed to obtain Finder access: com.apple.finder does not exist")
}
guard let items = finder.items else {
throw runtimeError("Failed to obtain Finder access: finder.items does not exist")
}
let object = items().object(atLocation: URL(fileURLWithPath: path))
guard let item = object as? FinderItem else {
throw runtimeError(
"""
Failed to obtain Finder access: finder.items().object(atLocation: URL(fileURLWithPath: \
\"\(path)\") is a '\(type(of: object))' that does not conform to 'FinderItem'
"""
)
}
guard let delete = item.delete else {
throw runtimeError("Failed to obtain Finder access: FinderItem.delete does not exist")
}
let result = delete()
}
Though it's not obvious from the generic type returned by delete, delete actually returns a FinderItem that contains an object specifier referring to the file in the trash. For example, put a file named "testfile.pdf" in your documents folder and try running this script in the Script Editor:
tell application "Finder"
set target_file to document file "testfile.pdf" of item "Documents" of folder "dtsengineer42" of folder "Users" of startup disk of application "Finder"
set new_location to delete target_file
return new_location
end tell
returns: document file "testfile.pdf" of item ".Trash" of folder "dtsengineer42" of folder "Users" of startup disk of application "Finder"
*NOTE - these directions use my home folder name, you will need to change that to yours for them to work on your machine.
This is an object specifier specifying where the object is with directions for finding it. And, you can change this script to get the file url for the trashed file like so:
tell application "Finder"
set target_file to document file "testfile.pdf" of item "Documents" of folder "dtsengineer42" of folder "Users" of startup disk of application "Finder"
set new_location to delete target_file
return URL of new_location
end tell
returns "file:///Users/dtsengineer42/.Trash/testfile.pdf"
And of course you can do the same thing with Scripting Bridge. But, in this case, the delete command returns a generic SBObject. Coerce the SBObject returned by delete into a FinderItem and then you can access the URL method and convert the object specifier into a URL like so:
NSString *testFile = @"testfile.pdf";
FinderFile *targetFile = [[[[[self.finder home] folders]
objectWithName:@"Documents"] files]
objectWithName: testFile];
if ( [targetFile exists] ) {
NSLog(@"%@ exists", testFile);
} else {
NSLog(@"%@ does not exist", testFile);
}
SBObject *movedTargetFile = [targetFile delete];
NSString *theURL = [(FinderItem *) movedTargetFile URL];
NSLog(@"moved target = %@", theURL);
outputs:
file exists
moved target = file:///Users/dtsengineer42/.Trash/testfile.pdf