I have some Swift 3 code to decode an iOS Objective-C protocol (which has a Swift counterpart). After concluding Swift 3 reflection was not developed enough to accomplish what I needed, I stumbled on the objc runtime method protocol_copyMethodDescriptionList()
, which returns an array of the following C structs:
struct objc_method_description
SEL name;
char *types;
};
The code fetches a list of protocol selector names, but not sure what's being returned in the type
field. I'm confused about how to properly decode objc_method_description.type
values.
What I'm getting in the the type
fields are in a cryptic format, for example, "B48@0:8@16{_NSRange=QQ}24@40"
At first I thought it was a problem in how I was converting C strings, but after some study, I suspect it actually is an encoding of the parameters, similar how Java's JVM passes around method signatures. But I still have no reference by which to decode it.
import UIKit
class ViewController: UIViewController, UITextViewDelegate {
@IBOutlet weak var noteView : UITextView!
func decodeProto() {
var methodCount : UInt32 = 1
if let methodList = protocol_copyMethodDescriptionList(UITextViewDelegate.self,
false, true, UnsafeMutablePointer<UInt32>(&methodCount)) {
for i in 0..<Int(methodCount) {
let methodDesc = methodList[i];
let name = methodDesc.name
let types = String(validatingUTF8: methodDesc.types)
print("\(name) \(types)")
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
decodeProto()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
The output of that in the XCode console is:
Optional(
textViewDidBeginEditing:
) Optional("v24@0:8@16")
Optional(textViewDidEndEditing:
) Optional("v24@0:8@16")
Optional(textViewShouldBeginEditing:
) Optional("B24@0:8@16")
Optional(textViewShouldEndEditing:
) Optional("B24@0:8@16")
Optional(textView:shouldChangeTextInRange:replacementText:
) Optional("B48@0:8@16{_NSRange=QQ}24@40")
Optional(textView:shouldChangeTextInRange:replacementText:) Optional("B48@0:8@16{_NSRange=QQ}24@40")
.
.
.