Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 can't find which one.

thanks

like image 556
Remizorrr Avatar asked Jan 05 '10 22:01

Remizorrr


2 Answers

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;
}
like image 188
Rob Keniger Avatar answered Oct 23 '22 21:10

Rob Keniger


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:

  1. Go to ~/Desktop in Finder

  2. In terminal, do:

  3. cd ~/Desktop

  4. mkdir aafoo

  5. 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.

like image 5
bbum Avatar answered Oct 23 '22 21:10

bbum