- Notifications
You must be signed in to change notification settings - Fork2.2k
JSPatch bridge Objective-C and Javascript using the Objective-C runtime. You can call any Objective-C class and method in JavaScript by just including a small engine. JSPatch is generally used to hotfix iOS App.
License
bang590/JSPatch
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
请大家不要自行接入 JSPatch,统一接入 JSPatch 平台,让热修复在一个安全和可控的环境下使用。原因详见这里
JSPatch bridges Objective-C and JavaScript using the Objective-C runtime. You can call any Objective-C class and method in JavaScript by just including a small engine. That makes the APP obtaining the power of script language: add modules or replacing Objective-C code to fix bugs dynamically.
JSPatch is still in development, welcome to improve the project together.
Notice: Please go toWiki to get full document.
@implementationAppDelegate- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [JPEnginestartEngine];NSString *sourcePath = [[NSBundlemainBundle]pathForResource:@"demo"ofType:@"js"];NSString *script = [NSStringstringWithContentsOfFile:sourcePathencoding:NSUTF8StringEncodingerror:nil]; [JPEngineevaluateScript:script]; self.window = [[UIWindowalloc]initWithFrame:[UIScreenmainScreen].bounds]; [self.windowaddSubview:[selfgenView]]; [self.windowmakeKeyAndVisible];returnYES;}- (UIView *)genView{return [[UIViewalloc]initWithFrame:CGRectMake(0,0,320,320)];}@end
// demo.jsrequire('UIView, UIColor, UILabel')defineClass('AppDelegate',{// replace the -genView methodgenView:function(){varview=self.ORIGgenView();view.setBackgroundColor(UIColor.greenColor())varlabel=UILabel.alloc().initWithFrame(view.frame());label.setText("JSPatch");label.setTextAlignment(1);view.addSubview(label);returnview;}});
You can also try to useJSPatch Convertor to convertor code from Objective-C to JavaScript automatically.
CocoaPods is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like JSPatch in your projects. See the"Getting Started" guide for more information.
# Your Podfileplatform:ios,'6.0'pod'JSPatch'
CopyJSEngine.m
JSEngine.h
JSPatch.js
inJSPatch/
to your project.
#import "JPEngine.h"
- call
[JPEngine startEngine]
- exec JavasScript by
[JPEngine evaluateScript:@""]
[JPEnginestartEngine];// exec js directly[JPEngineevaluateScript:@"\ var alertView = require('UIAlertView').alloc().init();\ alertView.setTitle('Alert');\ alertView.setMessage('AlertView from js'); \ alertView.addButtonWithTitle('OK');\ alertView.show(); \"];// exec js file from network[NSURLConnectionsendAsynchronousRequest:[NSURLRequestrequestWithURL:[NSURLURLWithString:@"http://cnbang.net/test.js"]]queue:[NSOperationQueuemainQueue]completionHandler:^(NSURLResponse *response,NSData *data,NSError *connectionError) {NSString *script = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding]; [JPEngineevaluateScript:script];}];// exec local js fileNSString *sourcePath = [[NSBundlemainBundle]pathForResource:@"sample"ofType:@"js"];NSString *script = [NSStringstringWithContentsOfFile:sourcePathencoding:NSUTF8StringEncodingerror:nil];[JPEngineevaluateScript:script];
//requirerequire('UIView, UIColor, UISlider, NSIndexPath')// Invoke class methodvarredColor=UIColor.redColor();// Invoke instance methodvarview=UIView.alloc().init();view.setNeedsLayout();// set proertyview.setBackgroundColor(redColor);// get propertyvarbgColor=view.backgroundColor();// multi-params method (use underline to separate)// OC:NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:1];varindexPath=NSIndexPath.indexPathForRow_inSection(0,1);// method name contains underline (use double undeline to represent)// OC: [JPObject _privateMethod];JPObject.__privateMethod()// use .toJS() to convert NSArray / NSString / NSDictionary to JS type.vararr=require('NSMutableArray').alloc().init()arr.addObject("JS")jsArr=arr.toJS()console.log(jsArr.push("Patch").join(''))//output: JSPatch// use hashes to represent struct like CGRect / CGSize / CGPoint / NSRangevarview=UIView.alloc().initWithFrame({x:20,y:20,width:100,height:100});varx=view.bounds().x;// wrap function with `block()` when passing block from JS to OC// OC Method: + (void)request:(void(^)(NSString *content, BOOL success))callbackrequire('JPObject').request(block("NSString *, BOOL",function(ctn,succ){if(succ)log(ctn)}));// GCDdispatch_after(1.0,function(){// do something})dispatch_async_main(function(){// do something})
Go to wiki page for more details:Base Usage
You can redefine an existing class and override methods.
// OC@implementationJPTableViewController...- (void)tableView:(UITableView *)tableViewdidSelectRowAtIndexPath:(NSIndexPath *)indexPath{NSString *content = self.dataSource[[indexPathrow]];//may cause out of bound JPViewController *ctrl = [[JPViewControlleralloc]initWithContent:content]; [self.navigationControllerpushViewController:ctrl];}- (NSArray *)dataSource{return @[@"JSPatch",@"is"];}- (void)customMethod{NSLog(@"callCustom method")}@end
// JSdefineClass("JPTableViewController", {// instance method definitions tableView_didSelectRowAtIndexPath:function(tableView, indexPath) { var row = indexPath.row()if (self.dataSource().count() > row) {//fix the out of bound bug here var content = self.dataSource().objectAtIndex(row); var ctrl = JPViewController.alloc().initWithContent(content); self.navigationController().pushViewController(ctrl); } }, dataSource:function() {// get the original method by adding prefix 'ORIG' var data = self.ORIGdataSource().toJS();return data.push('Good!'); }}, {})
Go to wiki page for more details:Usage of defineClass
There are some extensions provide support for custom struct type, C methods and other functional, call+addExtensions:
after starting engine to add extensions:
@implementationAppDelegate- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [JPEnginestartEngine];//add extensions after startEngine [JPEngineaddExtensions:@[@"JPInclude",@"JPCGTransform"]];NSString *sourcePath = [[NSBundlemainBundle]pathForResource:@"demo"ofType:@"js"];NSString *script = [NSStringstringWithContentsOfFile:sourcePathencoding:NSUTF8StringEncodingerror:nil]; [JPEngineevaluateScript:script];}@end
include('test.js')//include function provide by JPInclude.mvarview=require('UIView').alloc().init()//CGAffineTransform is supported in JPCGTransform.mview.setTransform({a:1,b:0,c:0,d:1,tx:0,ty:100})
Extensions can be added dynamiclly in JS, which is recommended:
require('JPEngine').addExtensions(['JPInclude','JPCGTransform'])// `include()` and `CGAffineTransform` is avaliable now.
You can create your own extension to support custom struct type and C methods in project, see the wiki page for more details:Adding new extensions
- iOS 7+, forward compatibility with iOS 6
- JavaScriptCore.framework
- Support armv7/armv7s/arm64
About
JSPatch bridge Objective-C and Javascript using the Objective-C runtime. You can call any Objective-C class and method in JavaScript by just including a small engine. JSPatch is generally used to hotfix iOS App.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.