FSDetermineIfRefIsEnclosedByFolder(): No const for Cocoa's Temp Dir?
FSDetermineIfRefIsEnclosedByFolder(): No const for Cocoa's Temp Dir?
- Subject: FSDetermineIfRefIsEnclosedByFolder(): No const for Cocoa's Temp Dir?
- From: Jerry Krinock <email@hidden>
- Date: Wed, 12 Aug 2009 07:10:41 -0700
Because my application deals with a small number of documents -- most
users will have only one, and because these documents have "agents"
associated with them and are often not edited, I want my app to warn
the user immediately upon opening a document that is in the Trash,
instead of the default Cocoa behavior which is to open it and complain
later only if the user attempts to save changes.
Unfortunately, the correct way to determine if a file is in a special
directory, using Folder Manager function
FSDetermineIfRefIsEnclosedByFolder(), does not seem able to determine
whether or not a path that I get from the url passed to -[NSDocument
readFromURL:ofType:error:] is temporary. The first problem is that
Cocoa apparently copies the file to a temporary directory, something
like
/private/var/folders/PR/PRtZlutkFa82jPnfdYcUUk+++TI/-Tmp-/
before opening it, so this path is indeed "not in the trash".
OK, so then I try FSDetermineIfRefIsEnclosedByFolder() again, and
again, passing kTemporaryFolderType, kChewableItemsFolderType,
kTemporaryItemsInCacheDataFolderType, and kWhereToEmptyTrashFolderType
in succession. But it in each case, it returns 'false' -- meaning
that the file is not in the specified special directory.
So, finally I resorted to the obviously wrong kludge of getting the
"Cocoa" temporary directory from NSTemporaryDirectory() and testing
whether or not this is a prefix of the given path. Of course, this
works.
What's the correct way to do this?
Sincerely,
Jerry Krinock
@interface NSFileManager (SomeMore)
/*!
@brief Returns YES if a file or directory exists at a given
path and is not in a temporary or Trash folder. Otherwise,
returns NO.
*/
- (BOOL)fileIsPermanentAtPath:(NSString*)path ;
// ...Other methods
@end
@implementation NSFileManager (SomeMore)
- (BOOL)fileIsPermanentAtPath:(NSString*)path {
// The ^correct^ way to find if a path is in a temporary folder
should
// be to pass its FSRef along with kTemporaryFolderType to
// FSDetermineIfRefIsEnclosedByFolder(). I have done this
farther down,
// but it "just doesn't work" to find paths which are in the
// temporary directory that Cocoa uses, something like:
// /private/var/folders/PR/PRtZlutkFa82jPnfdYcUUk+++TI/-Tmp-/
// So, to work around that I first get the current ^Cocoa^
temporary
// directory and see if the given path is in there, with or
without the
// "/private" symbolic link
NSString* cocoaTempDir = NSTemporaryDirectory() ;
if ([path hasPrefix:cocoaTempDir]) {
return NO ;
}
cocoaTempDir = [@"/private"
stringByAppendingPathComponent:cocoaTempDir] ;
if ([path hasPrefix:cocoaTempDir]) {
return NO ;
}
FSRef fsRef;
OSStatus err = paramErr ;
if (path) {
err = FSPathMakeRef(
(UInt8*)[path UTF8String],
&fsRef,
NULL) ;
// If file does not exist, the above will return -43 fnfErr
// So we will skip to the end with ok = NO.
}
if (err == noErr) {
Boolean result ;
FSDetermineIfRefIsEnclosedByFolder (
0,
kTrashFolderType,
&fsRef,
&result
) ;
// Note: FSDetermineIfRefIsEnclosedByFolder will return a -35
nsvErr
// (no such volume) if the fsRef given in the third argument
is not
// in the specified folder. Probably that is because it is
iterating
// through all possible volumes that match the specification
given in the
// first parameter, 0, which means "all volumes", and the
last one it tried
// was something that didn't exist, maybe an OS9/Classic
volume.
// Seems like a bug to me. But anyhow, we ignore it.
if (result == true) {
return NO ;
}
FSDetermineIfRefIsEnclosedByFolder (
0,
kTemporaryFolderType,
&fsRef,
&result
) ;
if (result == true) {
return NO ;
}
err = FSDetermineIfRefIsEnclosedByFolder (
0,
kWhereToEmptyTrashFolderType,
&fsRef,
&result
) ;
if (result == true) {
return NO ;
}
FSDetermineIfRefIsEnclosedByFolder (
0,
kTemporaryItemsInCacheDataFolderType,
&fsRef,
&result
) ;
if (result == true) {
return NO ;
}
FSDetermineIfRefIsEnclosedByFolder (
0,
kChewableItemsFolderType,
&fsRef,
&result
) ;
if (result == true) {
return NO ;
}
}
return YES ;
}
// ...Other methdods
@end
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden