1

I'm writing a FileMaker Pro plugin for OS X, and I need to be able to access a file in the /Applications/FileMaker Pro 11/Extensions/blah.fmplugin/Contents/Resources directory. (But this could be /apps/FileMaker Pro 11 Advanced/Extensions/xyz.fmplugin/Contents/Resources or something else, depending on where the user installed FMP and whether they renamed the plugin etc.) Since I can't control where the user has installed FMP, or whether they are running FMP or FMPA or whether they have renamed my plugin (although this is less likely than the FMP vs FMPA situation), I do not know the path to the plugin's bundle.

I've found answers like this: Relative Paths Not Working in Xcode C++ but that gives me the path to the Resources folder in the FileMaker.app instead of in my plugin.

i.e. I get /Applications/FileMaker Pro 11/FileMaker Pro.app/Contents/Resources instead of the path to the Resources folder in my plugin.

Is there something I need to configure in Xcode to get the above solution to work? Or is there some other way to get at the path? The CFBundleGetMainBundle() call makes it sound like it is meant to return the bundle of the app itself rather than the plugin.

I have found some possibilities based on the Bundle Programming Guide and CFBundleGetBundleWithIdentifier (mentioned by mipadi), but I haven't been able to figure out yet exactly what functions I need and what the prerequisites are.

Community
  • 1
  • 1
Wodin
  • 3,243
  • 1
  • 26
  • 55

2 Answers2

3

This seems to do it. CFBundleGetBundleWithIdentifier should have worked too, but I decided to go with the NSBundle stuff rather than CF*. I put this in a .mm file and included it in the project. I can then call the get_resources_path() function and get the path as a string.

#include <Foundation/Foundation.h>

#include <string>

std::string *get_resources_path()
{
    NSBundle *bundle;

    bundle = [NSBundle bundleWithIdentifier: @"com.example.fmplugin"];
    if (bundle == NULL) {
        // error handling
    }

    NSString *respath = [bundle resourcePath];
    if (respath == NULL) {
        // error handling
    }

    const char *path = [respath UTF8String];
    if (path == NULL) {
        // error handling
    }

    return new std::string(path);
}
Wodin
  • 3,243
  • 1
  • 26
  • 55
2

You can use CFBundleCreate if you know the path to your bundle; or you can get the bundle using the bundle identifier via CFBundleGetBundleWithIdentifier.

mipadi
  • 398,885
  • 90
  • 523
  • 479