Skip to content

Instantly share code, notes, and snippets.

@bradhowes
Last active March 18, 2022 12:17
Show Gist options
  • Save bradhowes/4cd0b3da56b24166243e88d77329e909 to your computer and use it in GitHub Desktop.
Save bradhowes/4cd0b3da56b24166243e88d77329e909 to your computer and use it in GitHub Desktop.
Workarounds for Swift PM Bundle Handling
// When working properly, SWIFTPM_MODULE_BUNDLE is defined. At least on Xcode 13.2, this is not always the case with
// packages, especially when running tests. The code below was pulled from my SF2Lib Swift package. This package is
// used in my SoundFonts application. The workaround below handles two situations where SWIFTPM_MODULE_BUNDLE is not
// working right:
//
// 1. SWIFTPM_MODULE_BUNDLE not defined -- seems to be limited to unit tests in the SF2Lib package
// 2. SWIFTPM_MODULE_BUNDLE defined but throws exception -- seems to be limited to unit tests of a package that depends
// on SF2Lib package
//
#if defined(SWIFTPM_MODULE_BUNDLE)
+ (NSString*)getConfigurationPath {
// Here we are attempting to locate a "Configuration.plist" file in our bundle. This works properly when running on a
// device or in a simulator. However when testing a component that depends on this Swift package, the Apple code that
// sets SWIFTPM_MODULE_BUNDLE to the right NSBundle instance fails to locate the bundle and raises an exception.
// Here we catch it and provide a workaround.
@try {
return [SWIFTPM_MODULE_BUNDLE pathForResource:@"Configuration" ofType:@"plist"];
} @catch (NSException *exception) {
// Most likely we are in a unit test for something that depends on SF2Lib -- either the build system is not putting
// stuff in the right location, or the code for SWIFTPM_MODULE_BUNDLE is not accounting for the test case.
NSArray<NSBundle*>* allBundles = [NSBundle allBundles];
for (int index = 0; index < [allBundles count]; ++index) {
NSBundle* bundle = [allBundles objectAtIndex:index];
NSString* bundleIdent = bundle.bundleIdentifier;
NSLog(@"bundle: %@ - %@", bundleIdent, bundle.resourcePath);
NSString* found = [bundle pathForResource:@"SF2Lib_SF2Lib" ofType:@"bundle"];
if (found != NULL) {
bundle = [[NSBundle alloc] initWithPath:found];
bundleIdent = bundle.bundleIdentifier;
NSLog(@"bundle: %@ - %@", bundleIdent, bundle.resourcePath);
NSString* found = [bundle pathForResource:@"Configuration" ofType:@"plist"];
if (found != NULL) return found;
}
}
return NULL;
}
}
#else
// Workaround for situations where SWIFTPM_MODULE_BUNDLE is not defined. This seems to be the case in all unit tests.
// We visit all known bundles and hope for the best.
+ (NSString*)getConfigurationPath {
NSArray<NSBundle*>* allBundles = [NSBundle allBundles];
for (int index = 0; index < [allBundles count]; ++index) {
NSBundle* bundle = [allBundles objectAtIndex:index];
NSString* bundleIdent = bundle.bundleIdentifier;
NSLog(@"bundle: %@ - %@", bundleIdent, bundle.resourcePath);
NSString* found = [bundle pathForResource:@"Configuration" ofType:@"plist"];
if (found != NULL) return found;
}
return NULL;
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment