 <p>Here is my solution. use unsafeBitCast to avoid cast fail warning.</p> <pre><code>extension Object { func toDictionary() -&gt; [String:AnyObject] { let properties = self.objectSchema.properties.map { $0.name } var dicProps = [String:AnyObject]() for (key, value) in self.dictionaryWithValuesForKeys(properties) { if let value = value as? ListBase { dicProps[key] = value.toArray() } else if let value = value as? Object { dicProps[key] = value.toDictionary() } else { dicProps[key] = value } } return dicProps } } extension ListBase { func toArray() -&gt; [AnyObject] { var _toArray = [AnyObject]() for i in 0..&lt;self._rlmArray.count { let obj = unsafeBitCast(self._rlmArray[i], Object.self) _toArray.append(obj.toDictionary()) } return _toArray } } </code></pre>