A short story on reflection with Swift
Reflection?
Reflection?
let vc = UIViewController()
print(vc is UIViewController) // true
print(vc.view is UIView) // true
Reflection?
query {
search(text: "cat") {
???
}
}
query {
search(text: "cat") {
animal {
animal_type
}
}
}
Reflection?
query {
search(text: "cat") {
... on Animal {
animal_type
}
... on Nicknames {
nickname
}
... on Superheroes {
name
}
}
}
Reflection?
Reflection?
fragment NotificationData on NotificationTypes {
... on IRecord {
id
created_at
}
... on INotification {
message
category
resolved
read
}
... on NewMatchInCurrentlyJoinedAlbumNotification {
matched_photos(slice: { offset: 0, limit: 1}) {
...PhotoDetails
}
albumMembership {
...AlbumMembershipDetails
}
}
... on UsersJoinedAlbumNotification {
new_members {
id
}
albumMembership {
...AlbumMembershipDetails
}
}
... on UsersUploadedToAlbumNotification {
photos(slice: { offset: 0, limit: 1 }) {
uploader {
id
}
}
albumMembership {
...AlbumMembershipDetails
}
}
}
Reflection?
public struct NotificationData: GraphQLNamedFragment {
public let asNewMatchInCurrentlyJoinedAlbumNotification: AsNewMatchInCurrentlyJoinedAlbumNotification?
public let asUsersJoinedAlbumNotification: AsUsersJoinedAlbumNotification?
public let asUsersUploadedToAlbumNotification: AsUsersUploadedToAlbumNotification?
public struct AsNewMatchInCurrentlyJoinedAlbumNotification: GraphQLConditionalFragment {
public let id: String
public let createdAt: String?
public let message: String?
public let category: NotificationCategories?
public let resolved: Bool?
public let read: Bool?
[... rest of the properties in the fragment ...]
}
public struct AsUsersJoinedAlbumNotification: GraphQLConditionalFragment {
public let id: String
public let createdAt: String?
public let message: String?
public let category: NotificationCategories?
public let resolved: Bool?
public let read: Bool?
[... rest of the properties in the fragment ...]
}
public struct AsUsersUploadedToAlbumNotification: GraphQLConditionalFragment {
public let id: String
public let createdAt: String?
public let message: String?
public let category: NotificationCategories?
public let resolved: Bool?
public let read: Bool?
[... rest of the properties in the fragment ...]
}
}
Reflection?
class NotificationTableViewCell: UITableViewCell {
open var notification: NotificationData? {
didSet {
setDisplayValues()
}
}
}
class NewUploadsNotificationCell: NotificationTableViewCell
class UsersJoinedAlbumNotificationCell: NotificationTableViewCell
class InboundInvitationNotificationCell: NotificationTableViewCell
class NewMatchesNotificationCell: NotificationTableViewCell
Reflection?
extension NotificationData {
public func getNotificationId() -> String? {
if let id = self.asUsersJoinedAlbumNotification?.id {
return id
}
if let id = self.asNewMatchInCurrentlyJoinedAlbumNotification?.id {
return id
}
if let id = self.asUsersUploadedToAlbumNotification?.albumMembership?.id {
return id
}
if let id = self.asInboundAlbumInvitationNotification?.id {
return id
}
return nil
}
}
😱
Reflection?
Â
Reflection?
🤔
Reflection?
init(reflecting: Any)
let children: Mirror.Children
var customMirror: Mirror
var description: String
let displayStyle: Mirror.DisplayStyle?
let subjectType: Any.Type
var superclass:Mirror: Mirror?
Reflection?
extension NotificationData {
public func objectForKey(key: String) -> AnyObject? {
let notificationUnionTypes = [
"asNewMatchInCurrentlyJoinedAlbumNotification",
"asUsersJoinedAlbumNotification",
"asUsersUploadedToAlbumNotification",
"asInboundAlbumInvitationNotification"
]
let mirror = Mirror(reflecting: self)
for case let (label?, value) in mirror.children {
if notificationUnionTypes.contains(label) {
let unionTypeMirror = Mirror(reflecting: value)
for case let (label?, value) in unionTypeMirror.children {
let objectMirror = Mirror(reflecting: value)
for case let (label?, value) in objectMirror.children {
if key == label {
return value as AnyObject
}
}
}
}
}
return nil
}
}
Reflection?
/// Returns the notification id
public func getId() -> String? {
return self.objectForKey(key: "id") as? String
}
/// Returns the notification category
public func getCategory() -> NotificationCategories? {
if let category = self.objectForKey(key: "category") as? NotificationCategories {
return category
} else {
return nil
}
}
/// Returns whether the notification is read or not
public func isRead() -> Bool {
if let isRead = self.objectForKey(key: "read") as? Bool {
return isRead
} else {
return false
}
}
/// Returns whether a notificatio has been resolved (user cleared its associated action)
public func isResolved() -> Bool {
if let isResolved = self.objectForKey(key: "resolved") as? Bool {
return isResolved
} else {
return false
}
}
Reflection?
Reflection?
Reflection?