-
Notifications
You must be signed in to change notification settings - Fork 16
Install and Usage Tutorial
- Clone the repo and go into it.
git clone https://github.com/Soulghost/Dyamk
cd Dyamk
- Run
install.sh
, it needs root to mkdir in /opt, you can check if it is safe by your self.
sh install.sh
- Some scripts are written in Python3, so you needs Python3 environment, if you don't have it, try pyenv.
- copy the
DyamkClient.podspec
andDyamk
dir to your app's root dir, make sure these two files are in the same location, then you can use CocoaPods to install it.
pod 'DyamkClient', :path => '../DyamkClient.podspec'
- open the
DyamkInjector.xcodeproj
with Xcode in theDyamkInjector
dir. - change the build target to
Build Me
. - open the
Build Settings
tab, and select the targetBuildMe
, find the configuration keyDYAMK_PYTHON3_PATH
and change it to your python3 path, you can usewhich python3
in the shell to find it.
#import <DyamkClient/DYAEngine.h>
// ...
- (void)someEntryInHostAppToInject {
[super viewDidLoad];
self.dyaEngine = [[DYAEngine alloc] init];
NSError *dyaError = nil;
[self.dyaEngine startAtPort:2224 error:&dyaError];
if (dyaError) {
NSLog(@"Error: %@", dyaError);
} else {
NSLog(@"DYA Server start at 2224");
}
}
All of your code should go in the DyamkCodePlayground
class in the DyamkInjector
Project, there is a __dyamk_debug_code_goes_here
function for you, you can think it as the main function for your dylib.
void __dyamk_debug_code_goes_here() {
// your code
}
Because the dylib will be inject and run again and again, so we needs to clear up the context everytime, so we would better create a new controller and dismiss the last one each time, there is a method in DyamkUIAspectTool
for you to create and find controllers.
You can create a new controller by call dya_presentControllerForDebug
function like this, and as you can see, we named the controller "self" to simulator we are work in the controller itself.
void __dyamk_debug_code_goes_here() {
UIViewController *self = dya_presentControllerForDebug();
self.view.backgroundColor = [UIColor lightGrayColor];
}
You can use Dyamk_Method_N
macro function to create a method's imp, a Dyamk_Method_N
recevies 2 + 2*N
params, they are: return type, name and param list.
such as Dyamk_Method_2.
// declare
Dyamk_Method_2(return_value_type, function_name, param1_type, param1_name, param2_type, param2_name);
// usage
Dyamk_Method_2(int, add, int, a, int, b) {
return a + b;
}
Then you can use Dyamk_AddMethod
to add it to a class.
The Dyamk_AddMethod
macro function using objc runtime to add or replace an instance method.
// declare
Dyamk_AddMethod(class_name, SEL, function_name, type_encoding);
// usage
Dyamk_AddMethod(SomeClass, @selector(add::), add, v@:ii);
The function will add a prefix for the function and convert a C or C++ function to an IMP for the objc message resolving, and the last param is type encoding for objc runtime, you can learn it from https://nshipster.com/type-encodings/.
//
// DyamkCodePlayground.m
// DyamkInjector
//
#import <UIKit/UIKit.h>
#import "DyamkUIAspectTool.h"
#import <objc/runtime.h>
#import "DyamkEventTool.h"
Dyamk_Method_1(void, onClick, id, sender) {
NSLog(@"sender is %@", sender);
// add btn's event handle goes here
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
void __dyamk_debug_code_goes_here() {
UIViewController *self = dya_presentControllerForDebug();
UIButton *addBtn = [UIButton buttonWithType:UIButtonTypeContactAdd];
addBtn.center = self.view.center;
Dyamk_AddMethod(UIViewController, @selector(addClick:), onClick, v@:@);
[addBtn addTarget:self action:@selector(addClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:addBtn];
}
#pragma clang diagnostic pop