Compare commits

...

22 Commits

Author SHA1 Message Date
Tanner Bennett fcdb33fce2 Clean up FLEXObjcInternal.mm 2019-04-24 12:27:41 -05:00
Tanner Bennett 1eb8e4f430 Fix various warnings 2019-04-24 11:32:08 -05:00
Tanner Bennett 1d937777c0 Add address explorer 2019-04-24 11:11:25 -05:00
Tanner Bennett 308afda5c2 Improve FLEXPointerIsValidObjcObject
Previously, it assumed any address you gave it was valid and readable. It no longer makes this assumption.
2019-04-24 11:11:25 -05:00
Tanner Bennett f7b00e02ee Change UICatalog bundle ID 2019-04-24 11:11:25 -05:00
Tanner Bennett 0ff29e1f90 Add +[FLEXUtility alert:message:from:] 2019-04-24 11:11:25 -05:00
Tanner Bennett 3fe31e8628 Always display a description
Except while searching of course
2019-04-18 09:34:08 -05:00
Tanner Bennett 33263bfcfa Allow copying object address
Long press on the description row in an explorer screen
2019-04-18 09:34:08 -05:00
Tanner Bennett d6caab29dc Organize ObjectExplorers/
- Group classes into folders (Views, Controllers)
- Add FLEXTableViewCell, FLEXSubtitleTableViewCell
- FLEXMultilineTableViewCell inherits from FLEXTableViewCell
- FLEXTableViewCell makes it easy to add custom UIMenuItem commands to any cell without subclassing it or exposing any state to it
2019-04-18 09:34:08 -05:00
Tanner Bennett 5d181adcb8 Add example archived object in demo app 2019-04-17 11:52:45 -05:00
zhangpeng 4ba2fdc289 Support viewing archived objects in file browser 2019-04-17 11:52:45 -05:00
Tanner Bennett 140dc32775 Update pod version and maintainer 2019-04-16 11:21:05 -05:00
Tanner Bennett 78568cd5be Fix FLEX not being embedded into example app 2019-04-16 11:14:52 -05:00
Tanner Bennett b010cdb072 Refactor file browser view controller
Fix #251
2019-04-16 11:07:35 -05:00
Tanner Bennett 37e299733b Fix #261
Crash: +[NSString stringWithUTF8String:]: NULL cString
2019-04-12 13:46:56 -05:00
Tanner Bennett f3a1587cf1 Replace UICatalog launch images with launch xib 2019-04-12 13:34:11 -05:00
Tanner Bennett 821ca1683b Update project settings, Xcode 10.2 2019-04-12 13:25:00 -05:00
Chengming Liao 7e13ca2757 Update FLEXMultiColumnTableView.m
indentation
2019-04-12 10:13:03 -05:00
Chengming Liao 129c91c876 add compiler flags 2019-04-12 10:13:03 -05:00
Chengming Liao d2f6ff0b40 Fix safeArea for database content view 2019-04-12 10:13:03 -05:00
Alexander Leontev 69414e4174 Don't shorten curl 2019-04-12 10:12:09 -05:00
Lanbo Zhang 0654fb4b5f podfile should include .mm file 2019-04-12 10:10:09 -05:00
86 changed files with 1010 additions and 546 deletions
@@ -8,7 +8,7 @@
#import "FLEXArgumentInputTextView.h"
#warning TODO This is never supported
// #warning TODO This is never supported
@interface FLEXArgumentInputJSONObjectView : FLEXArgumentInputTextView
@end
@@ -51,6 +51,13 @@ static const CGFloat kColumnMargin = 1;
CGFloat height = self.frame.size.height;
CGFloat topheaderHeight = [self topHeaderHeight];
CGFloat leftHeaderWidth = [self leftHeaderWidth];
CGFloat topInsets = 0.f;
#if FLEX_AT_LEAST_IOS11_SDK
if (@available (iOS 11.0, *)) {
topInsets = self.safeAreaInsets.top;
}
#endif
CGFloat contentWidth = 0.0;
NSInteger rowsCount = [self numberOfColumns];
@@ -58,13 +65,13 @@ static const CGFloat kColumnMargin = 1;
contentWidth += [self contentWidthForColumn:i];
}
self.leftTableView.frame = CGRectMake(0, topheaderHeight, leftHeaderWidth, height - topheaderHeight);
self.headerScrollView.frame = CGRectMake(leftHeaderWidth, 0, width - leftHeaderWidth, topheaderHeight);
self.leftTableView.frame = CGRectMake(0, topheaderHeight + topInsets, leftHeaderWidth, height - topheaderHeight - topInsets);
self.headerScrollView.frame = CGRectMake(leftHeaderWidth, topInsets, width - leftHeaderWidth, topheaderHeight);
self.headerScrollView.contentSize = CGSizeMake( self.contentTableView.frame.size.width, self.headerScrollView.frame.size.height);
self.contentTableView.frame = CGRectMake(0, 0, contentWidth + [self numberOfColumns] * [self columnMargin] , height - topheaderHeight);
self.contentScrollView.frame = CGRectMake(leftHeaderWidth, topheaderHeight, width - leftHeaderWidth, height - topheaderHeight);
self.contentTableView.frame = CGRectMake(0, 0, contentWidth + [self numberOfColumns] * [self columnMargin] , height - topheaderHeight - topInsets);
self.contentScrollView.frame = CGRectMake(leftHeaderWidth, topheaderHeight + topInsets, width - leftHeaderWidth, height - topheaderHeight - topInsets);
self.contentScrollView.contentSize = self.contentTableView.frame.size;
self.leftHeader.frame = CGRectMake(0, 0, [self leftHeaderWidth], [self topHeaderHeight]);
self.leftHeader.frame = CGRectMake(0, topInsets, [self leftHeaderWidth], [self topHeaderHeight]);
}
@@ -12,6 +12,8 @@
#import "FLEXWebViewController.h"
#import "FLEXImagePreviewViewController.h"
#import "FLEXTableListViewController.h"
#import "FLEXObjectExplorerFactory.h"
#import "FLEXObjectExplorerViewController.h"
@interface FLEXFileBrowserTableViewCell : UITableViewCell
@end
@@ -88,6 +90,12 @@
}
#pragma mark - Misc
- (void)alert:(NSString *)title message:(NSString *)message {
[[[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
}
#pragma mark - FLEXFileBrowserSearchOperationDelegate
- (void)fileBrowserSearchOperationResult:(NSArray<NSString *> *)searchResult size:(uint64_t)size
@@ -185,56 +193,70 @@
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
NSString *fullPath = [self filePathAtIndexPath:indexPath];
NSString *subpath = [fullPath lastPathComponent];
NSString *pathExtension = [subpath pathExtension];
NSString *subpath = fullPath.lastPathComponent;
NSString *pathExtension = subpath.pathExtension;
BOOL isDirectory = NO;
BOOL stillExists = [[NSFileManager defaultManager] fileExistsAtPath:fullPath isDirectory:&isDirectory];
if (stillExists) {
UIViewController *drillInViewController = nil;
if (isDirectory) {
drillInViewController = [[[self class] alloc] initWithPath:fullPath];
} else if ([FLEXUtility isImagePathExtension:pathExtension]) {
UIImage *image = [UIImage imageWithContentsOfFile:fullPath];
drillInViewController = [[FLEXImagePreviewViewController alloc] initWithImage:image];
if (!stillExists) {
[self alert:@"File Not Found" message:@"The file at the specified path no longer exists."];
[self reloadDisplayedPaths];
return;
}
UIViewController *drillInViewController = nil;
if (isDirectory) {
drillInViewController = [[[self class] alloc] initWithPath:fullPath];
} else if ([FLEXUtility isImagePathExtension:pathExtension]) {
UIImage *image = [UIImage imageWithContentsOfFile:fullPath];
drillInViewController = [[FLEXImagePreviewViewController alloc] initWithImage:image];
} else {
NSData *fileData = [NSData dataWithContentsOfFile:fullPath];
if (!fileData.length) {
[self alert:@"Empty File" message:@"No data returned from the file."];
return;
}
// Special case keyed archives, json, and plists to get more readable data.
NSString *prettyString = nil;
if ([pathExtension isEqualToString:@"json"]) {
prettyString = [FLEXUtility prettyJSONStringFromData:fileData];
} else {
// Special case keyed archives, json, and plists to get more readable data.
NSString *prettyString = nil;
if ([pathExtension isEqual:@"archive"] || [pathExtension isEqual:@"coded"]) {
prettyString = [[NSKeyedUnarchiver unarchiveObjectWithFile:fullPath] description];
} else if ([pathExtension isEqualToString:@"json"]) {
prettyString = [FLEXUtility prettyJSONStringFromData:[NSData dataWithContentsOfFile:fullPath]];
} else if ([pathExtension isEqualToString:@"plist"]) {
NSData *fileData = [NSData dataWithContentsOfFile:fullPath];
@try {
// Try to decode an archived object regardless of file extension
id object = [NSKeyedUnarchiver unarchiveObjectWithData:fileData];
drillInViewController = [FLEXObjectExplorerFactory explorerViewControllerForObject:object];
} @catch (NSException *e) {
// Try to decode a property list instead, also regardless of file extension
prettyString = [[NSPropertyListSerialization propertyListWithData:fileData options:0 format:NULL error:NULL] description];
}
if ([prettyString length] > 0) {
drillInViewController = [[FLEXWebViewController alloc] initWithText:prettyString];
} else if ([FLEXWebViewController supportsPathExtension:pathExtension]) {
drillInViewController = [[FLEXWebViewController alloc] initWithURL:[NSURL fileURLWithPath:fullPath]];
} else if ([FLEXTableListViewController supportsExtension:subpath.pathExtension]) {
drillInViewController = [[FLEXTableListViewController alloc] initWithPath:fullPath];
}
else {
NSString *fileString = [NSString stringWithContentsOfFile:fullPath encoding:NSUTF8StringEncoding error:NULL];
if ([fileString length] > 0) {
drillInViewController = [[FLEXWebViewController alloc] initWithText:fileString];
}
}
}
if (drillInViewController) {
drillInViewController.title = [subpath lastPathComponent];
[self.navigationController pushViewController:drillInViewController animated:YES];
} else {
[self openFileController:fullPath];
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
if (prettyString.length) {
drillInViewController = [[FLEXWebViewController alloc] initWithText:prettyString];
} else if ([FLEXWebViewController supportsPathExtension:pathExtension]) {
drillInViewController = [[FLEXWebViewController alloc] initWithURL:[NSURL fileURLWithPath:fullPath]];
} else if ([FLEXTableListViewController supportsExtension:pathExtension]) {
drillInViewController = [[FLEXTableListViewController alloc] initWithPath:fullPath];
}
else if (!drillInViewController) {
NSString *fileString = [NSString stringWithUTF8String:fileData.bytes];
if (fileString.length) {
drillInViewController = [[FLEXWebViewController alloc] initWithText:fileString];
}
}
}
if (drillInViewController) {
drillInViewController.title = subpath.lastPathComponent;
[self.navigationController pushViewController:drillInViewController animated:YES];
} else {
[[[UIAlertView alloc] initWithTitle:@"File Removed" message:@"The file at the specified path no longer exists." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
[self reloadDisplayedPaths];
// Share the file otherwise
[self openFileController:fullPath];
}
}
@@ -8,6 +8,7 @@
#import "FLEXGlobalsTableViewController.h"
#import "FLEXUtility.h"
#import "FLEXRuntimeUtility.h"
#import "FLEXLibrariesTableViewController.h"
#import "FLEXClassesTableViewController.h"
#import "FLEXObjectExplorerViewController.h"
@@ -26,6 +27,7 @@ typedef NS_ENUM(NSUInteger, FLEXGlobalsRow) {
FLEXGlobalsRowNetworkHistory,
FLEXGlobalsRowSystemLog,
FLEXGlobalsRowLiveObjects,
FLEXGlobalsRowAddressInspector,
FLEXGlobalsRowFileBrowser,
FLEXGlobalsCookies,
FLEXGlobalsRowSystemLibraries,
@@ -56,6 +58,7 @@ typedef NS_ENUM(NSUInteger, FLEXGlobalsRow) {
for (FLEXGlobalsRow defaultRowIndex = 0; defaultRowIndex < FLEXGlobalsRowCount; defaultRowIndex++) {
FLEXGlobalsTableViewControllerEntryNameFuture titleFuture = nil;
FLEXGlobalsTableViewControllerViewControllerFuture viewControllerFuture = nil;
FLEXGlobalsTableViewControllerRowAction rowAction = nil;
switch (defaultRowIndex) {
case FLEXGlobalsRowAppClasses:
@@ -69,6 +72,49 @@ typedef NS_ENUM(NSUInteger, FLEXGlobalsRow) {
return classesViewController;
};
break;
case FLEXGlobalsRowAddressInspector:
titleFuture = ^NSString *{
return @"🔎 Address Explorer";
};
rowAction = ^(FLEXGlobalsTableViewController *host) {
NSString *title = @"Explore Object at Address";
NSString *message = @"Paste a hexadecimal address below, starting with '0x'. "
"Use the unsafe option if you need to bypass pointer validation, "
"but know that it may crash the app if the address is invalid.";
UIAlertController *addressInput = [UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
void (^handler)(UIAlertAction *) = ^(UIAlertAction *action) {
if (action.style == UIAlertActionStyleCancel) {
[host deselectSelectedRow]; return;
}
NSString *address = addressInput.textFields.firstObject.text;
[host tryExploreAddress:address safely:action.style == UIAlertActionStyleDefault];
};
[addressInput addTextFieldWithConfigurationHandler:^(UITextField *textField) {
NSString *copied = [UIPasteboard generalPasteboard].string;
textField.placeholder = @"0x00000070deadbeef";
// Go ahead and paste our clipboard if we have an address copied
if ([copied hasPrefix:@"0x"]) {
textField.text = copied;
[textField selectAll:nil];
}
}];
[addressInput addAction:[UIAlertAction actionWithTitle:@"Explore"
style:UIAlertActionStyleDefault
handler:handler]];
[addressInput addAction:[UIAlertAction actionWithTitle:@"Unsafe Explore"
style:UIAlertActionStyleDestructive
handler:handler]];
[addressInput addAction:[UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:handler]];
[host presentViewController:addressInput animated:YES completion:nil];
};
break;
case FLEXGlobalsRowSystemLibraries: {
NSString *titleString = @"📚 System Libraries";
@@ -212,10 +258,18 @@ typedef NS_ENUM(NSUInteger, FLEXGlobalsRow) {
break;
}
NSParameterAssert(titleFuture);
NSParameterAssert(viewControllerFuture);
NSAssert(viewControllerFuture || rowAction, @"The switch-case above must assign one of these");
if (viewControllerFuture) {
[defaultGlobalEntries addObject:[FLEXGlobalsTableViewControllerEntry
entryWithNameFuture:titleFuture
viewControllerFuture:viewControllerFuture]];
} else {
[defaultGlobalEntries addObject:[FLEXGlobalsTableViewControllerEntry
entryWithNameFuture:titleFuture
action:rowAction]];
}
[defaultGlobalEntries addObject:[FLEXGlobalsTableViewControllerEntry entryWithNameFuture:titleFuture viewControllerFuture:viewControllerFuture]];
}
return defaultGlobalEntries;
@@ -231,6 +285,11 @@ typedef NS_ENUM(NSUInteger, FLEXGlobalsRow) {
return self;
}
- (void)deselectSelectedRow {
NSIndexPath *selected = self.tableView.indexPathForSelectedRow;
[self.tableView deselectRowAtIndexPath:selected animated:YES];
}
#pragma mark - Public
+ (void)setApplicationWindow:(UIWindow *)applicationWindow
@@ -247,13 +306,39 @@ typedef NS_ENUM(NSUInteger, FLEXGlobalsRow) {
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(donePressed:)];
}
#pragma mark -
#pragma mark - Misc
- (void)donePressed:(id)sender
{
[self.delegate globalsViewControllerDidFinish:self];
}
- (void)tryExploreAddress:(NSString *)addressString safely:(BOOL)safely {
NSScanner *scanner = [NSScanner scannerWithString:addressString];
unsigned long long hexValue = 0;
BOOL didParseAddress = [scanner scanHexLongLong:&hexValue];
const void *pointerValue = (void *)hexValue;
NSString *error = nil;
if (didParseAddress) {
if (safely && ![FLEXRuntimeUtility pointerIsValidObjcObject:pointerValue]) {
error = @"The given address is unlikely to be a valid object.";
}
} else {
error = @"Malformed address. Make sure it's not too long and starts with '0x'.";
}
if (!error) {
id object = (__bridge id)pointerValue;
FLEXObjectExplorerViewController *explorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:object];
[self.navigationController pushViewController:explorer animated:YES];
} else {
[FLEXUtility alert:@"Uh-oh" message:error from:self];
[self deselectSelectedRow];
}
}
#pragma mark - Table Data Helpers
- (FLEXGlobalsTableViewControllerEntry *)globalEntryAtIndexPath:(NSIndexPath *)indexPath
@@ -268,13 +353,6 @@ typedef NS_ENUM(NSUInteger, FLEXGlobalsRow) {
return entry.entryNameFuture();
}
- (UIViewController *)viewControllerToPushForRowAtIndexPath:(NSIndexPath *)indexPath
{
FLEXGlobalsTableViewControllerEntry *entry = [self globalEntryAtIndexPath:indexPath];
return entry.viewControllerFuture();
}
#pragma mark - Table View Data Source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
@@ -302,14 +380,16 @@ typedef NS_ENUM(NSUInteger, FLEXGlobalsRow) {
return cell;
}
#pragma mark - Table View Delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController *viewControllerToPush = [self viewControllerToPushForRowAtIndexPath:indexPath];
[self.navigationController pushViewController:viewControllerToPush animated:YES];
FLEXGlobalsTableViewControllerEntry *entry = [self globalEntryAtIndexPath:indexPath];
if (entry.viewControllerFuture) {
[self.navigationController pushViewController:entry.viewControllerFuture() animated:YES];
} else {
entry.rowAction(self);
}
}
@end
@@ -83,7 +83,7 @@
[self.logMessageIdentifiers addIndex:(NSUInteger)message.messageID];
}
self.lastTimestamp = @(asl_get(newMessages.lastObject.aslMessage, ASL_KEY_TIME));
self.lastTimestamp = @(asl_get(newMessages.lastObject.aslMessage, ASL_KEY_TIME) ?: "null");
}
dispatch_async(dispatch_get_main_queue(), ^{
@@ -94,7 +94,7 @@
- (NSString *)description
{
NSString *escaped = [self.messageText stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"];
return [NSString stringWithFormat:@"(%lu) %@", self.messageText.length, escaped];
return [NSString stringWithFormat:@"(%@) %@", @(self.messageText.length), escaped];
}
@end
+1 -6
View File
@@ -28,12 +28,7 @@
}
if (request.HTTPBody) {
if ([request.allHTTPHeaderFields[@"Content-Length"] intValue] < 1024) {
[curlCommandString appendFormat:@"-d \'%@\'",
[[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding]];
} else {
[curlCommandString appendFormat:@"[TOO MUCH DATA TO INCLUDE]"];
}
[curlCommandString appendFormat:@"-d \'%@\'", [[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding]];
}
return curlCommandString;
@@ -6,17 +6,23 @@
// Copyright (c) 2014 f. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class FLEXGlobalsTableViewController;
typedef NSString *(^FLEXGlobalsTableViewControllerEntryNameFuture)(void);
/// Simply return a view controller to be pushed on the navigation stack
typedef UIViewController *(^FLEXGlobalsTableViewControllerViewControllerFuture)(void);
/// Do something like present an alert, then use the host
/// view controller to present or push another view controller.
typedef void (^FLEXGlobalsTableViewControllerRowAction)(FLEXGlobalsTableViewController *host);
@interface FLEXGlobalsTableViewControllerEntry : NSObject
@property (nonatomic, readonly, copy) FLEXGlobalsTableViewControllerEntryNameFuture entryNameFuture;
@property (nonatomic, readonly, copy) FLEXGlobalsTableViewControllerViewControllerFuture viewControllerFuture;
@property (nonatomic, readonly, copy) FLEXGlobalsTableViewControllerRowAction rowAction;
+ (instancetype)entryWithNameFuture:(FLEXGlobalsTableViewControllerEntryNameFuture)nameFuture viewControllerFuture:(FLEXGlobalsTableViewControllerViewControllerFuture)viewControllerFuture;
+ (instancetype)entryWithNameFuture:(FLEXGlobalsTableViewControllerEntryNameFuture)nameFuture action:(FLEXGlobalsTableViewControllerRowAction)rowSelectedAction;
@end
@@ -10,7 +10,8 @@
@implementation FLEXGlobalsTableViewControllerEntry
+ (instancetype)entryWithNameFuture:(FLEXGlobalsTableViewControllerEntryNameFuture)nameFuture viewControllerFuture:(FLEXGlobalsTableViewControllerViewControllerFuture)viewControllerFuture
+ (instancetype)entryWithNameFuture:(FLEXGlobalsTableViewControllerEntryNameFuture)nameFuture
viewControllerFuture:(FLEXGlobalsTableViewControllerViewControllerFuture)viewControllerFuture
{
NSParameterAssert(nameFuture);
NSParameterAssert(viewControllerFuture);
@@ -22,4 +23,17 @@
return entry;
}
+ (instancetype)entryWithNameFuture:(FLEXGlobalsTableViewControllerEntryNameFuture)nameFuture
action:(FLEXGlobalsTableViewControllerRowAction)rowSelectedAction
{
NSParameterAssert(nameFuture);
NSParameterAssert(rowSelectedAction);
FLEXGlobalsTableViewControllerEntry *entry = [[self alloc] init];
entry->_entryNameFuture = [nameFuture copy];
entry->_rowAction = [rowSelectedAction copy];
return entry;
}
@end
@@ -15,6 +15,7 @@
#import "FLEXIvarEditorViewController.h"
#import "FLEXMethodCallingViewController.h"
#import "FLEXInstancesTableViewController.h"
#import "FLEXTableView.h"
#import <objc/runtime.h>
typedef NS_ENUM(NSUInteger, FLEXObjectExplorerScope) {
@@ -90,10 +91,19 @@ typedef NS_ENUM(NSUInteger, FLEXMetadataKind) {
@implementation FLEXObjectExplorerViewController
- (id)initWithStyle:(UITableViewStyle)style
+ (void)initialize
{
// Force grouped style
return [super initWithStyle:UITableViewStyleGrouped];
if (self == [FLEXObjectExplorerViewController class]) {
// Initialize custom menu items for entire app
UIMenuItem *copyObjectAddress = [[UIMenuItem alloc] initWithTitle:@"Copy Address" action:@selector(copyObjectAddress:)];
[UIMenuController sharedMenuController].menuItems = @[copyObjectAddress];
[[UIMenuController sharedMenuController] update];
}
}
- (void)loadView
{
self.tableView = [[FLEXTableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
}
- (void)viewDidLoad
@@ -134,7 +144,8 @@ typedef NS_ENUM(NSUInteger, FLEXMetadataKind) {
#pragma mark - Search
- (void)refreshScopeTitles {
- (void)refreshScopeTitles
{
if (!self.searchBar) return;
Class parent = [self.object superclass];
@@ -172,7 +183,8 @@ typedef NS_ENUM(NSUInteger, FLEXMetadataKind) {
[self updateDisplayedData];
}
- (NSArray *)metadata:(FLEXMetadataKind)metadataKind forScope:(FLEXObjectExplorerScope)scope {
- (NSArray *)metadata:(FLEXMetadataKind)metadataKind forScope:(FLEXObjectExplorerScope)scope
{
switch (metadataKind) {
case FLEXMetadataKindProperties:
switch (self.scope) {
@@ -221,7 +233,8 @@ typedef NS_ENUM(NSUInteger, FLEXMetadataKind) {
}
}
- (NSInteger)totalCountOfMetadata:(FLEXMetadataKind)metadataKind forScope:(FLEXObjectExplorerScope)scope {
- (NSInteger)totalCountOfMetadata:(FLEXMetadataKind)metadataKind forScope:(FLEXObjectExplorerScope)scope
{
return [self metadata:metadataKind forScope:scope].count;
}
@@ -273,20 +286,24 @@ typedef NS_ENUM(NSUInteger, FLEXMetadataKind) {
- (BOOL)shouldShowDescription
{
BOOL showDescription = YES;
// Not if it's empty or nil.
NSString *descripition = [FLEXUtility safeDescriptionForObject:self.object];
if (showDescription) {
showDescription = [descripition length] > 0;
}
// Not if we have filter text that doesn't match the desctiption.
if (showDescription && [self.filterText length] > 0) {
showDescription = [descripition rangeOfString:self.filterText options:NSCaseInsensitiveSearch].length > 0;
if (self.filterText.length) {
NSString *description = [self displayedObjectDescription];
return [description rangeOfString:self.filterText options:NSCaseInsensitiveSearch].length > 0;
}
return showDescription;
return YES;
}
- (NSString *)displayedObjectDescription {
NSString *desc = [FLEXUtility safeDescriptionForObject:self.object];
if (!desc.length) {
NSString *address = [FLEXUtility addressOfObject:self.object];
desc = [NSString stringWithFormat:@"Object at %@ returned empty description", address];
}
return desc;
}
@@ -688,7 +705,7 @@ typedef NS_ENUM(NSUInteger, FLEXMetadataKind) {
NSString *title = nil;
switch (section) {
case FLEXObjectExplorerSectionDescription:
title = [FLEXUtility safeDescriptionForObject:self.object];
title = [self displayedObjectDescription];
break;
case FLEXObjectExplorerSectionCustom:
@@ -808,19 +825,9 @@ typedef NS_ENUM(NSUInteger, FLEXMetadataKind) {
return canDrillIn;
}
- (BOOL)canCopyRow:(NSInteger)row inExplorerSection:(FLEXObjectExplorerSection)section
- (BOOL)sectionHasActions:(NSInteger)section
{
BOOL canCopy = NO;
switch (section) {
case FLEXObjectExplorerSectionDescription:
canCopy = YES;
break;
default:
break;
}
return canCopy;
return [self explorerSectionAtIndex:section] == FLEXObjectExplorerSectionDescription;
}
- (NSString *)titleForExplorerSection:(FLEXObjectExplorerSection)section
@@ -1019,45 +1026,65 @@ typedef NS_ENUM(NSUInteger, FLEXMetadataKind) {
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath
{
FLEXObjectExplorerSection explorerSection = [self explorerSectionAtIndex:indexPath.section];
BOOL canCopy = [self canCopyRow:indexPath.row inExplorerSection:explorerSection];
return canCopy;
return [self sectionHasActions:indexPath.section];
}
- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
{
BOOL canPerformAction = NO;
if (action == @selector(copy:)) {
FLEXObjectExplorerSection explorerSection = [self explorerSectionAtIndex:indexPath.section];
BOOL canCopy = [self canCopyRow:indexPath.row inExplorerSection:explorerSection];
canPerformAction = canCopy;
FLEXObjectExplorerSection explorerSection = [self explorerSectionAtIndex:indexPath.section];
switch (explorerSection) {
case FLEXObjectExplorerSectionDescription:
return action == @selector(copy:) || action == @selector(copyObjectAddress:);
default:
return NO;
}
return canPerformAction;
}
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
{
if (action == @selector(copy:)) {
FLEXObjectExplorerSection explorerSection = [self explorerSectionAtIndex:indexPath.section];
NSString *stringToCopy = @"";
NSString *title = [self titleForRow:indexPath.row inExplorerSection:explorerSection];
if ([title length] > 0) {
stringToCopy = [stringToCopy stringByAppendingString:title];
}
NSString *subtitle = [self subtitleForRow:indexPath.row inExplorerSection:explorerSection];
if ([subtitle length] > 0) {
if ([stringToCopy length] > 0) {
stringToCopy = [stringToCopy stringByAppendingString:@"\n\n"];
}
stringToCopy = [stringToCopy stringByAppendingString:subtitle];
}
[[UIPasteboard generalPasteboard] setString:stringToCopy];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[self performSelector:action withObject:indexPath];
#pragma clang diagnostic pop
}
#pragma mark - UIMenuController
/// Prevent the search bar from trying to use us as a responder
///
/// Our table cells will use the UITableViewDelegate methods
/// to make sure we can perform the actions we want to
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
return NO;
}
- (void)copy:(NSIndexPath *)indexPath
{
FLEXObjectExplorerSection explorerSection = [self explorerSectionAtIndex:indexPath.section];
NSString *stringToCopy = @"";
NSString *title = [self titleForRow:indexPath.row inExplorerSection:explorerSection];
if (title.length) {
stringToCopy = [stringToCopy stringByAppendingString:title];
}
NSString *subtitle = [self subtitleForRow:indexPath.row inExplorerSection:explorerSection];
if (subtitle.length) {
if (stringToCopy.length) {
stringToCopy = [stringToCopy stringByAppendingString:@"\n\n"];
}
stringToCopy = [stringToCopy stringByAppendingString:subtitle];
}
[UIPasteboard generalPasteboard].string = stringToCopy;
}
- (void)copyObjectAddress:(NSIndexPath *)indexPath
{
[UIPasteboard generalPasteboard].string = [FLEXUtility addressOfObject:self.object];
}
@@ -6,11 +6,11 @@
// Copyright (c) 2015 f. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "FLEXTableViewCell.h"
extern NSString *const kFLEXMultilineTableViewCellIdentifier;
@interface FLEXMultilineTableViewCell : UITableViewCell
@interface FLEXMultilineTableViewCell : FLEXTableViewCell
+ (CGFloat)preferredHeightWithAttributedText:(NSAttributedString *)attributedText inTableViewWidth:(CGFloat)tableViewWidth style:(UITableViewStyle)style showsAccessory:(BOOL)showsAccessory;
@@ -0,0 +1,17 @@
//
// FLEXSubtitleTableViewCell.h
// FLEX
//
// Created by Tanner on 4/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface FLEXSubtitleTableViewCell : UITableViewCell
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,18 @@
//
// FLEXSubtitleTableViewCell.m
// FLEX
//
// Created by Tanner on 4/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
//
#import "FLEXSubtitleTableViewCell.h"
@implementation FLEXSubtitleTableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
return [super initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
}
@end
@@ -0,0 +1,17 @@
//
// FLEXTableView.h
// FLEX
//
// Created by Tanner on 4/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface FLEXTableView : UITableView
@property (nonatomic, readonly) NSString *defaultReuseIdentifier;
@property (nonatomic, readonly) NSString *subtitleReuseIdentifier;
@property (nonatomic, readonly) NSString *multilineReuseIdentifier;
@end
@@ -0,0 +1,47 @@
//
// FLEXTableView.m
// FLEX
//
// Created by Tanner on 4/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
//
#import "FLEXTableView.h"
#import "FLEXSubtitleTableViewCell.h"
#import "FLEXMultilineTableViewCell.h"
@implementation FLEXTableView
- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style
{ self = [super initWithFrame:frame style:style];
if (self) {
[self registerCells:@{
self.defaultReuseIdentifier: [FLEXTableViewCell class],
self.subtitleReuseIdentifier: [FLEXSubtitleTableViewCell class],
self.multilineReuseIdentifier: [FLEXMultilineTableViewCell class],
}];
}
return self;
}
- (void)registerCells:(NSDictionary<NSString*,Class> *)registrationMapping
{ [registrationMapping enumerateKeysAndObjectsUsingBlock:^(NSString *identifier, Class cellClass, BOOL *stop) {
[self registerClass:cellClass forCellReuseIdentifier:identifier];
}];
}
- (NSString *)defaultReuseIdentifier
{ return @"kFLEXTableViewCellIdentifier";
}
- (NSString *)subtitleReuseIdentifier
{ return @"kFLEXSubtitleTableViewCellIdentifier";
}
- (NSString *)multilineReuseIdentifier
{
return kFLEXMultilineTableViewCellIdentifier;
}
@end
@@ -0,0 +1,13 @@
//
// FLEXTableViewCell.h
// FLEX
//
// Created by Tanner on 4/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface FLEXTableViewCell : UITableViewCell
@end
@@ -0,0 +1,77 @@
//
// FLEXTableViewCell.m
// FLEX
//
// Created by Tanner on 4/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
//
#import "FLEXTableViewCell.h"
#import "FLEXUtility.h"
#import "FLEXTableView.h"
@interface UITableView (Internal)
// Exists at least since iOS 5
- (BOOL)_canPerformAction:(SEL)action forCell:(UITableViewCell *)cell sender:(id)sender;
- (void)_performAction:(SEL)action forCell:(UITableViewCell *)cell sender:(id)sender;
@end
@interface UITableViewCell (Internal)
// Exists at least since iOS 5
@property (nonatomic, readonly) FLEXTableView *_tableView;
@end
@implementation FLEXTableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
UIFont *cellFont = [FLEXUtility defaultTableViewCellLabelFont];
self.textLabel.font = cellFont;
self.detailTextLabel.font = cellFont;
self.detailTextLabel.textColor = [UIColor grayColor];
}
return self;
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
return [self._tableView _canPerformAction:action forCell:self sender:sender];
}
/// We use this to allow our table view to allow its delegate
/// to handle any action it chooses to support, without
/// explicitly implementing the method ourselelves.
///
/// Alternative considered: override respondsToSelector
/// to return NO. I decided against this for simplicity's
/// sake. I see this as "fixing" a poorly designed API.
/// That approach would require lots of boilerplate to
/// make the menu appear above this cell.
- (void)forwardInvocation:(NSInvocation *)invocation
{
// Must be unretained to avoid over-releasing
__unsafe_unretained id sender;
[invocation getArgument:&sender atIndex:2];
SEL action = invocation.selector;
// [self._tableView _performAction:action forCell:[self retain] sender:[sender retain]];
invocation.selector = @selector(_performAction:forCell:sender:);
[invocation setArgument:&action atIndex:2];
[invocation setArgument:(void *)&self atIndex:3];
[invocation setArgument:(void *)&sender atIndex:4];
[invocation invokeWithTarget:self._tableView];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
if ([self canPerformAction:selector withSender:nil]) {
return [self._tableView methodSignatureForSelector:@selector(_performAction:forCell:sender:)];
}
return [super methodSignatureForSelector:selector];
}
@end
+70 -191
View File
@@ -30,7 +30,10 @@
#import "FLEXObjcInternal.h"
#import <objc/runtime.h>
// For malloc_size
#import <malloc/malloc.h>
// For vm_region_64
#include <mach/mach.h>
#define ALWAYS_INLINE inline __attribute__((always_inline))
#define NEVER_INLINE inline __attribute__((noinline))
@@ -40,14 +43,18 @@
// as few modifications as possible. Changes are noted in boxed comments.
// https://opensource.apple.com/source/objc4/objc4-723/
// https://opensource.apple.com/source/objc4/objc4-723/runtime/objc-internal.h.auto.html
// https://opensource.apple.com/source/objc4/objc4-723/runtime/objc-private.h.auto.html
// https://opensource.apple.com/source/objc4/objc4-723/runtime/objc-config.h.auto.html
// https://opensource.apple.com/source/objc4/objc4-723/runtime/objc-object.h.auto.html
/////////////////////
// objc-internal.h //
/////////////////////
#if __LP64__
#define OBJC_HAVE_TAGGED_POINTERS 1
#endif
#if OBJC_HAVE_TAGGED_POINTERS
#if TARGET_OS_OSX && __x86_64__
// 64-bit Mac - tag bit is LSB
# define OBJC_MSB_TAGGED_POINTERS 0
@@ -56,38 +63,12 @@
# define OBJC_MSB_TAGGED_POINTERS 1
#endif
#define _OBJC_TAG_INDEX_MASK 0x7
// array slot includes the tag bit itself
#define _OBJC_TAG_SLOT_COUNT 16
#define _OBJC_TAG_SLOT_MASK 0xf
#define _OBJC_TAG_EXT_INDEX_MASK 0xff
// array slot has no extra bits
#define _OBJC_TAG_EXT_SLOT_COUNT 256
#define _OBJC_TAG_EXT_SLOT_MASK 0xff
#if OBJC_MSB_TAGGED_POINTERS
# define _OBJC_TAG_MASK (1UL<<63)
# define _OBJC_TAG_INDEX_SHIFT 60
# define _OBJC_TAG_SLOT_SHIFT 60
# define _OBJC_TAG_PAYLOAD_LSHIFT 4
# define _OBJC_TAG_PAYLOAD_RSHIFT 4
# define _OBJC_TAG_EXT_MASK (0xfUL<<60)
# define _OBJC_TAG_EXT_INDEX_SHIFT 52
# define _OBJC_TAG_EXT_SLOT_SHIFT 52
# define _OBJC_TAG_EXT_PAYLOAD_LSHIFT 12
# define _OBJC_TAG_EXT_PAYLOAD_RSHIFT 12
#else
# define _OBJC_TAG_MASK 1UL
# define _OBJC_TAG_INDEX_SHIFT 1
# define _OBJC_TAG_SLOT_SHIFT 0
# define _OBJC_TAG_PAYLOAD_LSHIFT 0
# define _OBJC_TAG_PAYLOAD_RSHIFT 4
# define _OBJC_TAG_EXT_MASK 0xfUL
# define _OBJC_TAG_EXT_INDEX_SHIFT 4
# define _OBJC_TAG_EXT_SLOT_SHIFT 4
# define _OBJC_TAG_EXT_PAYLOAD_LSHIFT 0
# define _OBJC_TAG_EXT_PAYLOAD_RSHIFT 12
#endif
//////////////////////////////////////
@@ -98,137 +79,6 @@ static BOOL flex_isTaggedPointer(const void *ptr)
return ((uintptr_t)ptr & _OBJC_TAG_MASK) == _OBJC_TAG_MASK;
}
///////////////////
// objc-config.h //
///////////////////
// Define SUPPORT_INDEXED_ISA=1 on platforms that store the class in the isa
// field as an index into a class table.
#if __ARM_ARCH_7K__ >= 2
# define SUPPORT_INDEXED_ISA 1
#else
# define SUPPORT_INDEXED_ISA 0
#endif
// Define SUPPORT_PACKED_ISA=1 on platforms that store the class in the isa
// field as a maskable pointer with other data around it.
#if (!__LP64__ || TARGET_OS_WIN32 || TARGET_OS_SIMULATOR)
# define SUPPORT_PACKED_ISA 0
#else
# define SUPPORT_PACKED_ISA 1
#endif
// Define SUPPORT_NONPOINTER_ISA=1 on any platform that may store something
// in the isa field that is not a raw pointer.
#if !SUPPORT_INDEXED_ISA && !SUPPORT_PACKED_ISA
# define SUPPORT_NONPOINTER_ISA 0
#else
# define SUPPORT_NONPOINTER_ISA 1
#endif
////////////////////
// objc-private.h //
////////////////////
union isa_t
{
isa_t() { }
isa_t(uintptr_t value) : bits(value) { }
Class cls;
uintptr_t bits;
#if SUPPORT_PACKED_ISA
// extra_rc must be the MSB-most field (so it matches carry/overflow flags)
// nonpointer must be the LSB (fixme or get rid of it)
// shiftcls must occupy the same bits that a real class pointer would
// bits + RC_ONE is equivalent to extra_rc + 1
// RC_HALF is the high bit of extra_rc (i.e. half of its range)
// future expansion:
// uintptr_t fast_rr : 1; // no r/r overrides
// uintptr_t lock : 2; // lock for atomic property, @synch
// uintptr_t extraBytes : 1; // allocated with extra bytes
# if __arm64__
# define ISA_MASK 0x0000000ffffffff8ULL
# define ISA_MAGIC_MASK 0x000003f000000001ULL
# define ISA_MAGIC_VALUE 0x000001a000000001ULL
struct {
uintptr_t nonpointer : 1;
uintptr_t has_assoc : 1;
uintptr_t has_cxx_dtor : 1;
uintptr_t shiftcls : 33; // MACH_VM_MAX_ADDRESS 0x1000000000
uintptr_t magic : 6;
uintptr_t weakly_referenced : 1;
uintptr_t deallocating : 1;
uintptr_t has_sidetable_rc : 1;
uintptr_t extra_rc : 19;
# define RC_ONE (1ULL<<45)
# define RC_HALF (1ULL<<18)
};
# elif __x86_64__
# define ISA_MASK 0x00007ffffffffff8ULL
# define ISA_MAGIC_MASK 0x001f800000000001ULL
# define ISA_MAGIC_VALUE 0x001d800000000001ULL
struct {
uintptr_t nonpointer : 1;
uintptr_t has_assoc : 1;
uintptr_t has_cxx_dtor : 1;
uintptr_t shiftcls : 44; // MACH_VM_MAX_ADDRESS 0x7fffffe00000
uintptr_t magic : 6;
uintptr_t weakly_referenced : 1;
uintptr_t deallocating : 1;
uintptr_t has_sidetable_rc : 1;
uintptr_t extra_rc : 8;
# define RC_ONE (1ULL<<56)
# define RC_HALF (1ULL<<7)
};
# else
# error unknown architecture for packed isa
# endif
// SUPPORT_PACKED_ISA
#endif
#if SUPPORT_INDEXED_ISA
# if __ARM_ARCH_7K__ >= 2
# define ISA_INDEX_IS_NPI 1
# define ISA_INDEX_MASK 0x0001FFFC
# define ISA_INDEX_SHIFT 2
# define ISA_INDEX_BITS 15
# define ISA_INDEX_COUNT (1 << ISA_INDEX_BITS)
# define ISA_INDEX_MAGIC_MASK 0x001E0001
# define ISA_INDEX_MAGIC_VALUE 0x001C0001
struct {
uintptr_t nonpointer : 1;
uintptr_t has_assoc : 1;
uintptr_t indexcls : 15;
uintptr_t magic : 4;
uintptr_t has_cxx_dtor : 1;
uintptr_t weakly_referenced : 1;
uintptr_t deallocating : 1;
uintptr_t has_sidetable_rc : 1;
uintptr_t extra_rc : 7;
# define RC_ONE (1ULL<<25)
# define RC_HALF (1ULL<<6)
};
# else
# error unknown architecture for indexed isa
# endif
// SUPPORT_INDEXED_ISA
#endif
};
///////////////////
// objc-object.h //
///////////////////
@@ -241,27 +91,7 @@ static BOOL flex_isExtTaggedPointer(const void *ptr)
return ((uintptr_t)ptr & _OBJC_TAG_EXT_MASK) == _OBJC_TAG_EXT_MASK;
}
struct flex_objc_object {
isa_t isa;
};
//////////////////////////////////////////////////////////
// Returns nil on platforms without nonpointer isa. //
// Supporting those platforms would be too complicated //
// for such a niche feature anyway. - @NSExceptional //
// //
// Code modified from objc_object::ISA() on 11/04/18 //
//////////////////////////////////////////////////////////
static id flex_getIsa(const flex_objc_object *object) {
#if SUPPORT_NONPOINTER_ISA
if (object->isa.nonpointer) {
return object_getClass((__bridge id)object);
}
return (__bridge Class)(void *)object->isa.bits;
#else
return nil;
#endif
}
/////////////////////////////////////
// FLEXObjectInternal //
@@ -269,27 +99,70 @@ static id flex_getIsa(const flex_objc_object *object) {
/////////////////////////////////////
extern "C" {
/// Assumes memory is valid and readable.
static BOOL FLEXPointerIsReadable(const void *inPtr)
{
kern_return_t error = KERN_SUCCESS;
vm_size_t vmsize;
vm_address_t address = (vm_address_t)inPtr;
vm_region_basic_info_data_t info;
mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
memory_object_name_t object;
error = vm_region_64(
mach_task_self(),
&address,
&vmsize,
VM_REGION_BASIC_INFO,
(vm_region_info_t)&info,
&info_count,
&object
);
if (error != KERN_SUCCESS) {
// vm_region/vm_region_64 returned an error
return NO;
} else if (!(BOOL)(info.protection & VM_PROT_READ)) {
return NO;
}
// Read the memory
vm_offset_t readMem = 0;
mach_msg_type_number_t size = 0;
address = (vm_address_t)inPtr;
error = vm_read(mach_task_self(), address, sizeof(uintptr_t), &readMem, &size);
if (error != KERN_SUCCESS) {
// vm_read returned an error
return NO;
}
return YES;
}
/// Accepts addresses that may or may not be readable.
/// https://blog.timac.org/2016/1124-testing-if-an-arbitrary-pointer-is-a-valid-objective-c-object/
BOOL FLEXPointerIsValidObjcObject(const void * ptr)
BOOL FLEXPointerIsValidObjcObject(const void *ptr)
{
uintptr_t pointer = (uintptr_t)ptr;
if (!ptr) {
return NO;
}
#if OBJC_HAVE_TAGGED_POINTERS
// Tagged pointers have 0x1 set, no other valid pointers do
// objc-internal.h -> _objc_isTaggedPointer()
if (flex_isTaggedPointer(ptr) || flex_isExtTaggedPointer(ptr)) {
return YES;
}
#endif
// Check pointer alignment
if ((pointer % sizeof(uintptr_t)) != 0) {
return NO;
}
// From LLDB:
// Pointers in a class_t will only have bits 0 through 46 set,
// so if any pointer has bits 47 through 63 high, we know that this is not a valid isa
@@ -297,13 +170,19 @@ BOOL FLEXPointerIsValidObjcObject(const void * ptr)
if ((pointer & 0xFFFF800000000000) != 0) {
return NO;
}
// http://www.sealiesoftware.com/blog/archive/2013/09/24/objc_explain_Non-pointer_isa.html :
if (flex_getIsa((const flex_objc_object *)ptr)) {
return YES;
// Make sure dereferencing this address won't crash
if (!FLEXPointerIsReadable(ptr)) {
return NO;
}
return NO;
// http://www.sealiesoftware.com/blog/archive/2013/09/24/objc_explain_Non-pointer_isa.html :
if (!object_getClass((__bridge id)ptr)) {
return NO;
}
return YES;
}
}
+3
View File
@@ -34,6 +34,7 @@
+ (NSString *)applicationImageName;
+ (NSString *)applicationName;
+ (NSString *)safeDescriptionForObject:(id)object;
+ (NSString *)addressOfObject:(id)object;
+ (UIFont *)defaultFontOfSize:(CGFloat)size;
+ (UIFont *)defaultTableViewCellLabelFont;
+ (NSString *)stringByEscapingHTMLEntitiesInString:(NSString *)originalString;
@@ -51,6 +52,8 @@
+ (NSArray<UIWindow *> *)allWindows;
+ (void)alert:(NSString *)title message:(NSString *)message from:(UIViewController *)viewController;
// Swizzling utilities
+ (SEL)swizzledSelectorForSelector:(SEL)selector;
+19 -4
View File
@@ -48,7 +48,7 @@
+ (UIViewController *)viewControllerForView:(UIView *)view
{
UIViewController *viewController = nil;
SEL viewDelSel = NSSelectorFromString([NSString stringWithFormat:@"%@ewDelegate", @"_vi"]);
SEL viewDelSel = NSSelectorFromString(@"_viewDelegate");
if ([view respondsToSelector:viewDelSel]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
@@ -58,7 +58,8 @@
return viewController;
}
+ (UIViewController *)viewControllerForAncestralView:(UIView *)view{
+ (UIViewController *)viewControllerForAncestralView:(UIView *)view
{
UIViewController *viewController = nil;
SEL viewDelSel = NSSelectorFromString([NSString stringWithFormat:@"%@ewControllerForAncestor", @"_vi"]);
if ([view respondsToSelector:viewDelSel]) {
@@ -126,6 +127,11 @@
return description;
}
+ (NSString *)addressOfObject:(id)object
{
return [NSString stringWithFormat:@"%p", object];
}
+ (UIFont *)defaultFontOfSize:(CGFloat)size
{
return [UIFont fontWithName:@"HelveticaNeue" size:size];
@@ -249,7 +255,8 @@
return httpResponseString;
}
+ (BOOL)isErrorStatusCodeFromURLResponse:(NSURLResponse *)response {
+ (BOOL)isErrorStatusCodeFromURLResponse:(NSURLResponse *)response
{
NSIndexSet *errorStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(400, 200)];
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
@@ -260,7 +267,6 @@
return NO;
}
+ (NSDictionary<NSString *, id> *)dictionaryFromQuery:(NSString *)query
{
NSMutableDictionary<NSString *, id> *queryDictionary = [NSMutableDictionary dictionary];
@@ -372,6 +378,15 @@
return windows;
}
+ (void)alert:(NSString *)title message:(NSString *)message from:(UIViewController *)viewController
{
[[[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:@"Dismiss", nil] show];
}
+ (SEL)swizzledSelectorForSelector:(SEL)selector
{
return NSSelectorFromString([NSString stringWithFormat:@"_flex_swizzle_%x_%@", arc4random(), NSStringFromSelector(selector)]);
+22 -10
View File
@@ -45,9 +45,12 @@
535682BF18F3670300BAAD62 /* UIColor+AAPLApplicationSpecific.m in Sources */ = {isa = PBXBuildFile; fileRef = 535682A618F3670300BAAD62 /* UIColor+AAPLApplicationSpecific.m */; };
53874F9918F36B1800510922 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 53874F9718F36B1800510922 /* Localizable.strings */; };
779B1EF51C0C4F25001F5E49 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 779B1EF41C0C4F25001F5E49 /* libsqlite3.dylib */; };
9420A1AD1C1E84EE00B587DF /* FLEX.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9420A1AC1C1E84EE00B587DF /* FLEX.framework */; };
943203FE1978F42F00E24DB3 /* AAPLCatalogTableTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 943203FD1978F42F00E24DB3 /* AAPLCatalogTableTableViewController.m */; };
94CB4D431A97183E0054A905 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 94CB4D421A97183E0054A905 /* libz.dylib */; };
C34C811A22678CF5006C4D4B /* Person.m in Sources */ = {isa = PBXBuildFile; fileRef = C34C811922678CF5006C4D4B /* Person.m */; };
C3EF50CD22610FE200B0BE49 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = C3EF50CC22610FE200B0BE49 /* LaunchScreen.xib */; };
C3FB77E52266367F00DF4E73 /* FLEX.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3FB77E42266367F00DF4E73 /* FLEX.framework */; };
C3FB77E6226636AA00DF4E73 /* FLEX.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C3FB77E42266367F00DF4E73 /* FLEX.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -57,6 +60,7 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
C3FB77E6226636AA00DF4E73 /* FLEX.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@@ -132,10 +136,13 @@
535682A618F3670300BAAD62 /* UIColor+AAPLApplicationSpecific.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+AAPLApplicationSpecific.m"; sourceTree = "<group>"; };
53874F9818F36B1800510922 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
779B1EF41C0C4F25001F5E49 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = ../../../../../../usr/lib/libsqlite3.dylib; sourceTree = "<group>"; };
9420A1AC1C1E84EE00B587DF /* FLEX.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FLEX.framework; path = "../../../Library/Developer/Xcode/DerivedData/FLEX-gixtctkeshzdbwbdapvulcvleeiu/Build/Products/Debug-iphoneos/FLEX.framework"; sourceTree = "<group>"; };
943203FC1978F42F00E24DB3 /* AAPLCatalogTableTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AAPLCatalogTableTableViewController.h; sourceTree = "<group>"; };
943203FD1978F42F00E24DB3 /* AAPLCatalogTableTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AAPLCatalogTableTableViewController.m; sourceTree = "<group>"; };
94CB4D421A97183E0054A905 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
C34C811822678CF5006C4D4B /* Person.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Person.h; sourceTree = "<group>"; };
C34C811922678CF5006C4D4B /* Person.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Person.m; sourceTree = "<group>"; };
C3EF50CC22610FE200B0BE49 /* LaunchScreen.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = "<group>"; };
C3FB77E42266367F00DF4E73 /* FLEX.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = FLEX.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -143,7 +150,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9420A1AD1C1E84EE00B587DF /* FLEX.framework in Frameworks */,
C3FB77E52266367F00DF4E73 /* FLEX.framework in Frameworks */,
779B1EF51C0C4F25001F5E49 /* libsqlite3.dylib in Frameworks */,
94CB4D431A97183E0054A905 /* libz.dylib in Frameworks */,
5356824018F3656900BAAD62 /* CoreGraphics.framework in Frameworks */,
@@ -188,7 +195,7 @@
5356823C18F3656900BAAD62 /* Frameworks */ = {
isa = PBXGroup;
children = (
9420A1AC1C1E84EE00B587DF /* FLEX.framework */,
C3FB77E42266367F00DF4E73 /* FLEX.framework */,
779B1EF41C0C4F25001F5E49 /* libsqlite3.dylib */,
94CB4D421A97183E0054A905 /* libz.dylib */,
5356823D18F3656900BAAD62 /* Foundation.framework */,
@@ -216,6 +223,7 @@
5356824518F3656900BAAD62 /* UICatalog-Info.plist */,
5356824B18F3656900BAAD62 /* UICatalog-Prefix.pch */,
53874F9718F36B1800510922 /* Localizable.strings */,
C3EF50CC22610FE200B0BE49 /* LaunchScreen.xib */,
);
name = "Supporting Files";
sourceTree = "<group>";
@@ -292,6 +300,8 @@
535682A618F3670300BAAD62 /* UIColor+AAPLApplicationSpecific.m */,
5356824F18F3656900BAAD62 /* Main_iPhone.storyboard */,
5356825218F3656900BAAD62 /* Main_iPad.storyboard */,
C34C811822678CF5006C4D4B /* Person.h */,
C34C811922678CF5006C4D4B /* Person.m */,
);
name = Application;
sourceTree = "<group>";
@@ -332,7 +342,7 @@
5356823218F3656900BAAD62 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1000;
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = f;
TargetAttributes = {
5356823918F3656900BAAD62 = {
@@ -342,7 +352,7 @@
};
buildConfigurationList = 5356823518F3656900BAAD62 /* Build configuration list for PBXProject "UICatalog" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
@@ -366,6 +376,7 @@
22679D5D1C741A7A002248FC /* dogs.realm in Resources */,
5356825418F3656900BAAD62 /* Main_iPad.storyboard in Resources */,
53874F9918F36B1800510922 /* Localizable.strings in Resources */,
C3EF50CD22610FE200B0BE49 /* LaunchScreen.xib in Resources */,
5356825918F3656900BAAD62 /* Images.xcassets in Resources */,
3EC6487318FF8A5000024205 /* ReadMe.txt in Resources */,
5356825118F3656900BAAD62 /* Main_iPhone.storyboard in Resources */,
@@ -391,6 +402,7 @@
535682AF18F3670300BAAD62 /* AAPLDefaultSearchBarViewController.m in Sources */,
535682BC18F3670300BAAD62 /* AAPLTextViewController.m in Sources */,
535682B418F3670300BAAD62 /* AAPLPickerViewController.m in Sources */,
C34C811A22678CF5006C4D4B /* Person.m in Sources */,
535682BE18F3670300BAAD62 /* AAPLWebViewController.m in Sources */,
535682BB18F3670300BAAD62 /* AAPLTextFieldViewController.m in Sources */,
535682BF18F3670300BAAD62 /* UIColor+AAPLApplicationSpecific.m in Sources */,
@@ -445,6 +457,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
@@ -498,6 +511,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
@@ -544,7 +558,6 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
DEVELOPMENT_TEAM = S6N2F22V2Z;
EXCLUDED_SOURCE_FILE_NAMES = "";
FRAMEWORK_SEARCH_PATHS = (
@@ -555,7 +568,7 @@
GCC_PREFIX_HEADER = "UICatalog/UICatalog-Prefix.pch";
INFOPLIST_FILE = "UICatalog/UICatalog-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.UICatalog";
PRODUCT_BUNDLE_IDENTIFIER = com.flipboard.FLEX.example;
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
@@ -565,7 +578,6 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
DEVELOPMENT_TEAM = S6N2F22V2Z;
EXCLUDED_SOURCE_FILE_NAMES = "FLEX*";
FRAMEWORK_SEARCH_PATHS = (
@@ -576,7 +588,7 @@
GCC_PREFIX_HEADER = "UICatalog/UICatalog-Prefix.pch";
INFOPLIST_FILE = "UICatalog/UICatalog-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.UICatalog";
PRODUCT_BUNDLE_IDENTIFIER = com.flipboard.FLEX.example;
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
+5
View File
@@ -49,6 +49,7 @@
#if DEBUG
#import <FLEX/FLEX.h>
#import "Person.h"
#if __has_include(<Realm/Realm.h>)
#import "Dog.h"
#import "Owner.h"
@@ -71,6 +72,10 @@
[self sendExampleNetworkRequests];
self.repeatingLogExampleTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(sendExampleLogMessage) userInfo:nil repeats:YES];
// For testing unarchiving of objects
NSString *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *whereToSaveBob = [documents stringByAppendingPathComponent:@"Bob.plist"];
[NSKeyedArchiver archiveRootObject:[Person bob] toFile:whereToSaveBob];
#if __has_include(<Realm/Realm.h>)
[self setUpRealm];
#endif
@@ -1,20 +1,55 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
@@ -44,6 +79,16 @@
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -1,74 +0,0 @@
{
"images" : [
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "736h",
"filename" : "iPhone6PlusPortrait.png",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "736h",
"filename" : "iPhone6PlusLandscape.png",
"minimum-system-version" : "8.0",
"orientation" : "landscape",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "667h",
"filename" : "iPhone6Portrait.png",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"filename" : "Launch@2x.png",
"scale" : "2x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "retina4",
"filename" : "Launch@2x~568h.png",
"minimum-system-version" : "7.0",
"orientation" : "portrait",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"filename" : "Launch.png",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"filename" : "Launch@2x.png",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"filename" : "Launch@2x~568h.png",
"subtype" : "retina4",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "bookmark_icon_1x.png"
"filename" : "bookmark_icon_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "bookmark_icon_2x.png"
"filename" : "bookmark_icon_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "bookmark_icon_highlighted_1x.png"
"filename" : "bookmark_icon_highlighted_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "bookmark_icon_highlighted_2x.png"
"filename" : "bookmark_icon_highlighted_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "checkmark_icon_1x.png"
"filename" : "checkmark_icon_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "checkmark_icon_2x.png"
"filename" : "checkmark_icon_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,12 +2,16 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "image_animal_5.png"
"filename" : "image_animal_5.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,12 +2,16 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "image_animal_2.png"
"filename" : "image_animal_2.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,12 +2,16 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "image_animal_3.png"
"filename" : "image_animal_3.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,12 +2,16 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "image_animal_4.png"
"filename" : "image_animal_4.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,12 +2,16 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "image_animal_1.png"
"filename" : "image_animal_1.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "search_bar_bg_1x.png"
"filename" : "search_bar_bg_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "search_bar_bg_2x.png"
"filename" : "search_bar_bg_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "search_icon_1x.png"
"filename" : "search_icon_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "search_icon_2x.png"
"filename" : "search_icon_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "slider_blue_track_1x.png"
"filename" : "slider_blue_track_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "slider_blue_track_2x.png"
"filename" : "slider_blue_track_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "slider_green_track_1x.png"
"filename" : "slider_green_track_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "slider_green_track_2x.png"
"filename" : "slider_green_track_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "slider_thumb_1x.png"
"filename" : "slider_thumb_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "slider_thumb_2x.png"
"filename" : "slider_thumb_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "stepper_and_segment_background_1x.png"
"filename" : "stepper_and_segment_background_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "stepper_and_segment_background_2x.png"
"filename" : "stepper_and_segment_background_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "stepper_and_segment_background_disabled_1x.png"
"filename" : "stepper_and_segment_background_disabled_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "stepper_and_segment_background_disabled_2x.png"
"filename" : "stepper_and_segment_background_disabled_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "stepper_and_segment_background_highlighted_1x.png"
"filename" : "stepper_and_segment_background_highlighted_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "stepper_and_segment_background_highlighted_2x.png"
"filename" : "stepper_and_segment_background_highlighted_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "stepper_and_segment_segment_divider_1x.png"
"filename" : "stepper_and_segment_segment_divider_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "stepper_and_segment_segment_divider_2x.png"
"filename" : "stepper_and_segment_segment_divider_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "decrement_1x.png"
"filename" : "decrement_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "decrement_2x.png"
"filename" : "decrement_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "stepper_increment_1x.png"
"filename" : "stepper_increment_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "stepper_increment_2x.png"
"filename" : "stepper_increment_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "text_field_background_1x.png"
"filename" : "text_field_background_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "text_field_background_2x.png"
"filename" : "text_field_background_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "text_field_purple_right_view_1x.png"
"filename" : "text_field_purple_right_view_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "text_field_purple_right_view_2x.png"
"filename" : "text_field_purple_right_view_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "text_view_attachment_1x.png"
"filename" : "text_view_attachment_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "text_view_attachment_2x.png"
"filename" : "text_view_attachment_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "toolbar_background_1x.png"
"filename" : "toolbar_background_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "toolbar_background_2x.png"
"filename" : "toolbar_background_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "tools_icon_1x.png"
"filename" : "tools_icon_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "tools_icon_2x.png"
"filename" : "tools_icon_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
@@ -2,13 +2,17 @@
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "x_icon_1x.png"
"filename" : "x_icon_1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "x_icon_2x.png"
"filename" : "x_icon_2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
+32
View File
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina5_9" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="FLEX" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Vr9-JF-Ls4">
<rect key="frame" x="130.66666666666666" y="275.66666666666669" width="114" height="60"/>
<fontDescription key="fontDescription" type="system" pointSize="50"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="Vr9-JF-Ls4" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="IUa-oU-7Gl"/>
<constraint firstItem="Vr9-JF-Ls4" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" multiplier="3:4" constant="1" id="tsn-lM-lhl"/>
</constraints>
</view>
</objects>
</document>
+20
View File
@@ -0,0 +1,20 @@
//
// Person.h
// UICatalog
//
// Created by Tanner on 4/17/19.
// Copyright © 2019 f. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Person : NSObject <NSCoding>
+ (instancetype)bob;
@property (nonatomic, readonly) NSString *name;
@property (nonatomic, readonly) NSInteger age;
@property (nonatomic, readonly) CGFloat height;
@property (nonatomic, readonly) NSNumber *numberOfKids;
@end
+37
View File
@@ -0,0 +1,37 @@
//
// Person.m
// UICatalog
//
// Created by Tanner on 4/17/19.
// Copyright © 2019 f. All rights reserved.
//
#import "Person.h"
@implementation Person
+ (id)bob {
Person *bob = [Person new];
bob->_name = @"Bob";
bob->_age = 50;
bob->_height = 5.8;
bob->_numberOfKids = @3;
return bob;
}
- (void)encodeWithCoder:(nonnull NSCoder *)coder {
[coder encodeObject:self.name forKey:@"name"];
[coder encodeInteger:self.age forKey:@"age"];
[coder encodeDouble:self.height forKey:@"height"];
[coder encodeObject:self.numberOfKids forKey:@"numberOfKids"];
}
- (nullable instancetype)initWithCoder:(nonnull NSCoder *)coder {
self->_name = [coder decodeObjectForKey:@"name"];
self->_age = [coder decodeIntegerForKey:@"age"];
self->_height = [coder decodeDoubleForKey:@"height"];
self->_numberOfKids= [coder decodeObjectForKey:@"numberOfKids"];
return self;
}
@end
+7 -5
View File
@@ -2,11 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
@@ -29,6 +24,13 @@
<string>2.12</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main_iPhone</string>
<key>UIMainStoryboardFile~ipad</key>
+4 -4
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = "FLEX"
spec.version = "2.4.0"
spec.version = "3.0.0"
spec.summary = "A set of in-app debugging and exploration tools for iOS"
spec.description = <<-DESC
- Inspect and modify views in the hierarchy.
@@ -27,11 +27,11 @@ Pod::Spec.new do |spec|
"http://engineering.flipboard.com/assets/flex/flex-readme-reverse-2.png" ]
spec.license = { :type => "BSD", :file => "LICENSE" }
spec.author = { "Ryan Olson" => "ryanolsonk@gmail.com" }
spec.social_media_url = "https://twitter.com/ryanolsonk"
spec.author = { "Tanner Bennett" => "tannerbennett@me.com" }
spec.social_media_url = "https://twitter.com/NSExceptional"
spec.platform = :ios, "8.0"
spec.source = { :git => "https://github.com/Flipboard/FLEX.git", :tag => "#{spec.version}" }
spec.source_files = "Classes/**/*.{h,m}"
spec.source_files = "Classes/**/*.{h,m,mm}"
spec.frameworks = [ "Foundation", "UIKit", "CoreGraphics" ]
spec.libraries = [ "z", "sqlite3" ]
spec.requires_arc = true
+77 -35
View File
@@ -44,8 +44,6 @@
3A4C94DC1B5B21410088C3F2 /* FLEXViewExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A4C94531B5B21410088C3F2 /* FLEXViewExplorerViewController.m */; };
3A4C94DD1B5B21410088C3F2 /* FLEXHeapEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A4C94551B5B21410088C3F2 /* FLEXHeapEnumerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
3A4C94DE1B5B21410088C3F2 /* FLEXHeapEnumerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A4C94561B5B21410088C3F2 /* FLEXHeapEnumerator.m */; };
3A4C94DF1B5B21410088C3F2 /* FLEXMultilineTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A4C94571B5B21410088C3F2 /* FLEXMultilineTableViewCell.h */; settings = {ATTRIBUTES = (Private, ); }; };
3A4C94E01B5B21410088C3F2 /* FLEXMultilineTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A4C94581B5B21410088C3F2 /* FLEXMultilineTableViewCell.m */; };
3A4C94E11B5B21410088C3F2 /* FLEXResources.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A4C94591B5B21410088C3F2 /* FLEXResources.h */; settings = {ATTRIBUTES = (Private, ); }; };
3A4C94E21B5B21410088C3F2 /* FLEXResources.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A4C945A1B5B21410088C3F2 /* FLEXResources.m */; };
3A4C94E31B5B21410088C3F2 /* FLEXRuntimeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A4C945B1B5B21410088C3F2 /* FLEXRuntimeUtility.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -179,6 +177,14 @@
C3DB9F642107FC9600B46809 /* FLEXObjectRef.h in Headers */ = {isa = PBXBuildFile; fileRef = C3DB9F622107FC9600B46809 /* FLEXObjectRef.h */; };
C3DB9F652107FC9600B46809 /* FLEXObjectRef.m in Sources */ = {isa = PBXBuildFile; fileRef = C3DB9F632107FC9600B46809 /* FLEXObjectRef.m */; };
C3DC287C223ED5F200F48AA6 /* FLEXOSLogController.m in Sources */ = {isa = PBXBuildFile; fileRef = C34EE30721CB23CC00BD3A7C /* FLEXOSLogController.m */; };
C3F31D3D2267D883003C991A /* FLEXSubtitleTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = C3F31D342267D883003C991A /* FLEXSubtitleTableViewCell.h */; };
C3F31D3E2267D883003C991A /* FLEXTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = C3F31D352267D883003C991A /* FLEXTableViewCell.h */; };
C3F31D3F2267D883003C991A /* FLEXMultilineTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = C3F31D362267D883003C991A /* FLEXMultilineTableViewCell.h */; };
C3F31D402267D883003C991A /* FLEXSubtitleTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C3F31D372267D883003C991A /* FLEXSubtitleTableViewCell.m */; };
C3F31D412267D883003C991A /* FLEXMultilineTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C3F31D382267D883003C991A /* FLEXMultilineTableViewCell.m */; };
C3F31D422267D883003C991A /* FLEXTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C3F31D392267D883003C991A /* FLEXTableViewCell.m */; };
C3F31D432267D883003C991A /* FLEXTableView.h in Headers */ = {isa = PBXBuildFile; fileRef = C3F31D3B2267D883003C991A /* FLEXTableView.h */; };
C3F31D442267D883003C991A /* FLEXTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = C3F31D3C2267D883003C991A /* FLEXTableView.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -232,8 +238,6 @@
3A4C94531B5B21410088C3F2 /* FLEXViewExplorerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXViewExplorerViewController.m; sourceTree = "<group>"; };
3A4C94551B5B21410088C3F2 /* FLEXHeapEnumerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXHeapEnumerator.h; sourceTree = "<group>"; };
3A4C94561B5B21410088C3F2 /* FLEXHeapEnumerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXHeapEnumerator.m; sourceTree = "<group>"; };
3A4C94571B5B21410088C3F2 /* FLEXMultilineTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMultilineTableViewCell.h; sourceTree = "<group>"; };
3A4C94581B5B21410088C3F2 /* FLEXMultilineTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMultilineTableViewCell.m; sourceTree = "<group>"; };
3A4C94591B5B21410088C3F2 /* FLEXResources.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXResources.h; sourceTree = "<group>"; };
3A4C945A1B5B21410088C3F2 /* FLEXResources.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXResources.m; sourceTree = "<group>"; };
3A4C945B1B5B21410088C3F2 /* FLEXRuntimeUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRuntimeUtility.h; sourceTree = "<group>"; };
@@ -369,6 +373,14 @@
C3DA55FD21A76406005DDA60 /* FLEXMutableFieldEditorViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FLEXMutableFieldEditorViewController.m; sourceTree = "<group>"; };
C3DB9F622107FC9600B46809 /* FLEXObjectRef.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FLEXObjectRef.h; sourceTree = "<group>"; };
C3DB9F632107FC9600B46809 /* FLEXObjectRef.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FLEXObjectRef.m; sourceTree = "<group>"; };
C3F31D342267D883003C991A /* FLEXSubtitleTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSubtitleTableViewCell.h; sourceTree = "<group>"; };
C3F31D352267D883003C991A /* FLEXTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableViewCell.h; sourceTree = "<group>"; };
C3F31D362267D883003C991A /* FLEXMultilineTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMultilineTableViewCell.h; sourceTree = "<group>"; };
C3F31D372267D883003C991A /* FLEXSubtitleTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXSubtitleTableViewCell.m; sourceTree = "<group>"; };
C3F31D382267D883003C991A /* FLEXMultilineTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMultilineTableViewCell.m; sourceTree = "<group>"; };
C3F31D392267D883003C991A /* FLEXTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableViewCell.m; sourceTree = "<group>"; };
C3F31D3B2267D883003C991A /* FLEXTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableView.h; sourceTree = "<group>"; };
C3F31D3C2267D883003C991A /* FLEXTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableView.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -451,32 +463,10 @@
3A4C943B1B5B21410088C3F2 /* ObjectExplorers */ = {
isa = PBXGroup;
children = (
3A4C943C1B5B21410088C3F2 /* FLEXArrayExplorerViewController.h */,
3A4C943D1B5B21410088C3F2 /* FLEXArrayExplorerViewController.m */,
3A4C943E1B5B21410088C3F2 /* FLEXClassExplorerViewController.h */,
3A4C943F1B5B21410088C3F2 /* FLEXClassExplorerViewController.m */,
3A4C94401B5B21410088C3F2 /* FLEXDefaultsExplorerViewController.h */,
3A4C94411B5B21410088C3F2 /* FLEXDefaultsExplorerViewController.m */,
3A4C94421B5B21410088C3F2 /* FLEXDictionaryExplorerViewController.h */,
3A4C94431B5B21410088C3F2 /* FLEXDictionaryExplorerViewController.m */,
3A4C94441B5B21410088C3F2 /* FLEXGlobalsTableViewControllerEntry.h */,
3A4C94451B5B21410088C3F2 /* FLEXGlobalsTableViewControllerEntry.m */,
3A4C94461B5B21410088C3F2 /* FLEXImageExplorerViewController.h */,
3A4C94471B5B21410088C3F2 /* FLEXImageExplorerViewController.m */,
3A4C94481B5B21410088C3F2 /* FLEXLayerExplorerViewController.h */,
3A4C94491B5B21410088C3F2 /* FLEXLayerExplorerViewController.m */,
3A4C944A1B5B21410088C3F2 /* FLEXObjectExplorerFactory.h */,
3A4C944B1B5B21410088C3F2 /* FLEXObjectExplorerFactory.m */,
3A4C944C1B5B21410088C3F2 /* FLEXObjectExplorerViewController.h */,
3A4C944D1B5B21410088C3F2 /* FLEXObjectExplorerViewController.m */,
3A4C944E1B5B21410088C3F2 /* FLEXSetExplorerViewController.h */,
3A4C944F1B5B21410088C3F2 /* FLEXSetExplorerViewController.m */,
3A4C94501B5B21410088C3F2 /* FLEXViewControllerExplorerViewController.h */,
3A4C94511B5B21410088C3F2 /* FLEXViewControllerExplorerViewController.m */,
3A4C94521B5B21410088C3F2 /* FLEXViewExplorerViewController.h */,
3A4C94531B5B21410088C3F2 /* FLEXViewExplorerViewController.m */,
C395D6D721789BD800BEAD4D /* FLEXColorExplorerViewController.h */,
C395D6D821789BD800BEAD4D /* FLEXColorExplorerViewController.m */,
C3F31D3A2267D883003C991A /* Views */,
C3F31D452267D8A2003C991A /* Controllers */,
);
path = ObjectExplorers;
sourceTree = "<group>";
@@ -486,8 +476,6 @@
children = (
3A4C94551B5B21410088C3F2 /* FLEXHeapEnumerator.h */,
3A4C94561B5B21410088C3F2 /* FLEXHeapEnumerator.m */,
3A4C94571B5B21410088C3F2 /* FLEXMultilineTableViewCell.h */,
3A4C94581B5B21410088C3F2 /* FLEXMultilineTableViewCell.m */,
3A4C94591B5B21410088C3F2 /* FLEXResources.h */,
3A4C945A1B5B21410088C3F2 /* FLEXResources.m */,
C37A0C91218BAC9600848CA7 /* FLEXObjcInternal.h */,
@@ -720,6 +708,52 @@
name = ExplorerInterface;
sourceTree = "<group>";
};
C3F31D3A2267D883003C991A /* Views */ = {
isa = PBXGroup;
children = (
C3F31D3B2267D883003C991A /* FLEXTableView.h */,
C3F31D3C2267D883003C991A /* FLEXTableView.m */,
C3F31D352267D883003C991A /* FLEXTableViewCell.h */,
C3F31D392267D883003C991A /* FLEXTableViewCell.m */,
C3F31D342267D883003C991A /* FLEXSubtitleTableViewCell.h */,
C3F31D372267D883003C991A /* FLEXSubtitleTableViewCell.m */,
C3F31D362267D883003C991A /* FLEXMultilineTableViewCell.h */,
C3F31D382267D883003C991A /* FLEXMultilineTableViewCell.m */,
);
path = Views;
sourceTree = "<group>";
};
C3F31D452267D8A2003C991A /* Controllers */ = {
isa = PBXGroup;
children = (
3A4C944C1B5B21410088C3F2 /* FLEXObjectExplorerViewController.h */,
3A4C944D1B5B21410088C3F2 /* FLEXObjectExplorerViewController.m */,
3A4C943C1B5B21410088C3F2 /* FLEXArrayExplorerViewController.h */,
3A4C943D1B5B21410088C3F2 /* FLEXArrayExplorerViewController.m */,
3A4C943E1B5B21410088C3F2 /* FLEXClassExplorerViewController.h */,
3A4C943F1B5B21410088C3F2 /* FLEXClassExplorerViewController.m */,
3A4C94401B5B21410088C3F2 /* FLEXDefaultsExplorerViewController.h */,
3A4C94411B5B21410088C3F2 /* FLEXDefaultsExplorerViewController.m */,
3A4C94421B5B21410088C3F2 /* FLEXDictionaryExplorerViewController.h */,
3A4C94431B5B21410088C3F2 /* FLEXDictionaryExplorerViewController.m */,
3A4C94441B5B21410088C3F2 /* FLEXGlobalsTableViewControllerEntry.h */,
3A4C94451B5B21410088C3F2 /* FLEXGlobalsTableViewControllerEntry.m */,
3A4C94461B5B21410088C3F2 /* FLEXImageExplorerViewController.h */,
3A4C94471B5B21410088C3F2 /* FLEXImageExplorerViewController.m */,
3A4C94481B5B21410088C3F2 /* FLEXLayerExplorerViewController.h */,
3A4C94491B5B21410088C3F2 /* FLEXLayerExplorerViewController.m */,
3A4C944E1B5B21410088C3F2 /* FLEXSetExplorerViewController.h */,
3A4C944F1B5B21410088C3F2 /* FLEXSetExplorerViewController.m */,
3A4C94501B5B21410088C3F2 /* FLEXViewControllerExplorerViewController.h */,
3A4C94511B5B21410088C3F2 /* FLEXViewControllerExplorerViewController.m */,
3A4C94521B5B21410088C3F2 /* FLEXViewExplorerViewController.h */,
3A4C94531B5B21410088C3F2 /* FLEXViewExplorerViewController.m */,
C395D6D721789BD800BEAD4D /* FLEXColorExplorerViewController.h */,
C395D6D821789BD800BEAD4D /* FLEXColorExplorerViewController.m */,
);
path = Controllers;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@@ -748,7 +782,6 @@
3A4C94DB1B5B21410088C3F2 /* FLEXViewExplorerViewController.h in Headers */,
3A4C95321B5B21410088C3F2 /* FLEXSystemLogTableViewCell.h in Headers */,
3A4C94F91B5B21410088C3F2 /* FLEXArgumentInputNumberView.h in Headers */,
3A4C94DF1B5B21410088C3F2 /* FLEXMultilineTableViewCell.h in Headers */,
3A4C953A1B5B21410088C3F2 /* FLEXNetworkSettingsTableViewController.h in Headers */,
3A4C94D11B5B21410088C3F2 /* FLEXLayerExplorerViewController.h in Headers */,
779B1ED01C0C4D7C001F5E49 /* FLEXMultiColumnTableView.h in Headers */,
@@ -772,7 +805,9 @@
224D49AA1C673AB5000EAB86 /* FLEXSQLiteDatabaseManager.h in Headers */,
3A4C95031B5B21410088C3F2 /* FLEXArgumentInputView.h in Headers */,
94A5151D1C4CA1F10063292F /* FLEXExplorerViewController.h in Headers */,
C3F31D3F2267D883003C991A /* FLEXMultilineTableViewCell.h in Headers */,
3A4C94C51B5B21410088C3F2 /* FLEXArrayExplorerViewController.h in Headers */,
C3F31D432267D883003C991A /* FLEXTableView.h in Headers */,
3A4C94CB1B5B21410088C3F2 /* FLEXDictionaryExplorerViewController.h in Headers */,
3A4C95071B5B21410088C3F2 /* FLEXDefaultEditorViewController.h in Headers */,
C309B82F223ED64400B228EC /* FLEXLogController.h in Headers */,
@@ -786,10 +821,12 @@
3A4C94EF1B5B21410088C3F2 /* FLEXArgumentInputDateView.h in Headers */,
3A4C94C71B5B21410088C3F2 /* FLEXClassExplorerViewController.h in Headers */,
3A4C94F71B5B21410088C3F2 /* FLEXArgumentInputNotSupportedView.h in Headers */,
C3F31D3E2267D883003C991A /* FLEXTableViewCell.h in Headers */,
3A4C94E51B5B21410088C3F2 /* FLEXUtility.h in Headers */,
3A4C94CF1B5B21410088C3F2 /* FLEXImageExplorerViewController.h in Headers */,
2EF6B04E1D494BE50006BDA5 /* FLEXNetworkCurlLogger.h in Headers */,
3A4C950B1B5B21410088C3F2 /* FLEXFieldEditorViewController.h in Headers */,
C3F31D3D2267D883003C991A /* FLEXSubtitleTableViewCell.h in Headers */,
94A515251C4CA2080063292F /* FLEXExplorerToolbar.h in Headers */,
3A4C953C1B5B21410088C3F2 /* FLEXNetworkTransaction.h in Headers */,
3A4C94D71B5B21410088C3F2 /* FLEXSetExplorerViewController.h in Headers */,
@@ -862,7 +899,7 @@
isa = PBXProject;
attributes = {
CLASSPREFIX = FLEX;
LastUpgradeCheck = 0930;
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = Flipboard;
TargetAttributes = {
1C27A8B51F0E5A0300F0D02D = {
@@ -875,11 +912,11 @@
};
buildConfigurationList = 3A4C94191B5B20570088C3F2 /* Build configuration list for PBXProject "FLEX" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
mainGroup = 3A4C94151B5B20570088C3F2;
productRefGroup = 3A4C94201B5B20570088C3F2 /* Products */;
@@ -941,6 +978,7 @@
C3DA55FF21A76406005DDA60 /* FLEXMutableFieldEditorViewController.m in Sources */,
3A4C95081B5B21410088C3F2 /* FLEXDefaultEditorViewController.m in Sources */,
779B1ED11C0C4D7C001F5E49 /* FLEXMultiColumnTableView.m in Sources */,
C3F31D412267D883003C991A /* FLEXMultilineTableViewCell.m in Sources */,
3A4C94EE1B5B21410088C3F2 /* FLEXArgumentInputColorView.m in Sources */,
3A4C94F01B5B21410088C3F2 /* FLEXArgumentInputDateView.m in Sources */,
3A4C94CA1B5B21410088C3F2 /* FLEXDefaultsExplorerViewController.m in Sources */,
@@ -948,7 +986,7 @@
679F64871BD53B7B00A8C94C /* FLEXCookiesTableViewController.m in Sources */,
3A4C94CE1B5B21410088C3F2 /* FLEXGlobalsTableViewControllerEntry.m in Sources */,
3A4C94FE1B5B21410088C3F2 /* FLEXArgumentInputStructView.m in Sources */,
3A4C94E01B5B21410088C3F2 /* FLEXMultilineTableViewCell.m in Sources */,
C3F31D402267D883003C991A /* FLEXSubtitleTableViewCell.m in Sources */,
3A4C95431B5B21410088C3F2 /* FLEXNetworkObserver.m in Sources */,
3A4C94D21B5B21410088C3F2 /* FLEXLayerExplorerViewController.m in Sources */,
779B1EDB1C0C4D7C001F5E49 /* FLEXTableListViewController.m in Sources */,
@@ -969,6 +1007,7 @@
94A515281C4CA2080063292F /* FLEXToolbarItem.m in Sources */,
3A4C94D81B5B21410088C3F2 /* FLEXSetExplorerViewController.m in Sources */,
3A4C95311B5B21410088C3F2 /* FLEXSystemLogMessage.m in Sources */,
C3F31D422267D883003C991A /* FLEXTableViewCell.m in Sources */,
3A4C94F41B5B21410088C3F2 /* FLEXArgumentInputFontView.m in Sources */,
3A4C953B1B5B21410088C3F2 /* FLEXNetworkSettingsTableViewController.m in Sources */,
3A4C94FC1B5B21410088C3F2 /* FLEXArgumentInputStringView.m in Sources */,
@@ -987,6 +1026,7 @@
C395D6DA21789BD800BEAD4D /* FLEXColorExplorerViewController.m in Sources */,
3A4C95001B5B21410088C3F2 /* FLEXArgumentInputSwitchView.m in Sources */,
3A4C94CC1B5B21410088C3F2 /* FLEXDictionaryExplorerViewController.m in Sources */,
C3F31D442267D883003C991A /* FLEXTableView.m in Sources */,
3A4C953F1B5B21410088C3F2 /* FLEXNetworkTransactionDetailTableViewController.m in Sources */,
224D49AB1C673AB5000EAB86 /* FLEXSQLiteDatabaseManager.m in Sources */,
779B1ED91C0C4D7C001F5E49 /* FLEXTableLeftCell.m in Sources */,
@@ -1053,6 +1093,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
@@ -1112,6 +1153,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"