Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Swift and Objective-C Class Parsing
// Swift and Objective-C Class Parsing
import Foundation
// Class parsing
enum ClassType {
case Swift, ObjectiveC
func toString() -> String {
switch self {
case .Swift:
return "Swift"
case .ObjectiveC:
return "Objective-C"
struct ParsedClass {
let type: ClassType
let name: String
let mangledName: String?
let moduleName: String?
extension String {
subscript (r: Range<Int>) -> String {
get {
let startIndex = advance(self.startIndex, r.startIndex)
let endIndex = advance(startIndex, r.endIndex)
return self[Range(start: startIndex, end: endIndex)]
func parseClass(aClass: AnyClass) -> ParsedClass {
// Swift mangling details found here:
let originalName = NSStringFromClass(aClass)
if !originalName.hasPrefix("_T") {
// Not a Swift symbol
return ParsedClass(type: ClassType.ObjectiveC,
name: originalName,
mangledName: nil,
moduleName: nil)
let originalNameLength = originalName.utf16count
var cursor = 4
var substring = originalName[cursor..originalNameLength-cursor]
// Module
let moduleLength = substring.bridgeToObjectiveC().integerValue
let moduleLengthLength = "\(moduleLength)".utf16count
let moduleName = substring[moduleLengthLength..moduleLength]
// Update cursor and substring
cursor += moduleLengthLength + moduleName.utf16count
substring = originalName[cursor..originalNameLength-cursor]
// Class name
let classLength = substring.bridgeToObjectiveC().integerValue
let classLengthLength = "\(classLength)".utf16count
let className = substring[classLengthLength..classLength]
return ParsedClass(type: ClassType.Swift,
name: className,
mangledName: originalName,
moduleName: moduleName)
// Playground start
class MySwiftClass {
// Empty class
var parsedClass = parseClass(MySwiftClass.self)
parsedClass = parseClass(NSObject.self)
func demangle(className: String) -> String {
let tmpClassName = ("__TMP" + className).bridgeToObjectiveC().UTF8String
let propertyName: CString = "tmpProperty"
let tmpClass: AnyClass! = objc_allocateClassPair(NSObject.self, tmpClassName, 0)
let propertyType = "@\"\(className)\"".bridgeToObjectiveC().UTF8String
let attr = objc_property_attribute_t(name: "T", value: propertyType)
class_addProperty(tmpClass, propertyName, [attr], 1)
let property = class_getProperty(tmpClass, propertyName)
var attCount: CUnsignedInt = 0;
let atts = property_copyAttributeList(property, &attCount)
return "\(atts[0].value)"
Copy link

jpsim commented Jun 25, 2014

I just added a second version, which is probably just as unstable as (if not more than) the first.

It relies on an implementation quirk where the type encoding of a Swift property in a Swift class shows the demangled name.

I still recommend using v1 over v2, but wanted to share my findings nonetheless.

Copy link

inamiy commented Jun 26, 2014

This is very nice 👍

Is there any licensing to this code?
I borrowed your v1 code and wrote my debugging tool here, just working like C macro.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment