What's the best way to check if a Nib or Xib file exists before trying to load it using initWithNibName:bundle:
or similar?

- 25,607
- 27
- 108
- 188
-
Why would the nib be missing? Especially in an iPhone app; it's not like the user can mess around inside your signed application bundle. (Maybe on jailbreak, but even then, the user should expect brokenness if they go deleting things from inside of apps.) – Peter Hosey May 29 '09 at 00:01
-
1You are quire right. I have quite a complex interface hierarchy and some of the nib's are not yet completed. I wanted to 'catch' any not found and display a "Not Implemented" alert, it means I can send out demos and not crash the simulator if I click on the wrong button. – Richard Stelling May 29 '09 at 00:08
-
@PeterHosey How about when designing a library/framework? You don't know what is and isn't included in your user's app. Better put a check in there. – Kevin Jan 05 '16 at 17:28
-
@Kevin: Why would that be any of the library/framework's business? – Peter Hosey Jan 10 '16 at 05:58
-
@PeterHosey So you can gracefully return an error or throw an exception, instead of just crashing the app... – Kevin Jan 10 '16 at 15:21
-
@Kevin: That's not the part I'm asking about. Why is the library/framework even trying to use a nib/storyboard from the app in the first place? – Peter Hosey Jan 12 '16 at 04:15
-
@PeterHosey Someone could be making a library to make it easier to use different nibs/storyboards... Why should I come up with reasons? I never said it's a useful thing to do, just that the possibility is there, jeez. – Kevin Jan 12 '16 at 07:27
3 Answers
Macro
#define AssertFileExists(path) NSAssert([[NSFileManager defaultManager] fileExistsAtPath:path], @"Cannot find the file: %@", path)
#define AssertNibExists(file_name_string) AssertFileExists([[NSBundle mainBundle] pathForResource:file_name_string ofType:@"nib"])
Here are a set of macros that you can call before you try an load a .xib
or .nib
, they will help identify missing files and spit out useful message about what exactly is missing.
Solutions
Objective-C:
if([[NSBundle mainBundle] pathForResource:fileName ofType:@"nib"] != nil)
{
//file found
...
}
Please note, the documentation states that ofType:
should be the extension of the file. However even if you are using .xib you need to pass `@"nib" or you will get a false-negative.
Swift:
guard Bundle.main.path(forResource: "FileName", ofType: "nib") != nil else {
...
}
(See: touti's original answer: https://stackoverflow.com/a/55919888/89035)

- 1
- 1

- 25,607
- 27
- 108
- 188
-
2great solution, but please consider editing your answer: the documentation about `ofType:` is actually correct, and the argument *could* be the extension of the file (you can actually put the entire filename in the `pathForResource:` and nil in `ofType:` and everything will work just fine, though I don't know if it's good practice). The reason of the `xib`/`nib` difference is that *xib files are actually preprocessed and packed as nib in the app*, `pathForResource:ofType:` works as specified ;-) (just check an .app content if you don't believe me) – Rick77 Dec 03 '15 at 08:36
-
PS: just seen the answer timestamp and you are doing mobile since 2009?! *-Wow-* – Rick77 Dec 03 '15 at 08:40
-
If you want to look for a storyboard instead, just change your `ofType:` parameter to be "storyboardc". Looks like a typo, but that's the extension storyboards have inside the bundle. – Matt Long Apr 08 '16 at 03:51
-
Solution For swift :
guard Bundle.main.path(forResource: "FileName", ofType: "nib") != nil else {
...
}

- 1,164
- 6
- 18
There are two solutions I see here.
You could just call initWithNibName:bundle: and catch an exception if it fails (I like this idea, it feels robust). You will probably want to verify that the exception is in fact a "file not found" exception rather than, say, an "out of memory" exception.
Alternatively, you could check the existence of the nib first, using NSBundle's pathForResource:ofType:, which returns nil for files that don't exist.

- 205,541
- 37
- 345
- 415
-
`initWithNibName:bundle:` doesn't throw an exception if the file does not exist you only get problems when you try to use it with something like `pushViewController:animated:` – Richard Stelling May 28 '09 at 23:47
-
4initWithNibName:bundle returns nil if nib can't be found; so check for this instead. – Abizern May 28 '09 at 23:51
-
2@Abizern I was thinking that exactly, but it does not seem to work, although the documentation says it will return nil if not nib file is found I am getting always an allocation. And I have clean up the project so is no cache problem... – PakitoV May 03 '14 at 12:41
-
-
@Abizern yep, but the nib is not there... so not sure if the method is faulty or I am doing something wrong (but cant think of anything) – PakitoV May 03 '14 at 15:03
-
-
3@Emilio is correct, `initWithNibName:bundle:` seems to return a valid object even if you pass it a total garbage name. – roperklacks Jul 21 '14 at 14:03