Skip to content
junzhan edited this page Dec 18, 2015 · 1 revision

Use Wax in Swift

  • install Wax
  • create Bridging-Header, add #import <wax/wax.h>
  • if you start wax in Swift code ,you should use wax_startWithNil()
  • SwiftExample

How to hook, invoke Swift method

  • waxClass should add Swift module name,like:
waxClass{"SwiftExample.TestSwiftVC"}

function viewDidLoad(self)
	print("lua viewDidLoad");
	self:ORIGviewDidLoad();
end
  • invoke class methd should use objc_getClass(use luaSetWaxConfig({openBindOCFunction='true'})before call objc_getClass), like:
objc_getClass("SwiftExample.TestSwiftVC"):testClassReturnVoidWithaId(self:view())
  • create Swift instance
local vc = objc_getClass("SwiftExample.TestBSwiftVC"):initWithNibName_bundle("TestBSwiftVC", nil);
local a = objc_getClass("SwiftExample.TestASwiftClass"):init()

hook failed?

Pure Swift (no inheritance from NSObject) itself does not have runtime characteristics, function call at compile time has been determined, so pure Swift method can not be dynamic hooked. But Swift is compatible with Objective-c, the @objc and @dynamic is added to make the method can be runtime called. Therefore, we need to do the following steps:

  • Swift class should inherit NSObject
  • Swift method and property should add @dynamic in front (methods inherited from Objective-c don't need , but some Swift specific types such as Character, Tuple can not add @dynamic, which will compile error)

like:

class TestASwiftClass :NSObject{
    dynamic var aBool:Bool = true;
    dynamic var aInt:UInt = 0;
    dynamic var aDouble:Double = 1234.567;
    
    dynamic func testReturnVoidWithaId(aId:UIView){
        print("F:\(__FUNCTION__) L:\(__LINE__)");
        self.performSelector(Selector("testNoExistMethod"));
    }
}

class TestSwiftVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
    dynamic var aString:String = "abc";
    dynamic var aObject:AnyObject! = nil;
    
    override func viewDidLoad() {
    }
    override func viewDidAppear(animated: Bool) {
    }
    dynamic func callTestASwiftClass(){
    }
    
    dynamic func setupTableView(){
    }
}

PS: add @dynamic in front of Swift methd is ugly, if there is a better way, please let me know, Thanks!

Clone this wiki locally