9

It looks like on Cocoa there are many ways to move file/folder-directory to Trash:

  1. [[[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation]
  2. [[NSWorkspace sharedWorkspace] recycleURLs:]
  3. [NSFileManager trashItemAtURL:]
  4. [NSFileManager removeItemAtPath:]
  5. [NSFileManager removeItemAtURL:]

It would be nice to understand what the difference is by either reading an explanation here or a link to the official Apple docs.

Also if someone knows a universal way of moving a file/non-empty directory to Trash, it would be nice to know.

jscs
  • 63,694
  • 13
  • 151
  • 195
Igor
  • 5,620
  • 11
  • 51
  • 103

1 Answers1

11
  1. [[[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation]

This is deprecated, as of OS X 10.11, so no point in using it.

  1. [[NSWorkspace sharedWorkspace] recycleURLs:]

This is probably the one you want. It's asynchronous, so your application can continue to operate while the files are being moved to the trash.

  1. [NSFileManager trashItemAtURL:]

This is similar to option 2, but it's synchronous, and only handles one file at a time.

  1. [NSFileManager removeItemAtPath:]

This doesn't trash the file, it deletes it permanently, and immediately.

  1. [NSFileManager removeItemAtURL:]

This is just like option 4, except using a file:// URL instead of a path. More-convenient when you already have a URL rather than a path.

The reference pages for NSWorkspace and NSFileManager cover all of the differences between these methods fairly well.


Here's a quick sample, which uses recycleUrls: to delete a file or folder named "Junk" on the user's desktop:

- (IBAction)deleteJunk:(id)sender {
    NSFileManager *manager = [NSFileManager defaultManager];
    NSURL *url = [manager URLForDirectory:NSDesktopDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil]; // get Desktop folder
    url = [url URLByAppendingPathComponent:@"Junk"]; // URL to a file or folder named "Junk" on the Desktop
    NSArray *files = [NSArray arrayWithObject: url];
    [[NSWorkspace sharedWorkspace] recycleURLs:files completionHandler:^(NSDictionary *newURLs, NSError *error) {
        if (error != nil) {
            //do something about the error
            NSLog(@"%@", error);
        }
        for (NSString *file in newURLs) {
            NSLog(@"File %@ moved to %@", file, [newURLs objectForKey:file]);
        }
    }];
}
Mark Bessey
  • 19,598
  • 4
  • 47
  • 69
  • 1. I need the code that will work in 10.6+. 2. Is solution number 2 will work for both file(s) and non-empty directory? I will check those references as well. And can you put some sample code to trash the directory? – Igor Dec 02 '15 at 18:13
  • recycleUrls: is available in OS X 10.6 and later. I added some sample code to my answer. – Mark Bessey Dec 03 '15 at 04:45
  • I am getting an error on the line "NSArray *files = @[url];". Googling says that I need the latest LLVM, which I don't have. I am on the 10.6 with XCode 4.2. How do I rewrite this line? Thx. – Igor Dec 05 '15 at 05:09
  • I changed it to old-school Objective-C notation. Hope that helps. – Mark Bessey Dec 06 '15 at 21:34
  • are both options 2 and 3 accepts wildcards? And option 3 can send the directory and not just file, right? And options 3 is also 10.6+, right? Thank you. – Igor Dec 07 '15 at 16:37
  • OK, I looked it up and it appears that "trashItemAtURL" is 10.8+. Prior to 10.8 I can use "FSPathMoveObjectToTrashSync". Unfortunately the function documentation is not available anymore. Does this mean I'm out of luck? I found this: http://stackoverflow.com/questions/2852203/how-to-move-a-symlink-to-the-trash but I need a documentation in order to know what to pass to the function. Besides the function might be Carbon only and not be supported under Cocoa. – Igor Dec 08 '15 at 04:46
  • 2 option will display finder progress – Parag Bafna Jun 13 '18 at 03:56
  • Careful with `recycleURLs:`! When you try to recycle a lot of items (in the 1000s), this can lead to a crash because it'll start a *lot* of concurrent threads. – Thomas Tempelmann Jun 05 '19 at 17:00
  • @MarkBessey, sorry for the long delay. How do I check for possible errors? – Igor Sep 09 '21 at 23:53
  • @ThomasTempelmann, sorry for the long delay. How do I check for a possible errors? – Igor Sep 09 '21 at 23:54
  • @Igor Check for errors when doing what exactly? Whatever deletion function you use, they all come with some sort of error reporting. Also, the crash I warned about was happening in macOS 10.12 and 10.13 but was apparently fixed in 10.14 and later. Also, you can edit your comments. Or delete them and rewrite them if you made a mistake. This is not a chat site ;) – Thomas Tempelmann Sep 11 '21 at 07:56
  • @thomastempelman, what i mean is - someone will be calling the function above to move stuff to trash, right? I need error checking in that caller... – Igor Sep 11 '21 at 13:02
  • You can't check for errors at the time you call the function for recycleURLs: - that's what the completionHandler block is for. It'll get called at the end of the process, and can report errors to the user at that point, if desired. If you used trashItemAtURL:, it ruturns an error object, which you can inspect at that time. – Mark Bessey Sep 13 '21 at 19:17