johnno1962 / InjectionApp

Issue Tracking Repo for Injection as an App
MIT License
111 stars 7 forks source link

Unable to get injection to work with macOS app. #35

Open siegesmund opened 6 years ago

siegesmund commented 6 years ago

I've downloaded the Injection app and tried to use it with a newly created macOS project. I created the main.m file, and used the macOS menu patch option to patch it. main.m was successfully patched.

The dummy project consists of a view and a label, and all I'm trying to do is change the text on the table to see this reflected in the running application. In order to do this, I've saved the file, then used the keyboard shortcut to try to inject the update.

The result is a window displaying the error: Injection Error, simulator is not running.

MacOS 10.13 Xcode Version: 9.2 Derived data location is set to default.

johnno1962 commented 6 years ago

Does Injection connect to the app? Is anything logged. If the app is sandboxed it will need network entitlements for this connection.

siegesmund commented 6 years ago

No, nothing is logged.

I've tried setting App Sandbox to NO, and I've also tried setting com.apple.security.network.server and com.apple.security.network.client to YES. Still the same problem.

johnno1962 commented 6 years ago

Is -DDEBUG defined?

siegesmund commented 6 years ago

I’m using Swift, and the settings are the Xcode’s defaults. I looked around build settings and there were a number of debug settings, but no DDEBUG.

On Feb 20, 2018, at 12:58 PM, John Holdsworth notifications@github.com wrote:

-DDEBUG defined

johnno1962 commented 6 years ago

Look for Preprocessor Macros and add DEBUG=1 is it’s not there already. There really should be something logged.

siegesmund commented 6 years ago

It was set to that by default. So, yes, DEBUG=1 defined in Preprocessor Macros...

On Feb 20, 2018, at 1:17 PM, John Holdsworth notifications@github.com wrote:

Look for Preprocessor Macros and add DEBUG=1 is it’s not there already. There really should be something logged.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/johnno1962/InjectionApp/issues/35#issuecomment-367069162, or mute the thread https://github.com/notifications/unsubscribe-auth/ACaom9WublLcIEi7XCrBfpZlTgiheENfks5tWwxOgaJpZM4SMOZE.

siegesmund commented 6 years ago

It does log a successful patch to the injection console. But nothing to the Xcode console.

siegesmund commented 6 years ago

Also, in addition to the aforementioned error, in the optimize build console, it says: Unable to open Index DB at notfound: unable to open database file

johnno1962 commented 6 years ago

what are the contents of main.m?

siegesmund commented 6 years ago

// From here to end of file added by Injection Plugin //

ifdef DEBUG

define INJECTION_PORT 31452

static char _inMainFilePath[] = FILE; static const char *_inIPAddresses[] = {"192.168.7.20", "127.0.0.1", 0};

define INJECTION_ENABLED

import "/tmp/injectionforxcode/BundleInjection.h"

endif

On Feb 20, 2018, at 1:23 PM, John Holdsworth notifications@github.com wrote:

what are the contents of main.m?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/johnno1962/InjectionApp/issues/35#issuecomment-367070877, or mute the thread https://github.com/notifications/unsubscribe-auth/ACaom-trXUIFBIrJNYkkren-poG0HRijks5tWw2pgaJpZM4SMOZE.

johnno1962 commented 6 years ago

Can you try https://github.com/johnno1962/InjectionIII please. I’d rather support the newer version.

siegesmund commented 6 years ago

Absolutely. I’d love to use this and I really appreciate your work putting it out there and supporting it. Thank you!

I’ll give the new version a shot and see what happens.

On Feb 20, 2018, at 1:29 PM, John Holdsworth notifications@github.com wrote:

Can you try https://github.com/johnno1962/InjectionIII https://github.com/johnno1962/InjectionIII please. I’d rather support the newer version.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/johnno1962/InjectionApp/issues/35#issuecomment-367072775, or mute the thread https://github.com/notifications/unsubscribe-auth/ACaom7uJk0SfPmi8aD00UPKTVNffsdErks5tWw77gaJpZM4SMOZE.

