Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run-time Arguments Supported with Swift Assembly? #293

Closed
ghost opened this issue Dec 11, 2014 · 7 comments
Closed

Run-time Arguments Supported with Swift Assembly? #293

ghost opened this issue Dec 11, 2014 · 7 comments

Comments

@ghost
Copy link

ghost commented Dec 11, 2014

Hi,

I'm attempting to update my project to use Swift for all my TyphoonAssembly code. I've had some success, but I'm stuck trying to pass run-time arguments to a controller. Here's my code:

dynamic func webControllerForPath(path: String) -> AnyObject {
    return TyphoonDefinition.withClass(WebViewController.self) { (definition) in
        definition.parent = self.baseController();
        definition.useInitializer("initWithNibName:bundle:") { (initializer) in
            initializer.injectParameterWith("WebViewController");
            initializer.injectParameterWith(NSBundle.mainBundle());
        }
        definition.injectProperty("path", with: path);
    }
}

That last line is causing a crash. Specifically:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'You can't call a method on the runtime argument being passed in. It has to be passed in as-is'

Is this not supported? Thanks.

@alexgarbarev
Copy link
Contributor

Hi, It's because runtime arguments must be objective-c object, but you passing String. Try to replace String with NSString (String would be converted into NSString automatically by swift compiler)

@ghost
Copy link
Author

ghost commented Dec 11, 2014

Thanks, Alex! That was it. Working great now.

@ghost ghost closed this as completed Dec 11, 2014
@tspecht
Copy link

tspecht commented Sep 15, 2015

Hey! Sorry for posting on this issue, but I'm currently running into the same issue with the following code:

dynamic func typhoonStoryboard(name: NSString) -> AnyObject {
        return TyphoonDefinition.withClass(TyphoonStoryboard.self, configuration: { (definition) -> Void in
            definition.useInitializer("storyboardWithName:factory:bundle:", parameters: { (initializer) -> Void in
                initializer.injectParameterWith(name)
                initializer.injectParameterWith(self)
                initializer.injectParameterWith(NSBundle.mainBundle())
            })
        })
    }

    func viewController(withStoryboardName storyboardName: NSString, storyboardIdentifier: NSString) -> AnyObject {
        return TyphoonDefinition.withFactory(self.typhoonStoryboard(NSString(string: storyboardName)), selector: "instantiateViewControllerWithIdentifier:", parameters: { (method) -> Void in
            method.injectParameterWith(NSString(string: storyboardIdentifier))
        }, configuration: { (definition) -> Void in

        })
    }

Any idea what could be wrong? Like you see I'm already doing the workaround with NSString but it still crashes with above exception...

