make mac package/bundle programmatically
through terminal you can make it with a command - "SetFile -a B filename"
programmatically i think i should set one of the attributes through [[NSFileManager defaultManager] createDirectoryAtPath:dirPath withIntermediateDirectories:NO attributes:attributes error:nil];
but i c开发者_如何学运维an't find which one.
thanks
It is still useful to be able to set the bundle bit programmatically, for instance iPhoto does this to make the iPhoto Library folder appear as a single file.
You can set the bundle bit programmatically using the Carbon File Manager API. You'll need to make sure your app links against the Carbon framework and import the <Carbon/Carbon.h>
header. These calls are 64-bit safe.
- (void)setBundleBitOfFile:(NSString*)path toBool:(BOOL)newValue
{
const char* pathFSR = [path fileSystemRepresentation];
FSRef ref;
OSStatus err = FSPathMakeRef((const UInt8*)pathFSR, &ref, /*isDirectory*/ NULL);
if (err == noErr)
{
struct FSCatalogInfo catInfo;
union FinderInfoTransmuter finderInfoPointers = { .bytes = catInfo.finderInfo };
err = FSGetCatalogInfo(&ref,
kFSCatInfoFinderInfo,
&catInfo,
/*outName*/ NULL,
/*FSSpec*/ NULL,
/*parentRef*/ NULL);
if (err == noErr)
{
if (newValue)
finderInfoPointers.finderInfo->finderFlags |= kHasBundle;
else
finderInfoPointers.finderInfo->finderFlags &= ~kHasBundle;
FSSetCatalogInfo(&ref,
kFSCatInfoFinderInfo,
&catInfo);
}
}
}
- (BOOL)bundleBitOfFile:(NSString*)path
{
BOOL value = NO;
const char* pathFSR = [path fileSystemRepresentation];
FSRef ref;
OSStatus err = FSPathMakeRef((const UInt8*)pathFSR, &ref, /*isDirectory*/ NULL);
if (err == noErr)
{
struct FSCatalogInfo catInfo;
union FinderInfoTransmuter finderInfoPointers = { .bytes = catInfo.finderInfo };
err = FSGetCatalogInfo(&ref,
kFSCatInfoFinderInfo,
&catInfo,
/*outName*/ NULL,
/*FSSpec*/ NULL,
/*parentRef*/ NULL);
if (err == noErr)
{
value = (BOOL)(((finderInfoPointers.finderInfo->finderFlags) & kHasBundle) == kHasBundle);
}
}
return value;
}
What are you trying to do?
Almost all Mac OS X bundles are actually folders with a very specific layout of files/folders within. Rarely is a bundle just a file -- they do exist, but not often.
In most cases, the Bundle bit on the file is entirely irrelevant.
i want to set a folder as a bundle. so through the file system it will looks like a file. later a want to open that package with my application. the question is how to set the folder bundle attribute through cocoa.
You really don't need to set the bundle bit. As long as your folder has an extension (which it should) and your application is properly configured to open files/folders of that extension, it should sow up in the finder as if it were a file.
Example:
Go to ~/Desktop in Finder
In terminal, do:
cd ~/Desktop
mkdir aafoo
mv aafoo aafoo.rtfd
After (4), you'll see 'aafoo' show up in Finder as a folder.
AFter (5), 'aafoo' will change to be a TextEdit document. No attribute bits necessary.
OK -- fair enough. You really really want to set that bit.
Given that you have the command line to do it, I would suggest simply using NSTask. It will likely be easier than using an API to do so.
You do not set a bundle attribute. You define your document types in your application's Info.plist file, and this is where you specify whether your document's are packages or plain files.
You can do this from within Xcode by selecting "Get Info" on your application target; switch to the "Properties" tab, then under "Document Types" add a document, give it a Name, set its file extension, choose an Icon file, then check the "Package" checkmark.
Thanks everybody for help. I used the solution with info.plist file. this is the part of the plist file.
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>Project</string>
<key>LSHandlerRank</key>
<string>Default</string>
<key>LSTypeIsPackage</key>
<true/>
<key>CFBundleTypeExtensions</key>
<array>
<string>fbp</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>document</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
</array>
精彩评论