johnno1962 / injectionforxcode

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

Getting "Application not running/connected" message at AppCode v3.3 #69

Closed aslisabanci closed 8 years ago

aslisabanci commented 8 years ago

Hi guys, I can get Injection working at Xcode 7, with a Swift project and I'm excited to try the plugin at AppCode v3.3, too. So far I couldn't get this working and here's what I'm doing:

#ifdef DEBUG
#define INJECTION_PORT 31444 // AppCode
static char _inMainFilePath[] = __FILE__;
static const char *_inIPAddresses[] = {"172.19.7.24", 0};

#define INJECTION_ENABLED
#import "/Users/aslisabanci/Library/Application Support/Developer/Shared/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources//BundleInjection.h"
#endif

I choose Debug, the project starts in the simulator, I make my changes in the code and select Inject Source from the Run menu, to inject the new code. Then I get an error saying "Application not running/connected". Can you tell me how I can fix this?

Btw, thanks a lot for sharing this plugin with the community and keep up the good work! :]

johnno1962 commented 8 years ago

Hi, you seem to be doing all thie right things and you should be getting a message such as the following in the console as the app tries to connect:

2016-01-03 17:23:17.430 zapp[75117:4436375] +[BundleInjection load] 192.168.1.4 (see project's main.(m|mm) 2016-01-03 17:23:17.436 zapp[75117:4436421] Injection attempting connection to: 127.0.0.1:31444 2016-01-03 17:23:17.439 zapp[75117:4436421] Connected to "Injection" plugin, ready to load x86_64 code.

is DEBUG #defined in your project build?

aslisabanci commented 8 years ago

Hi @johnno1962, thanks for the reply. Yes, under Apple LLVM 7.0 - Preprocessing settings, under Preprocessor Macros -> Debug, I see DEBUG = 1 and I'm running the project in Debug scheme so this definition must be in action. Also, I guess Xcode requires this DEBUG definition too right? If so, this shouldn't be the problem because I can run the Injection plugin with Xcode.

johnno1962 commented 8 years ago

Are you getting the message I mentioned in the console though? If so it should be connecting, if not the #ifdef DEBUG is most likely the problem. Try removing it.

aslisabanci commented 8 years ago

I wasn't getting that message but now, after removing the #ifdef DEBUG line and adding main.m file to the project's files (I didn't need to add main.m to the project with Xcode btw, it was enough that it existed on the project's folder), I could get past the connection issue and now I can see the console log:

+[BundleInjection load] 192.168.2.190 (see project's main.(m|mm)
Injection attempting connection to: 127.0.0.1:31444
Connected to "Injection" plugin, ready to load x86_64 code.

Now for the next step I have another problem though. When I change a piece of code and try to inject this, I get an error saying that:

Injection: Use of uninitialized value $logDir in -d at /Users/aslisabanci/Library/Application Support/Developer/Shared/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/injectSource.pl line 30.
Injection: 
Injection: *** Could not locate compile command for /Users/aslisabanci/Desktop/X/X/Views/Intro/IntroViewController.swift
Injection: If you have switched xcode versions, please cmd-shift-k to clean then rebuild the project so there is a complete build history logged and try again.
Injection: iOSInjectionProject/x86_64/learnt_commands.gz ***
Injection: 
Injection:  at /Users/aslisabanci/Library/Application Support/Developer/Shared/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/common.pm line 55.
Injection:  main::error('Could not locate compile command for /Users/aslisabanci/Deskt...') called at /Users/aslisabanci/Library/Application Support/Developer/Shared/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/injectSource.pl line 236

Btw, I installed the plugin by downloading the source code and building the InjectionPlugin.xcodeproj myself. My DerivedData build location is Unique. I can compile my generated InjectionBundle.xcodeproj just fine. Here is what my BundleContents.m file looks like:

/*
    Generated for Injection of class implementations
*/

#define INJECTION_NOIMPL
#define INJECTION_BUNDLE InjectionBundle3

#define INJECTION_ENABLED
#import "/tmp/injectionforxcode/BundleInjection.h"

#undef _instatic
#define _instatic extern

#undef _inglobal
#define _inglobal extern

#undef _inval
#define _inval( _val... ) /* = _val */

#import "BundleContents.h"

extern
#if __cplusplus
"C" {
#endif
    int injectionHook(void);
#if __cplusplus
};
#endif

@interface InjectionBundle3 : NSObject
@end
@implementation InjectionBundle3

+ (void)load {
    Class bundleInjection = NSClassFromString(@"BundleInjection");
    [bundleInjection autoLoadedNotify:0 hook:(void *)injectionHook];
}

@end

int injectionHook() {
    NSLog( @"injectionHook():" );
    [InjectionBundle3 load];
    return YES;
}

I couldn't trace what I'm missing to get AppCode find this "compile command". And many thanks for your support so far!

johnno1962 commented 8 years ago

Not sure what the problem is now. it’s effectively grepping for the filename in iOSInjectionProject/x86_64/learnt_commands.gz which is a modified log of an xcodebuild on your project. Try removing the iOSInjectionProject and injecting again. If this log doesn’t contain the swift file you are trying to inject it doesn’t know how to compile the source.

aslisabanci commented 8 years ago

Ok, I removed IOSInjectionProject, re-injected some code and here's the console log:

Injection: Use of uninitialized value $logDir in -d at /Users/aslisabanci/Library/Application Support/Developer/Shared/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/injectSource.pl line 30.
Injection: Copying iOSBundleTemplate into project.
Injection: Learning compilations for files in project: xcodebuild  -configuration Debug -arch x86_64 -sdk iphonesimulator
Injection: Use of uninitialized value $file in substitution (s///) at /Users/aslisabanci/Library/Application Support/Developer/Shared/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/injectSource.pl line 169, <GEN3> line 439.
Injection: Use of uninitialized value $file in substitution (s///) at /Users/aslisabanci/Library/Application Support/Developer/Shared/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/injectSource.pl line 169, <GEN3> line 446.
Injection: Use of uninitialized value $file in substitution (s///) at /Users/aslisabanci/Library/Application Support/Developer/Shared/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/injectSource.pl line 169, <GEN3> line 453.
Injection: Use of uninitialized value $file in substitution (s///) at /Users/aslisabanci/Library/Application Support/Developer/Shared/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/injectSource.pl line 169, <GEN3> line 460.
Injection: 
Injection: *** Could not locate compile command for /Users/aslisabanci/Desktop/X/X/Views/Intro/IntroViewController.swift
Injection: If you have switched xcode versions, please cmd-shift-k to clean then rebuild the project so there is a complete build history logged and try again.
Injection: iOSInjectionProject/x86_64/learnt_commands.gz ***
Injection: 
Injection:  at /Users/aslisabanci/Library/Application Support/Developer/Shared/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/common.pm line 55.
Injection:  main::error('Could not locate compile command for /Users/aslisabanci/Deskt...') called at /Users/aslisabanci/Library/Application Support/Developer/Shared/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/injectSource.pl line 236

I checked learnt_commands file, and /Users/aslisabanci/Desktop/X/X/Views/Intro/IntroViewController.swift is contained in that, so I couldn't get something from this. Do you have any ideas about what else I can check?

johnno1962 commented 8 years ago

The line involved is this from injectSource.pl

            while ( my $line = <LOG> ) {
                if ( index( $line, $filename ) != -1 && index( $line, " $arch" ) != -1 &&
                    $line =~ m!@{[$xcodeApp||""]}/Contents/Developer/Toolchains/XcodeDefault\.xctoolchain.+?@{[
                            $isSwift ? " -primary-file ": " -c "
                        ]}("$selectedFile"|\Q$escaped\E)! ) {
                    $learnt .= ($learnt?';;':'').$line;
                    last FOUND;
                }
            }

We need to work out why that is not matching from iOSInjectionProject/x86_64/learnt_commands.gz. You could send me this file to injectionforxcode at johnholdsworth.com and I could atke a look

aslisabanci commented 8 years ago

I emailed the file to you @johnno1962, just checking to make sure you got it and if you like any other input from my side I'd happily help.

johnno1962 commented 8 years ago

Hi I got your email thanks. Did you not get my replies? I was asking if you could send me the output of:

xcodebuild clean; xcodebuild -configuration Debug -arch x86_64 -sdk iphonesimulator >/tmp/a.txt

as the file you sent is missing commands to build certain classes.

johnno1962 commented 8 years ago

Thanks for the info on this problem. I’ve taken a different tack for using injection for AppCode now that xcodebuild has changed with Xcode 7.2. It now creates a symbolic link to the logs directory for AppCode to process them in the same way as Xcode. Do you want to try the new version? You’ll need to inject a particular project with Xcode before you can inject with AppCode though it should be more reliable.

aslisabanci commented 8 years ago

My pleasure :) Yes of course, I'd be happy to try the new version and let you know how it goes.

aslisabanci commented 8 years ago

Hey @johnno1962, wanted to let you know that the new version is working fine with AppCode and I can inject new code. Thanks for your efforts! :beers: