Hot Code Swapping in Xcode?
Asked Answered
W

4

14

I am doing iOS game development using the cocos2d framework, and I tremendously envy the ability for Eclipse Java programmers to hot swap their code while they are debugging their application (i.e. change out variable values within a method and have the program live update as if you had a REPL without having to recompile).

This seems like something that would be absolutely tremendously helpful when it came to iOS development, where my development environment is (obviously) Xcode and the language I am programming in is Objective C. I have googled around but havent been able to find anything - so I thought I would ask the community.

Does anyone know if there a way to Hot Swap code in Xcode while programming in Objective C?

Thanks in advance

Wherefrom answered 17/4, 2012 at 17:35 Comment(3)
Xcode used to have this but IIRC it was slow and unreliable and people just didn't use it, so Apple killed the feature to focus on just making the debugger better.Frech
Thats a shame, do you know of any debugging features that provide similar / equivalent functionality? Im trying to reduce the number of times I change a variable and rebuild and run just to see if its the right number (game dev is a lot of trial and error)Wherefrom
If it's in a variable, you can just edit its value in the debugger.Invocate
D
11

Not possible with the current tools.

Keep in mind that iOS applications are signed -- if you change a single byte you'd have resign the whole thing. One could imagine making it work using runtime's support for dynamically adding and removing methods. But that'd surely require adding some extra stuff to support it on the device, and that's something that malware could easily take advantage of. So it's probably not a feature you'll be likely to see anytime soon.

By the way, Xcode versions 1.x-3.x did have a "Fix and Continue" feature. You could edit as you were debugging, use the Fix and Continue command, and continue running the updated code. I believe it was removed at some point, perhaps due to some combination of: requiring that your project be configured to use "zero link" and perhaps some other things; being less than completely reliable; probably not supporting iOS; the switch to llvm; other changes in Xcode 4. Maybe it'll come back someday -- if you want it back, file a bug -- but again, I think supporting it on iOS would be a challenge.

Demeter answered 17/4, 2012 at 17:48 Comment(1)
This answer seems to be outdated. @bartosz-hernas answer pointed me towards what seems to be an XCode 7.1 compatible solution: InjectionPlugin.Category
K
14

There is a great plugin which allow changing code in live, working APP. It is called InjectionPlugin.

As FAQ says:

How does it work? The Objective-C runtime allows you to load a new version of a class into an application using a bundle even if there is already an implementation linked into the application. Swizzling is used as the bundle is loaded to switch the existing class to use the methods of the new implementation. This can be done repeatedly and works for OSX and iOS applications and on iOS devices.

I made some small video which shows how to install and use this plugin http://nomtek.com/developers/how-to-install-and-use-injection-plugin-for-xcode/

Hope it helps!

Kreg answered 9/5, 2013 at 13:57 Comment(0)
D
11

Not possible with the current tools.

Keep in mind that iOS applications are signed -- if you change a single byte you'd have resign the whole thing. One could imagine making it work using runtime's support for dynamically adding and removing methods. But that'd surely require adding some extra stuff to support it on the device, and that's something that malware could easily take advantage of. So it's probably not a feature you'll be likely to see anytime soon.

By the way, Xcode versions 1.x-3.x did have a "Fix and Continue" feature. You could edit as you were debugging, use the Fix and Continue command, and continue running the updated code. I believe it was removed at some point, perhaps due to some combination of: requiring that your project be configured to use "zero link" and perhaps some other things; being less than completely reliable; probably not supporting iOS; the switch to llvm; other changes in Xcode 4. Maybe it'll come back someday -- if you want it back, file a bug -- but again, I think supporting it on iOS would be a challenge.

Demeter answered 17/4, 2012 at 17:48 Comment(1)
This answer seems to be outdated. @bartosz-hernas answer pointed me towards what seems to be an XCode 7.1 compatible solution: InjectionPlugin.Category
B
6

If you're just talking about changing variable values then you can achieve that surreptitiously via lldb (or, presumably) gdb. Supposing you had:

- (void)uselessMethod
{
    NSString *localString = @"I'm some local text";

    NSLog(@"%@", localString);
}

And put a breakpoint on the NSLog, at that point you could ask lldb to evaluate a reassignment of localString as a means of performing it. E.g.

po localString = @"Hat"

If you then allow program execution to continue, you should find that the reassignment has stuck. Similarly you can call any method or perform any other sort of assignment.

I've just tested this against Xcode 4.3.2.

Blythebm answered 17/4, 2012 at 17:53 Comment(2)
So what you are saying is that its possible within the xCode terminal (if im using lldb as the compiler - currently I was using GDB but only because that was the default), but this would involve 1) a breakpoint to be set, and 2) commands entered in the terminal which if they solved the problem, would then have to manually be moved over into the actual code. Did I understand this correctly?Wherefrom
I understood you only to be asking about changing variable values and I would assume gdb works the same as lldb in this respect. Otherwise I think you're correct; you can't edit and continue (per the Microsoft terminology, to make sure I've understood the question) as far as I'm aware.Blythebm
O
1

You can hot swap a variable value in Xcode by:

expression <variable> = <value>;.

By having a break point in the place where you wanna change the value and doing the command in Xcode console.

Example:

// Messages From Console
(lldb) expression graphFlag = @"X";    // Update variable value
(__NSCFConstantString *) $0 = 0x36f95718 @"X"  // Xcode prints the updated value
(lldb) expression graphFlag; // Printing value through expression command
(__NSCFConstantString *) $1 = 0x36f95718 @"X" // Hot Swapped variable value
Olympic answered 27/9, 2016 at 4:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.