siegesmund commented 6 years ago

So I downloaded and tried the new app. Same result - an error message saying that the simulator is not running.

siegesmund commented 6 years ago

And still nothing logged.

johnno1962 commented 6 years ago

Did you add Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/macOSInjection.bundle")?.load() to your appDidInit? This is the new "patching"

siegesmund commented 6 years ago

So that does work. I am no connected and it's logging. The logs suggest its' working correctly, but I'm not seeing a change in the app.

Log outputs are as follows:

Injection connected, watching /Users/foo/Documents/Programming/InjectionTest/... Compiling /Users/foo/Documents/Programming/InjectionTest/InjectionTest/ViewController.swift Loading /tmp/eval1.dylib. (Ignore any duplicate class warning) objc[6194]: Class _TtC13InjectionTest14ViewController is implemented in both /Users/foo/Library/Developer/Xcode/DerivedData/InjectionTest-ewblganvhtibaobplpuewjhyqkde/Build/Products/Debug/InjectionTest.app/Contents/MacOS/InjectionTest (0x100005e88) and /tmp/eval1.dylib (0x105980360). One of the two will be used. Which one is undefined. Injected 'InjectionTest.ViewController', vtable length: 64

johnno1962 commented 6 years ago

That’s what it looks like when it’s working. You’ll need to puzzle out what is happening using the limitations in the README like you can’t inject structs, final classes, possibly even using whole module optimisation doesn’t work. Start simple and work your way up.

siegesmund commented 6 years ago

Ok, thanks for the feedback. Here’s the problem I have: I’ve simply created a blank macOS app template project in Xcode and placed a text label in the middle of the default view. I’ve created an IBOutlet for the label in the sole view controller in the project. I assign it a value in viewDidLoad. When I change the value, I get log messages suggesting that the new value is being injected, but no change. There are no structs or final classes.

On Feb 20, 2018, at 5:07 PM, John Holdsworth notifications@github.com wrote:

That’s what it looks like when it’s working. You’ll need to puzzle out what is happening using the limitations in the README like you can’t inject structs, final classes, possibly even using whole module optimisation doesn’t work. Start simple and work your way up.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/johnno1962/InjectionApp/issues/35#issuecomment-367137290, or mute the thread https://github.com/notifications/unsubscribe-auth/ACaomyo5lGE9OfQ5mFpg3ZKjlL9byF7Vks5tW0IegaJpZM4SMOZE.

johnno1962 commented 6 years ago

Is viewDidLoad being called again?

siegesmund commented 6 years ago

Only on the initial compile. It’s not called on changes.

Sent from my iPhone

On Feb 20, 2018, at 6:39 PM, John Holdsworth notifications@github.com wrote:

Is viewDidLoad being called again?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

johnno1962 commented 6 years ago

If it’s not called again you need to look at an @objc injected() (which should be called when the class is injected) calling it when code is injected so you can see your code changes take effect.

siegesmund commented 6 years ago

I've tried several variations, including an @objc injected() method. injected() is not called either. Here is all of the relevant code:

ViewController:

class ViewController: NSViewController {

    @IBOutlet weak var label: NSTextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        print("Executing viewDidLoad\n")
        setup()
        // Do any additional setup after loading the view.
    }

    func setup() {
        self.label.stringValue = "Hello!"
    }

    @objc func injected() {
        print("Executing injected\n")
        viewDidLoad()
    }
}

App delegate:

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/macOSInjection.bundle")?.load()
        // Insert code here to initialize your application
    }

    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }

}

Also, App Sandbox is set to NO

johnno1962 commented 6 years ago

Can you try on thing? Make an outlet from you AppDelegate to the ViewController to see if injected() starts working? Objects need to be findable from a memory sweep starting at AppDelegate.

johnno1962 commented 6 years ago

Otherwise you can subscribe to the INJECTION_BUNDLE_NOTIFICATION to have your code called.