johnno1962 / injectionforxcode

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

Dosn't work in Xcode 9 when using Swift. Does work in Xcode 9 using Objective-C. #224

Closed MathiasHH closed 6 years ago

MathiasHH commented 6 years ago

I got the software, http://johnholdsworth.com/Injection9.app.zip, and installed it.

In Swift the function: func injected() { print("I've been injected: (self)") } dosn't get called, when I type ^=

In Objective-C the function: (void)injected { NSLog(@"I've been injected: %@", self); } does get called when I type ^=

johnno1962 commented 6 years ago

I think you need @objc func injected() these days.. Injection uses the Objective-C runtime.

MathiasHH commented 6 years ago

It dosn't seem to work. Do you have an example somewhere where you use Xcode 9 and Swift with injectionforxcode?

johnno1962 commented 6 years ago

Is the class final? Is it a struct?

MathiasHH commented 6 years ago

A UIViewController:

import UIKit

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
}

@objc func injected() { print("I've been injected: (self)") } }

johnno1962 commented 6 years ago

Did Xcode 8 work for you with Swift?

johnno1962 commented 6 years ago

I’ve checked my end and I can make a simple master/detail example that injects and logs an injected method. I’ve refreshed the Xcode 9 version of injection if you want to give it a try: http://johnholdsworth.com/injection.html

Rnorback commented 6 years ago

Hi John, I'm having the same problem with Xcode 9. Everything works great on xcode 8. Here's the exact error I'm getting on 9.

CoreSimulator detected Xcode.app relocation or CoreSimulatorService version change. Framework path (/Applications/Xcode.app/Contents/Developer/Library/PrivateFrameworks/CoreSimulator.framework) and version (375.21) does not match existing job path (/Library/Developer/PrivateFrameworks/CoreSimulator.framework/Versions/A/XPCServices/com.apple.CoreSimulator.CoreSimulatorService.xpc) and version (494.13.6). Attempting to remove the stale service in order to add the expected version.
Can’t call method “print” on an undefined value at /Users/robnorback/Desktop/Injection 3.app/Contents/Resources/injectSource.pl line 149.

Every error message I get tells me the simulator path is incorrect. Do I need to do some extra setup for this?

polac24 commented 6 years ago

Hi @Rnorback ! I had same issue with "relocation". Maybe it will solve your problem:

MathiasHH commented 6 years ago

I didn't try with Xcode 8.

The new version, http://johnholdsworth.com/Injection9.app.zip, does work with Xcode 9 and Swift.

Thanks a lot.

Rnorback commented 6 years ago

This command solved it for me

sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer

songxing10000 commented 6 years ago

Injection: Injection attempting connection to: 127.0.0.1:31452 Injection: Connected to "Injection" plugin, ready to load x86_64 code. Compiling /Users/dfpo/Desktop/ffff/ffff/ViewController.m 0.06 real 0.02 user 0.02 sys Injection: Loading /Users/dfpo/Library/Developer/Xcode/DerivedData/ffff-cwkubzzyiasrnhbioafsmaksvmsv/Logs/iOSInjectionProject/build/Debug-iphonesimulator/InjectionBundle1.bundle objc[19288]: Class ViewController is implemented in both /Users/dfpo/Library/Developer/CoreSimulator/Devices/1132FF26-672A-4CAA-8C46-54FC0D46435D/data/Containers/Bundle/Application/D6DE8BAC-1F65-43ED-AB01-CCFE468B74B5/ffff.app/ffff (0x10ad81e98) and /Users/dfpo/Library/Developer/Xcode/DerivedData/ffff-cwkubzzyiasrnhbioafsmaksvmsv/Logs/iOSInjectionProject/build/Debug-iphonesimulator/InjectionBundle1.bundle/InjectionBundle (0x123f002d0). One of the two will be used. Which one is undefined. 3 injections performed so far. Injection: Ignore any warning, Swizzled ViewController 0x123f002d0 -> 0x10ad81e98

johnno1962 commented 6 years ago

That's what it looks like when injection is working.

suadbay commented 6 years ago

I get the same thing with @songxing10000 , but the simulator does not update itself, the views?

johnno1962 commented 6 years ago

You need to re-open the View controller or call viewDidLoad: on your viewController class to have the views update. This is generally done from inside an “@objc injected()” method in your class.

songxing10000 commented 6 years ago

@johnno1962 do you mean I should pop the viewController and then push this viewController to see the the code change on this viewController effect

songxing10000 commented 6 years ago

get it


@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

}
- (void)injected {

     self.view.backgroundColor = [UIColor whiteColor];

}

@end

your code should put in method injected