johnno1962 / injectionforxcode

Runtime Code Injection for Objective-C & Swift
MIT License
6.55k stars 565 forks source link

Multiple building configurations #81

Closed simonedamico closed 8 years ago

simonedamico commented 8 years ago

Hello, does anyone have problems with multiple building configurations and schemes? I modified the injection perl script to have the correct building postfix (MyName instead of Debug) so I got past the path not found error; but what what I'm experiencing is that the new code is not correctly swizzled/loaded (even if I got the iOS 9 warning and a success message in the console). When I inject the code the whole rootViewController seems to be reloaded from the storyboard instead of just the view controller injected, I even tried without the storyboard and the new code doesn't get injected (i.e. changing the background colour).

ps: The sample project in this repo works perfectly fine.

johnno1962 commented 8 years ago

Without seeing more of your project I can’t comment what the problem would be. Are you sure you’re not doing an “Inject and Reset” ctl-shift-= by mistake causing you rootViewController to reload?

simonedamico commented 8 years ago

Yeah you're right. That solved the root controller reload problem. Still it doesn't pick up the changes after the injection.

The output in the console looks good: Compiling /Users/Simone/Documents/workspace/pronto-swift-app/Pronto/SignupSourceView.swift objc[59315]: Class InjectionBundle2 is implemented in both /Users/Simone/Documents/workspace/pronto-swift-app/iOSInjectionProject/build/Release-iphonesimulator/InjectionBundle2.bundle/InjectionBundle and /Users/Simone/Documents/workspace/pronto-swift-app/iOSInjectionProject/build/Release-iphonesimulator/InjectionBundle6.bundle/InjectionBundle. One of the two will be used. Which one is undefined. objc[59315]: Class _TtC6Pronto16SignupSourceView is implemented in both /Users/Simone/Library/Developer/CoreSimulator/Devices/10569465-5B85-4738-8242-92038135B621/data/Containers/Bundle/Application/BAE43AA0-206A-47F5-AC3A-C6E721CF679F/Pronto.app/Pronto and /Users/Simone/Documents/workspace/pronto-swift-app/iOSInjectionProject/build/Release-iphonesimulator/InjectionBundle6.bundle/InjectionBundle. One of the two will be used. Which one is undefined. 2016-03-10 17:25:47.182 Pronto[59315:933217] Ignore any warning, Swizzled Pronto.SignupSourceView 0x116566840 -> 0x1009484a0

johnno1962 commented 8 years ago

Is it a “final" class or are they “final" methods? These won’t inject.

simonedamico commented 8 years ago

No, i'm using Stevia and it's a straight copy of their example:

class SignupSourceView: UIView {
    let label = UILabel()

    convenience init() {
        self.init(frame: CGRectZero)
        render()
    }

    func render(){
        self.backgroundColor = .blackColor()
        sv([label.text("ciao")])
        layout([50,
                |-label-|])
    }
}
johnno1962 commented 8 years ago

you’d need to do a setNeedsDisplay in an injected() method though for the change to be visible?

simonedamico commented 8 years ago

The view controller has an helper suggested by Stevia for that

    override func viewDidLoad() {
        super.viewDidLoad()

        // Here we want to reload the view after injection
        // this is only needed for live reload
        on("INJECTION_BUNDLE_NOTIFICATION") {
            self.view = SignupSourceView()
        }
    }
johnno1962 commented 8 years ago

VC and view are in different files? Otherwise you can get “complications” referring to Class initialisers

johnno1962 commented 8 years ago

Can you send me an example project to injection @ johnholdsworth.com

simonedamico commented 8 years ago

Yeah, two separate files. I sent you a copy of the project.

johnno1962 commented 8 years ago

In the finish it seems injection only worked for DEBUG builds of this project. I’ll make a note in the README.