Usage of defineClass

JerryCat edited this page Jul 1, 2016 · 2 revisions

API

defineClass(classDeclaration, instanceMethods, classMethods)

@param classDeclaration: class name, super classname and protocols
@param instanceMethods: instance methods you want to override or add
@param classMethods: class methods you want to override or add

Replace Existing Method

1.Use _ to separate multiple params:

// OC
@implementation JPTestObject
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
@end
// JS
defineClass("JPTableViewController", {
  tableView_didSelectRowAtIndexPath: function(tableView, indexPath) {
    ...
  },
})

2.Use __ to represent _ in the Objective-C method name:

// OC
@implementation JPTableViewController
- (NSArray *) _dataSource {
}
@end
// JS
defineClass("JPTableViewController", {
  __dataSource: function() {
  },
})

3.Call original method by adding prefix ORIG to the method name.

// OC
@implementation JPTableViewController
- (void) viewDidLoad {
}
@end
// JS
defineClass("JPTableViewController", {
  viewDidLoad: function() {
     self.ORIGviewDidLoad();
  },
})

Super / Property / Member variables

1.Use self.super() to call super methods.

// JS
defineClass("JPTableViewController", {
  viewDidLoad: function() {
     self.super().viewDidLoad();
  }
})

2.Call methods to get / set existing property

// OC
@interface JPTableViewController
@property (nonatomic) NSArray *data;
@end
@implementation JPTableViewController
@end
// JS
defineClass("JPTableViewController", {
  viewDidLoad: function() {
     var data = self.data()     //get property value
     self.setData(data.toJS().push("JSPatch"))     //set property value
  },
})

3.Use getProp() and setProp_forKey() to get / set new property

// OC
@interface JPTableViewController
@end
@implementation JPTableViewController
@end
// JS
defineClass("JPTableViewController", {
  init: function() {
     self = self.super().init()
     self.setProp_forKey("JSPatch", "data")     //add new property (id data)
     return self;
  }
  viewDidLoad: function() {
     var data = self.getProp("data")     //get the new property value
  },
})

4.Use valueForKey() and setValue_forKey() to get / set member variables

// OC
@implementation JPTableViewController {
     NSArray *_data;
}
@end
// JS
defineClass("JPTableViewController", {
  viewDidLoad: function() {
     var data = self.valueForKey("_data")     //get member variables
     self.setValue_forKey(["JSPatch"], "_data")     //set member variables
  },
})

Add New Methods

You can add new methods to the existing Class, if you want to call the new method in Objective-C, all the params type is id.

// OC
@implementation JPTableViewController
- (void)viewDidLoad
{
     NSString* data = [self dataAtIndex:@(1)];
     NSLog(@"%@", data);      //output: Patch
}
@end
// JS
var data = ["JS", "Patch"]
defineClass("JPTableViewController", {
  dataAtIndex: function(idx) {
     return idx < data.length ? data[idx]: ""
  }
})

Protocol

You can make class conforms to protocols:

defineClass("JPViewController: UIViewController<UIScrollViewDelegate, UITextViewDelegate>", {

})

If you want to add method that defined in protocol and params or return types is not id, you must conforms to the protocol.

@protocol UIAlertViewDelegate <NSObject>
...
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
...
@end
defineClass("JPViewController: UIViewController <UIAlertViewDelegate>", {
  viewDidAppear: function(animated) {
    var alertView = require('UIAlertView')
      .alloc()
      .initWithTitle_message_delegate_cancelButtonTitle_otherButtonTitles(
        "Alert",
        self.dataSource().objectAtIndex(indexPath.row()), 
        self, 
        "OK", 
        null
      )
     alertView.show()
  }
  alertView_clickedButtonAtIndex: function(alertView, buttonIndex) {
    console.log('clicked index ' + buttonIndex)
  }
})