dyld_fatal_error with Typhoon+Swift+iOS7.x+Plist-bootstrapping

468 views Asked by At

I have very annoying problem with Typhoon Framework version 2.3.0 in Swift project.

I included Typhoon in Podfile as mentiond in tutorial, installed Pods, created bridging header and added #import <Typhoon/Typhoon.h> in this header.

Then I created assembly subclass called ApplicationAssebly :

import Foundation

public class ApplicationAssembly: TyphoonAssembly {
    public dynamic func appDelegate() -> AnyObject {
        return TyphoonDefinition.withClass(AppDelegate.self) {
            (definition) in
            definition.injectProperty("myAssembly", with: self)
        }
    }
}

As you see I want to inject that assembly into AppDelegate. I have also added TyphoonInitialAssemblies entry in Info.plist file. And in this moment my problems has started. I have tested few combinations resulting in NSException :

Can't resolve assembly for name xxx

This combinations are (typhtest is project/bundle name):

  • ClassName in Info.plist: ApplicationAssembly, Defines Module property in Build Settings : No
  • ClassName in Info.plist: ApplicationAssembly, Defines Module property in Build Settings : Yes
  • ClassName in Info.plist: typhtest.ApplicationAssembly, Defines Module property in Build Settings : No
  • ClassName in Info.plist: typhtest.ApplicationAssembly, Defines Module property in Build Settings : Yes

I have found this answer on StackOverflow so I've tried the last combination :

  • ClassName in Info.plist: _TtC8typhtest19ApplicationAssembly, Defines Module property in Build Settings : Yes

This combination doesn't throw NSException but I have dyld_fatal_error, stack trace from iPhone 5s (iOS 7.1) below :

iPhone 5s - iOS 7.1 error stack trace

I get slightly different stack trace from iPhone simulator (iOS 7.1) :

iOS 7.1 emulator error stack trace

What is strange that it works on iOS 8.1 simulator ! Also Typhoon Sample Application for Swift works well on my device.

I also tried to clean any Xcode and project caches and DerivedData directories, I've cleaned project and build folder and rebuilded the project, but it's not working. My Xcode version is 6.1 (6A1052d) and I'm using OSX Yosemite 10.10.1 .

GitHub repository with my code : https://github.com/papcio28/Typhoon-Dyld-Error

Edited 21.11.2014

What is also strange is that if I create the factory manually and inject something also manually, Typhoon works. Steps that I've made are :

  1. Removed TyphoonInitialAssemblies item from Info.plist
  2. Changes AppDelegate.application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool to

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        let factory = TyphoonBlockComponentFactory(assemblies: [AppAssembly()])
        factory.inject(self)
        return true
    }
    

But it doesn't change a fact that I want to use Typhoon without defining factory manually, so the question is still actual.

1

There are 1 answers

6
Jasper Blues On BEST ANSWER

This issue has been reproduced as a bug and will be resolved ASAP. It was also reproduced in the Typhoon sample app, after pod update, meanwhile a clean checkout works fine. This would suggest that a regression bug has crept in somewhere between 2.2.1 and 2.3.0, however checking this yielded some strange results, so it might not actually be the case. We'll post updates/discoveries to the issue log.

Workaround:

In the meantime, please bootstrap Typhoon by overriding the following method in your AppDelegate:

dynamic func initialFactory() -> TyphoonComponentFactory {

    return TyphoonBlockComponentFactory(assemblies:[
        ApplicationAssembly(),
        AnotherAssemblyIfRequired()])
}

This approach bootstraps Typhoon just like plist-integration, and so provides UIStoryboard integration, UIStateRestoration and so forth. . it was not documented until now, as we thought thought the plist style of staring Typhoon was sufficient and it would be simply confusing to provide too many options. However in this case it works for iOS7.1+Swift+Storyboards while plist does not.

Namespacing:

As for the namespace issue, it should not be necessary to mangle the name in the plist file as you did - Typhoon will detect if implicit namespaces are available and handle this transparently. But, if this is not working currently in iOS7.x, you can add a directive to your assembly as follows:

@objc(ApplicationAssembly)
public class ApplicationAssembly : TyphoonAssembly {
    //etc
}

Edit: Fixed in Typhoon 2.3.1:

As of Typhoon 2.3.1, plist bootstrapping can now be used with Swift+iOS7.x