FLEXShortcut.m 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. //
  2. // FLEXShortcut.m
  3. // FLEX
  4. //
  5. // Created by Tanner Bennett on 12/10/19.
  6. // Copyright © 2019 Flipboard. All rights reserved.
  7. //
  8. #import "FLEXShortcut.h"
  9. #import "FLEXProperty.h"
  10. #import "FLEXPropertyAttributes.h"
  11. #import "FLEXIvar.h"
  12. #import "FLEXMethod.h"
  13. #import "FLEXRuntime+UIKitHelpers.h"
  14. #import "FLEXObjectExplorerFactory.h"
  15. #import "FLEXFieldEditorViewController.h"
  16. #import "FLEXMethodCallingViewController.h"
  17. #import "FLEXMetadataSection.h"
  18. @interface FLEXShortcut () {
  19. id _item;
  20. }
  21. @property (nonatomic, readonly) FLEXMetadataKind metadataKind;
  22. @property (nonatomic, readonly) FLEXProperty *property;
  23. @property (nonatomic, readonly) FLEXMethod *method;
  24. @property (nonatomic, readonly) FLEXIvar *ivar;
  25. @property (nonatomic, readonly) id<FLEXRuntimeMetadata> metadata;
  26. @end
  27. @implementation FLEXShortcut
  28. + (id<FLEXShortcut>)shortcutFor:(id)item {
  29. if ([item conformsToProtocol:@protocol(FLEXShortcut)]) {
  30. return item;
  31. }
  32. FLEXShortcut *shortcut = [self new];
  33. shortcut->_item = item;
  34. if ([item isKindOfClass:[FLEXProperty class]]) {
  35. if (shortcut.property.isClassProperty) {
  36. shortcut->_metadataKind = FLEXMetadataKindClassProperties;
  37. } else {
  38. shortcut->_metadataKind = FLEXMetadataKindProperties;
  39. }
  40. }
  41. if ([item isKindOfClass:[FLEXIvar class]]) {
  42. shortcut->_metadataKind = FLEXMetadataKindIvars;
  43. }
  44. if ([item isKindOfClass:[FLEXMethod class]]) {
  45. // We don't care if it's a class method or not
  46. shortcut->_metadataKind = FLEXMetadataKindMethods;
  47. }
  48. return shortcut;
  49. }
  50. - (id)propertyOrIvarValue:(id)object {
  51. return [self.metadata currentValueWithTarget:object];
  52. }
  53. - (NSString *)titleWith:(id)object {
  54. switch (self.metadataKind) {
  55. case FLEXMetadataKindClassProperties:
  56. case FLEXMetadataKindProperties:
  57. // Since we're outside of the "properties" section, prepend @property for clarity.
  58. return [@"@property " stringByAppendingString:[_item description]];
  59. default:
  60. return [_item description];
  61. }
  62. NSAssert(
  63. [_item isKindOfClass:[NSString class]],
  64. @"Unexpected type: %@", [_item class]
  65. );
  66. return _item;
  67. }
  68. - (NSString *)subtitleWith:(id)object {
  69. if (self.metadataKind) {
  70. return [self.metadata previewWithTarget:object];
  71. }
  72. // Item is probably a string; must return empty string since
  73. // these will be gathered into an array. If the object is a
  74. // just a string, it doesn't get a subtitle.
  75. return @"";
  76. }
  77. - (UIViewController *)viewerWith:(id)object {
  78. NSAssert(self.metadataKind, @"Static titles cannot be viewed");
  79. return [self.metadata viewerWithTarget:object];
  80. }
  81. - (UIViewController *)editorWith:(id)object {
  82. NSAssert(self.metadataKind, @"Static titles cannot be edited");
  83. return [self.metadata editorWithTarget:object];
  84. }
  85. - (UITableViewCellAccessoryType)accessoryTypeWith:(id)object {
  86. if (self.metadataKind) {
  87. return [self.metadata suggestedAccessoryTypeWithTarget:object];
  88. }
  89. return UITableViewCellAccessoryDisclosureIndicator;
  90. }
  91. #pragma mark - Helpers
  92. - (FLEXProperty *)property { return _item; }
  93. - (FLEXMethodBase *)method { return _item; }
  94. - (FLEXIvar *)ivar { return _item; }
  95. - (id<FLEXRuntimeMetadata>)metadata { return _item; }
  96. @end