Search code examples
iosswifttyphoon

TyphoonConfig is trying to load plist with wrong bundle path


I'm new to Typhoon and can't seem to figure out how to get my Configuration.plist to load correctly. My project is modeled after the Swift PocketForecast example, although I started with my own CocoaPods based project and added Typhoon to it myself (i.e. I didn't start from a cloned PocketForecast project). I am using plist integration with multiple assemblies.

When I use this:

public dynamic func config() -> AnyObject {
    return TyphoonDefinition.configDefinitionWithName("Configuration.plist")
}

I get a file not found error and in the debugger I can see the path its using is "/path/to/MyProject.app/Frameworks/Typhoon.framework", but of course my config file isn't located there, it's located at "/path/to/MyProject.app/Configuration.plist". Yes, I have confirmed the file is actually there.

I tried to fix this problem by doing something like this:

public dynamic func config() -> AnyObject {
    return TyphoonDefinition.withClass(TyphoonConfigPostProcessor.self) {
        (definition) in
        definition.injectMethod("useResourceAtPath:") {
            (method) in
            method.injectParameterWith(self.configURL())
        }
    }
}

public dynamic func configURL() -> AnyObject {
    return TyphoonDefinition.withFactory(self.configBundle(), selector: "URLForResource:withExtension:", parameters: {
        (initializer) in
        initializer.injectParameterWith("Configuration")
        initializer.injectParameterWith("plist")
    })
}

public dynamic func configBundle() -> AnyObject {
    return TyphoonDefinition.withClass(NSBundle.self) {
        (definition) in
        definition.useInitializer("mainBundle")
    }
}    

And strangely, this works – sometimes. It appears random, and based on the order that my other Typhoon assemblies are loaded. In other words, sometimes everything works great, but other times the Typhoon initialization bombs out with a variety of different errors like "No component matching id XYZ" or "can't find value in config". But like I said, sometimes it works just fine.

I must be missing some fundamental piece of how Typhoon is initializing, so any help is greatly appreciated!

Edit: So after some poking around it looks like the first method I tried above is failing because of a problem with CocoaPods using a framework instead of a static lib for Swift projects? I found this code in TyphoonResource:

+ (id <TyphoonResource>)withName:(NSString *)name
{
    return [self withName:name inBundle:[NSBundle bundleForClass:[self class]]];
}

And since [self class] will resolve to a class within the Typhoon framework, I guess I see why that is the bundle it is the bundle it is using, but it seems like a bug to me. I'm going to see if I can figure out why this doesn't break the PocketForecast app.


Solution

  • This was a bug in Typhoon 3.0.1. As you indicated when Typhoon is linked as a Swift framework the wrong bundle for TyphoonConfig resources is used. This has since been corrected in Typhoon 3.0.2.