2015-09-15 09:26:32.484 MyApp[64855:5393006] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'You can't call a method on the runtime argument being passed in. It has to be passed in as-is'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010ae0ff65 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010a42edeb objc_exception_throw + 48
    2   CoreFoundation                      0x000000010ae0fe9d +[NSException raise:format:] + 205
    3   MyApp                            0x00000001052282b3 -[TyphoonInjectionByRuntimeArgument forwardingTargetForSelector:] + 67
    4   CoreFoundation                      0x000000010ad65c4e ___forwarding___ + 158
    5   CoreFoundation                      0x000000010ad65b28 _CF_forwarding_prep_0 + 120
    6   libswiftCore.dylib                  0x000000010bff54b3 _TTSf4g_d___TFSSCfMSSFT12_cocoaStringPSs9AnyObject__SS + 131
    7   libswiftCore.dylib                  0x000000010bfbce33 _TFSSCfMSSFT12_cocoaStringPSs9AnyObject__SS + 19
    8   libswiftFoundation.dylib            0x000000010c3e0af9 _TToFE10FoundationCSo8NSStringcfMS0_FT6stringS0__S0_ + 41
    9   libswiftFoundation.dylib            0x000000010c3e0a3a _TFE10FoundationCSo8NSStringCfMS0_FT6stringS0__S0_ + 58
    10  MyApp                            0x0000000104cc890d _TFC8MyApp22ViewControllerAssembly14viewControllerfS0_FT18withStoryboardNameCSo8NSString20storyboardIdentifierS1__PSs9AnyObject_ + 157
    11  MyApp                            0x0000000104cc90cf _TToFC8MyApp22ViewControllerAssembly14viewControllerfS0_FT18withStoryboardNameCSo8NSString20storyboardIdentifierS1__PSs9AnyObject_ + 79
    12  CoreFoundation                      0x000000010acfe85c __invoking___ + 140
    13  CoreFoundation                      0x000000010acfe6ae -[NSInvocation invoke] + 286
    14  CoreFoundation                      0x000000010ad8f016 -[NSInvocation invokeWithTarget:] + 54
    15  MyApp                            0x000000010520ea76 objc_msgSend_InjectionArguments + 454
    16  MyApp                            0x000000010520e83e -[TyphoonAssemblyDefinitionBuilder definitionForKey:] + 254
    17  MyApp                            0x000000010520e61f -[TyphoonAssemblyDefinitionBuilder populateCacheWithDefinitionForKey:] + 111
    18  MyApp                            0x000000010520e01b -[TyphoonAssemblyDefinitionBuilder builtDefinitionForKey:args:] + 203
    19  MyApp                            0x000000010520df20 -[TyphoonAssemblyDefinitionBuilder buildDefinitionForKey:] + 64
    20  MyApp                            0x000000010520de43 __49-[TyphoonAssemblyDefinitionBuilder populateCache]_block_invoke + 163
    21  CoreFoundation                      0x000000010ad6f0df __51-[__NSSetM enumerateObjectsWithOptions:usingBlock:]_block_invoke + 79
    22  CoreFoundation                      0x000000010ad6efea -[__NSSetM enumerateObjectsWithOptions:usingBlock:] + 202
    23  MyApp                            0x000000010520dd69 -[TyphoonAssemblyDefinitionBuilder populateCache] + 185
    24  MyApp                            0x000000010520dc1a -[TyphoonAssemblyDefinitionBuilder builtDefinitions] + 74
    25  MyApp                            0x000000010520a976 -[TyphoonAssembly definitions] + 54
    26  MyApp                            0x000000010520ff1a -[TyphoonBlockComponentFactory registerAllDefinitions:] + 90
    27  MyApp                            0x000000010520fd78 -[TyphoonBlockComponentFactory buildAssembly:] + 104
    28  MyApp                            0x000000010520fc10 -[TyphoonBlockComponentFactory initWithAssemblies:] + 544
    29  MyApp                            0x000000010520f8b7 +[TyphoonBlockComponentFactory factoryWithAssemblies:] + 87
    30  MyApp                            0x00000001052340d2 +[TyphoonStartup requireInitialFactory] + 194
    31  MyApp                            0x00000001052345ad __60+[TyphoonStartup swizzleSetDelegateMethodOnApplicationClass]_block_invoke + 93
    32  UIKit                               0x0000000108a8825b -[UIApplication _setDelegate:assumeOwnership:] + 51
    33  UIKit                               0x0000000108a93cea _UIApplicationMainPreparations + 1618
    34  UIKit                               0x0000000108a93647 UIApplicationMain + 124
    35  MyApp                            0x0000000104b1f80f main + 111
    36  libdyld.dylib                       0x000000010c5a492d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

@jasperblues
Copy link
Member

Hello @tspecht it is probably better to post on StackOverflow but in either case please include the crash/console output.

@tspecht
Copy link

tspecht commented Sep 15, 2015

@jasperblues thanks for the quick response! I added the crashlog and will also post on Stackoverflow, thought asking here directly would be more direct ;)

@alexgarbarev
Copy link
Contributor

@tspecht You can't call a method on the runtime argument being passed in. It has to be passed in as-is
while you passing runtime argument into NSString(string: storyboardName))

@jasperblues
Copy link
Member

@tspecht So that means:

  • The parameter is already specified as NSString, so just pass in as-is. No need to wrap with:
NSString(string: storyboardName)

If you interested in the behind-the-scenes info on the reason for this it is because:

  • Typhoon gather information from all the assemblies on how to build objects at startup.
  • At runtime the assembly interface poses in front of the TyphoonComponentFactory which knows how to emit components based on all of those gathered rules.

Therefore: At startup we are just capturing information about which parameter is routed where. Typhoon is a typical introspective/reflective style of DI container -> Rules/blue-prints first->post-processors->instantiation of components.

You're welcome to ask here on GH, just that on StackOverflow you might get a larger audience and its indexed well by Google too.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants