10

Given an NSFileWrapper object (for a file or directory), is there any way to get the full path for the location of the actual file on the disk?

[fileWrapper filename] only returns the file name, not the path, so it isn't what I'm looking for.

hpique
  • 119,096
  • 131
  • 338
  • 476
Greg
  • 9,068
  • 6
  • 49
  • 91
  • 1
    In case you're using `NSDocument`.... http://www.zedkep.com/blog/index.php?/archives/197-Determining-a-full-file-path-from-an-NSFileWrapper.html – Michael Dautermann Jan 13 '12 at 05:21
  • I am using `NSDocument`, and I did see that post. My only concern is that the document could be moved to a new location while open, and this is handled transparently. But if I try to access a file by the old path, it'll crash. – Greg Jan 13 '12 at 09:23
  • Is there a callback function in `NSDocument` to tell me when the file physically moves or is renamed? – Greg Jan 13 '12 at 09:25

3 Answers3

5

No, there's no way to get the full path from NSFileWrapper.

Costique
  • 23,712
  • 4
  • 76
  • 79
3

If you're using NSDocument you can get the path of regular-file file wrappers with a little hack.

First create a NSFileWrapper subclass and overload the regular-file methods that receive a URL to store a copy of it.

@implementation RMFileWrapper

- (id) initWithURL:(NSURL *)url options:(NSFileWrapperReadingOptions)options error:(NSError *__autoreleasing *)outError {
    if (self = [super initWithURL:url options:options error:outError]) {
        self.originalURL = url;
    }
    return self;
}

- (BOOL) readFromURL:(NSURL *)url options:(NSFileWrapperReadingOptions)options error:(NSError *__autoreleasing *)outError {
    BOOL successful = [super readFromURL:url options:options error:outError];
    if (successful) {
        self.originalURL = url;
    }
    return successful;
}

@end

Then add this NSFileWrapper category:

@implementation NSFileWrapper(bestURLWithDocument)

- (NSURL*) bestURLInDocument:(SBDocument*)document {
    if (document.fileURL && self.filename) {
        NSString* path = [document.fileURL.path stringByAppendingPathComponent:self.filename];
        return [NSURL fileURLWithPath:path];
    } else if ([self isKindOfClass:[RMFileWrapper class]]) {
        RMFileWrapper *fileWrapper = (RMFileWrapper*) self;
        return fileWrapper.originalURL;        
    }
    return nil;
}

@end

bestURLInDocument: will return the url of the file-system node if available, or the original file url if not.

The above code assumes that you're not nesting directory file wrappers.

hpique
  • 119,096
  • 131
  • 338
  • 476
  • 1
    How are you substituting the standard NSFileWrapper class for your custom subclass? – Tony Arnold Aug 08 '13 at 12:53
  • Also, this method guarantees little in terms of the returned URL. If autosaving is enabled, the location of your file is only ever good for reading OR writing, depending on when you manage to capture the NSURL instance. I've filed http://openradar.me/14692573 – Tony Arnold Aug 09 '13 at 00:43
  • You can just subclass `NSDocument`/`UIDocument` then use `self.fileURL` – malhal Jan 24 '23 at 11:35
0

You can append path components to the UIDocument fileURL.

Swift 5.2

document.fileURL.appendingPathComponent("MyFolder", isDirectory: true).appendingPathComponent("MyImage.png", isDirectory: false)
Jayden Irwin
  • 921
  • 9
  • 14