objective-ccocoamacosfilesystems

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


Solution

  • Edit: this answer is now outdated. Refer to this solution by @luna-razzaghipour instead.

    Original answer:

    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;
    }