IOS dynamic hotfix
Warnning
Purely technical sharing, welcome to Github like. https://github.com/dKingbin/DynamicOCCopy the code
preface
IOS hotfixes were also put on hold after the JSPatch incident. Bang God mentioned in “JSPatch — Dynamic Update of iOS APP” that in order to comply with Apple’s rules, the executable code cannot be dynamically issued as mentioned in 3.3.2 of “Apple Developer Program License Agreement”. JSPatch specifically around the JS circle, so as to achieve the curve to save the country, to achieve the hot update scheme. However, it turns out that Apple doesn’t approve of this solution either, and the fundamental reason is that JSPath goes too far in supporting most OC/C syntax.
thinking
Now that JSPatch’s detour from JS has been rejected by Apple, it’s time to go back to square one and start again. I think there is at least one sufficient condition for a new framework or new scheme, but it should not be too extreme. As objective-C is a dynamic language, it is normal to be able to dynamically execute all OC syntax, and frameworks like Aspects are approved by Apple. Whether you need to run all C functions is debatable. The second is to abandon javascript/ Lua and similar languages as updated scripts in favor of native Objective-C as the updated scripting language.
Run C functions dynamically
C language has no reflection mechanism. As a compiled language, machine code is generated during compilation. So if you want to get a pointer to a function from a string, there are roughly two methods:
- Create a mapping table, the function name and function pointer to create a mapping table.
- Dlsym, according to the dynamic link library operation handle and symbol, return the corresponding symbol address.
The second approach is the one currently being adopted by JSPatch and is, of course, being warned by Apple. Dlsym is very powerful and is the optimal solution for getting Pointers to functions. The first is very limited, but does not use dark magic.
Adopt Objective-C as the updated scripting language
Direct parsing of Objective-C syntax via Flex/yACC, no scripting languages like JS/Lua.
DynamicOC
As a result of this thinking, I recently worked on DynamicOC in my spare time, which has 100% native support for using Objective-C as the updated scripting language. Of course, running C functions dynamically still uses dlSYM to obtain function Pointers, which will gradually change to the mapping table.
The principle of
DynamicOC uses Flex/yACC for lexical analysis and syntax analysis, and is converted into a syntax spanning tree AST. The corresponding code is then executed by parsing each node. Because you use Objective-C as the scripting language, it’s easy to adapt.
Functional features
- Execute OC code dynamically
- Dynamically execute C functions and block asynchronous calls
- Dynamically adding properties
- Dynamic substitution method
- Dynamic addition method
- There are good unit tests
- Flex/yACC implements a powerful OC syntax parser
- Support CGRect/CGSize/CGPoint/NSRange/UIEdgeInsets/CGAffineTransform structure commonly used…
Basic usage
Dynamically executing blocks
NSString* text = @" \ __block int result = 0; \ UIView* view = [[UIView alloc]init]; \ void(^blk)(int value) = ^(int value){\ view.tag = value; The \}; \ blk(1024); \ return view.tag;";
ASTNode* root = [ASTUtil parseString:text];
ASTVariable* result = [root execute];
NSAssert([result.value doubleValue] == 1024, nil);
Copy the code
Dynamically execute C functions
int echo(int value) {
return value;
}
NSString* text = @" \
[OCCfuntionHelper defineCFunction:@\"echo\" types:@\"int, int\"]; \
return echo(1024);";
ASTNode* root = [ASTUtil parseString:text];
ASTVariable* result = [root execute];
NSAssert([result.value doubleValue] == 1024, nil);
Copy the code
Dynamically adding Property
NSString* text = @" \ [OCCfuntionHelper defineCFunction:@\"objc_setAssociatedObject\" types:@\"void,id,void *,id,unsigned int\"]; \ [OCCfuntionHelper defineCFunction:@\"objc_getAssociatedObject\" types:@\"id,id,void *\"]; \ NSString* key = @\"key\"; \ objc_setAssociatedObject(self, key, @(1024), 1); \ return objc_getAssociatedObject(self, key);";
ASTNode* root = [ASTUtil parseString:text];
ASTVariable* result = [root execute];
NSAssert([result.value doubleValue] == 1024, nil);
Copy the code
Supported syntax
- if/else while do/while for
- return break continue
- i++ i– ++i –i
- +i -i ! i
- + – * / % and other four operations
- > > < < & | ^ allelic operations
- && | | > = < =! = > < and so on
- ? :
- __block
- array[i] dict[@””]
- @ 666 @ () @ @ [] {}
- self super
- self.property
- self->_property
- most of objective-c keyword
TODO
- @available()
- [NSString stringWithFormat:”%d”,value] : use [NSString stringWithFormat:”%@”,@(value)] instead.
- dispatch_async / dispatch_after …
- *stop =YES, in block
- fix bugs
Github link here: DynmaicOC, feel helpful can click a star oh! Thank you very much!
Refer to the link
JSPatch — Dynamically update iOS apps
The story of iOS dynamics
Apple Developer Program License Agreement
Didi iOS DynamicCocoa was born and set sail