0

I want to read a .plist file from a certain directory but pathForResource always returns nil, meaning it can't find the file I'm looking for. This is what I'm using to create the path. The file is stored in the Project folder.

NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"test" ofType: @"plist"];

What am I doing wrong? And how can I access a plist file from a directory which is not part of the project? This is for a macOS command line tool.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Lucci
  • 3
  • 2
  • `-pathForResource:ofType:` is for loading a file included in a specific bundle; in the case of `[NSBundle mainBundle]`, that means that it ships as part of your app. You have to make sure that the file is selected as part of a specific target in the Xcode sidebar (e.g. https://i.stack.imgur.com/v3Z0A.jpg). For loading files outside of your project — it depends on where they are. Are you expecting files in a specific location? – Itai Ferber Oct 29 '17 at 19:03
  • Thanks. Yes I'm expecting the files in a specific location. So do all the files need to be selected as part of the target (it's around 200 files)? I should mention, that I don't try to create an iOS app but a command line tool. – Lucci Oct 29 '17 at 19:13
  • 3
    A macOS command line program has no resource bundle. – rmaddy Oct 29 '17 at 19:16
  • Might be the problem here, thanks for pointing that out. So how do I go about accessing the plist then? – Lucci Oct 29 '17 at 19:19
  • @Lukas You can't, not with a command line programing. At least not from any bundle. You could store the plist file in some other useful folder and access it there. – rmaddy Oct 29 '17 at 19:31
  • What do you mean by "useful folder" and how could I access it from there? – Lucci Oct 29 '17 at 19:42
  • You could store it in a new mach-o segment in your executable and load it (them) from there. Not easy. Not straightforward. But it works. Alternatively, they need to be installed in some folder on the disk and then you read from that folder. Totally straightforward, but has installation issues (may run afoul of sandboxing). – bbum Oct 30 '17 at 02:05
  • @Lukas How are you expecting users to install this tool? The tool itself is simply an executable, so the files that you would like to ship with it have to go somewhere. As bbum mentions, you can effectively stick the files into the executable itself in Mach-O segments, but I wouldn't necessarily recommend it. If you ship the files separately, though — they will have to go somewhere. Are they downloaded from a server? Part of the tool itself? This is something you'll need to figure out. – Itai Ferber Oct 30 '17 at 02:07
  • @Lukas If the files need to be shipped with the tool, you'll either need to ask the user to move the files to somewhere where you expect (poor user experience), move them for them (error prone as the user may have already moved the files elsewhere), or download them as part of the tool (may or may not be feasible depending on the application). – Itai Ferber Oct 30 '17 at 02:08

1 Answers1

1

As the comments pointed out, you can't use +[NSBundle mainBundle] unless your app is structured with a .app/ bundle. If you are making a command line app (meaning a single binary), then to read in the path, you need to figure out the location of the file a different way.

When you say "The file is stored in the Project folder", I'm not quite sure what you mean. Surely you won't expect the .plist file to be hanging out in /usr/bin or wherever you end up deploying the binary! If the plist you're reading needs to ship with the app, then you should be using a bundle. If instead you generate the plist while running the app somehow (either by downloading it from the web or by building it up through storing things incrementally), then you should create a subfolder for your app in the Application Support directory which you can query for the .plist.

Once you have the .plist path, you can use +dictionaryWithContentsOfFile: to read it in.

Nick K9
  • 3,885
  • 1
  • 29
  • 62