Browse Source

Merge pull request #105 from TimOliver/timoliver-realm-integration

Added Realm Database File Introspection Alongside SQLite
Ryan Olson 10 years ago
parent
commit
26af4ef476

+ 3 - 3
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.h

@@ -13,10 +13,10 @@
 
 #import <Foundation/Foundation.h>
 
-@interface FLEXDatabaseManager : NSObject
+@protocol FLEXDatabaseManager <NSObject>
 
-
-- (instancetype)initWithPath:(NSString*)aPath;
+@required
+- (instancetype)initWithPath:(NSString*)path;
 
 - (BOOL)open;
 - (NSArray *)queryAllTables;

+ 14 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.h

@@ -0,0 +1,14 @@
+//
+//  FLEXRealmDatabaseManager.h
+//  FLEX
+//
+//  Created by Tim Oliver on 28/01/2016.
+//  Copyright © 2016 Realm. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "FLEXDatabaseManager.h"
+
+@interface FLEXRealmDatabaseManager : NSObject <FLEXDatabaseManager>
+
+@end

+ 113 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.m

@@ -0,0 +1,113 @@
+//
+//  FLEXRealmDatabaseManager.m
+//  FLEX
+//
+//  Created by Tim Oliver on 28/01/2016.
+//  Copyright © 2016 Realm. All rights reserved.
+//
+
+#import "FLEXRealmDatabaseManager.h"
+
+#if __has_include(<Realm/Realm.h>)
+#import <Realm/Realm.h>
+#import <Realm/RLMRealm_Dynamic.h>
+#else
+#import "FLEXRealmDefines.h"
+#endif
+
+@interface FLEXRealmDatabaseManager ()
+
+@property (nonatomic, copy) NSString *path;
+@property (nonatomic, strong) id realm;
+
+@end
+
+//#endif
+
+@implementation FLEXRealmDatabaseManager
+
+- (instancetype)initWithPath:(NSString*)aPath
+{
+    Class realmClass = NSClassFromString(@"RLMRealm");
+    if (realmClass == nil) {
+        return nil;
+    }
+    
+    self = [super init];
+    
+    if (self) {
+        _path = aPath;
+    }
+    return self;
+}
+
+- (BOOL)open
+{
+    Class realmClass = NSClassFromString(@"RLMRealm");
+    Class configurationClass = NSClassFromString(@"RLMRealmConfiguration");
+    
+    if (realmClass == nil || configurationClass == nil) {
+        return NO;
+    }
+    
+    NSError *error = nil;
+    id configuration = [[configurationClass alloc] init];
+    [configuration setPath:self.path];
+    self.realm = [realmClass realmWithConfiguration:configuration error:&error];
+    return (error == nil);
+}
+
+- (NSArray *)queryAllTables
+{
+    NSMutableArray *allTables = [NSMutableArray array];
+    RLMSchema *schema = [self.realm schema];
+    
+    for (RLMObjectSchema *objectSchema in schema.objectSchema) {
+        if (objectSchema.className == nil) {
+            continue;
+        }
+        
+        NSDictionary *dictionary = @{@"name":objectSchema.className};
+        [allTables addObject:dictionary];
+    }
+    
+    return allTables;
+}
+
+- (NSArray *)queryAllColumnsWithTableName:(NSString *)tableName
+{
+    RLMObjectSchema *objectSchema = [[self.realm schema] schemaForClassName:tableName];
+    if (objectSchema == nil) {
+        return nil;
+    }
+    
+    NSMutableArray *columnNames = [NSMutableArray array];
+    for (RLMProperty *property in objectSchema.properties) {
+        [columnNames addObject:property.name];
+    }
+    
+    return columnNames;
+}
+
+- (NSArray *)queryAllDataWithTableName:(NSString *)tableName
+{
+    RLMObjectSchema *objectSchema = [[self.realm schema] schemaForClassName:tableName];
+    RLMResults *results = [self.realm allObjects:tableName];
+    if (results.count == 0 || objectSchema == nil) {
+        return nil;
+    }
+    
+    NSMutableArray *allDataEntries = [NSMutableArray array];
+    for (RLMObject *result in results) {
+        NSMutableDictionary *entry = [NSMutableDictionary dictionary];
+        for (RLMProperty *property in objectSchema.properties) {
+            entry[property.name] = [result valueForKey:property.name];
+        }
+        
+        [allDataEntries addObject:entry];
+    }
+    
+    return allDataEntries;
+}
+
+@end

+ 46 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDefines.h

@@ -0,0 +1,46 @@
+//
+//  Realm.h
+//  FLEX
+//
+//  Created by Tim Oliver on 16/02/2016.
+//  Copyright © 2016 Realm. All rights reserved.
+//
+
+#if __has_include(<Realm/Realm.h>)
+#else
+
+@class RLMObject, RLMResults, RLMRealm, RLMRealmConfiguration, RLMSchema, RLMObjectSchema, RLMProperty;
+
+@interface RLMRealmConfiguration : NSObject
+@property (nonatomic, copy) NSString *path;
+@end
+
+@interface RLMRealm : NSObject
+@property (nonatomic, readonly) RLMSchema *schema;
++ (RLMRealm *)realmWithConfiguration:(RLMRealmConfiguration *)configuration error:(NSError **)error;
+- (RLMResults *)allObjects:(NSString *)className;
+@end
+
+@interface RLMSchema : NSObject
+@property (nonatomic, readonly) NSArray *objectSchema;
+- (RLMObjectSchema *)schemaForClassName:(NSString *)className;
+@end
+
+@interface RLMObjectSchema : NSObject
+@property (nonatomic, readonly) NSString *className;
+@property (nonatomic, readonly) NSArray *properties;
+@end
+
+@interface RLMProperty : NSString
+@property (nonatomic, readonly) NSString *name;
+@end
+
+@interface RLMResults : NSObject <NSFastEnumeration>
+@property (nonatomic, readonly) NSInteger count;
+@end
+
+@interface RLMObject : NSObject
+
+@end
+
+#endif

+ 19 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.h

@@ -0,0 +1,19 @@
+//
+//  PTDatabaseManager.h
+//  Derived from:
+//
+//  FMDatabase.h
+//  FMDB( https://github.com/ccgus/fmdb )
+//
+//  Created by Peng Tao on 15/11/23.
+//
+//  Licensed to Flying Meat Inc. under one or more contributor license agreements.
+//  See the LICENSE file distributed with this work for the terms under
+//  which Flying Meat Inc. licenses this file to you.
+
+#import <Foundation/Foundation.h>
+#import "FLEXDatabaseManager.h"
+
+@interface FLEXSQLiteDatabaseManager : NSObject <FLEXDatabaseManager>
+
+@end

+ 2 - 7
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.m

@@ -6,22 +6,18 @@
 //  Copyright © 2015年 Peng Tao. All rights reserved.
 //
 
-
-
-#import "FLEXDatabaseManager.h"
+#import "FLEXSQLiteDatabaseManager.h"
 #import <sqlite3.h>
 
 
 static NSString *const QUERY_TABLENAMES_SQL = @"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name";
 
-
-@implementation FLEXDatabaseManager
+@implementation FLEXSQLiteDatabaseManager
 {
     sqlite3* _db;
     NSString* _databasePath;
 }
 
-
 - (instancetype)initWithPath:(NSString*)aPath
 {
     self = [super init];
@@ -32,7 +28,6 @@ static NSString *const QUERY_TABLENAMES_SQL = @"SELECT name FROM sqlite_master W
     return self;
 }
 
-
 - (BOOL)open {
     if (_db) {
         return YES;

+ 1 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.h

@@ -10,6 +10,7 @@
 
 @interface FLEXTableListViewController : UITableViewController
 
++ (BOOL)supportsExtension:(NSString *)extension;
 - (instancetype)initWithPath:(NSString *)path;
 
 @end

+ 57 - 3
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.m

@@ -7,34 +7,57 @@
 //
 
 #import "FLEXTableListViewController.h"
+
 #import "FLEXDatabaseManager.h"
+#import "FLEXSQLiteDatabaseManager.h"
+#import "FLEXRealmDatabaseManager.h"
+
 #import "FLEXTableContentViewController.h"
 
 @interface FLEXTableListViewController ()
 {
-    FLEXDatabaseManager *_dbm;
+    id<FLEXDatabaseManager> _dbm;
     NSString *_databasePath;
 }
 
 @property (nonatomic, strong) NSArray *tables;
 
++ (NSArray *)supportedSQLiteExtensions;
++ (NSArray *)supportedRealmExtensions;
+
 @end
 
 @implementation FLEXTableListViewController
 
-
 - (instancetype)initWithPath:(NSString *)path
 {
     self = [super initWithStyle:UITableViewStyleGrouped];
     if (self) {
         _databasePath = [path copy];
-        _dbm = [[FLEXDatabaseManager alloc] initWithPath:path];
+        _dbm = [self databaseManagerForFileAtPath:_databasePath];
         [_dbm open];
         [self getAllTables];
     }
     return self;
 }
 
+- (id<FLEXDatabaseManager>)databaseManagerForFileAtPath:(NSString *)path
+{
+    NSString *pathExtension = path.pathExtension.lowercaseString;
+    
+    NSArray *sqliteExtensions = [FLEXTableListViewController supportedSQLiteExtensions];
+    if ([sqliteExtensions indexOfObject:pathExtension] != NSNotFound) {
+        return [[FLEXSQLiteDatabaseManager alloc] initWithPath:path];
+    }
+    
+    NSArray *realmExtensions = [FLEXTableListViewController supportedRealmExtensions];
+    if (realmExtensions != nil && [realmExtensions indexOfObject:pathExtension] != NSNotFound) {
+        return [[FLEXRealmDatabaseManager alloc] initWithPath:path];
+    }
+    
+    return nil;
+}
+
 - (void)getAllTables
 {
     NSArray *resultArray = [_dbm queryAllTables];
@@ -79,4 +102,35 @@
     return [NSString stringWithFormat:@"%lu tables", (unsigned long)self.tables.count];
 }
 
++ (BOOL)supportsExtension:(NSString *)extension
+{
+    extension = extension.lowercaseString;
+    
+    NSArray *sqliteExtensions = [FLEXTableListViewController supportedSQLiteExtensions];
+    if (sqliteExtensions.count > 0 && [sqliteExtensions indexOfObject:extension] != NSNotFound) {
+        return YES;
+    }
+    
+    NSArray *realmExtensions = [FLEXTableListViewController supportedRealmExtensions];
+    if (realmExtensions.count > 0 && [realmExtensions indexOfObject:extension] != NSNotFound) {
+        return YES;
+    }
+    
+    return NO;
+}
+
++ (NSArray *)supportedSQLiteExtensions
+{
+    return @[@"db", @"sqlite", @"sqlite3"];
+}
+
++ (NSArray *)supportedRealmExtensions
+{
+    if (NSClassFromString(@"RLMRealm") == nil) {
+        return nil;
+    }
+    
+    return @[@"realm"];
+}
+
 @end

+ 2 - 2
Classes/GlobalStateExplorers/FLEXFileBrowserTableViewController.m

@@ -217,8 +217,8 @@
                 drillInViewController = [[FLEXWebViewController alloc] initWithText:prettyString];
             } else if ([FLEXWebViewController supportsPathExtension:pathExtension]) {
                 drillInViewController = [[FLEXWebViewController alloc] initWithURL:[NSURL fileURLWithPath:fullPath]];
-            } else if ([[subpath pathExtension] isEqualToString:@"db"]) {
-              drillInViewController = [[FLEXTableListViewController alloc] initWithPath:fullPath];
+            } else if ([FLEXTableListViewController supportsExtension:subpath.pathExtension]) {
+                drillInViewController = [[FLEXTableListViewController alloc] initWithPath:fullPath];
             }
             else {
                 NSString *fileString = [NSString stringWithContentsOfFile:fullPath encoding:NSUTF8StringEncoding error:NULL];

+ 48 - 0
Example/UICatalog.xcodeproj/project.pbxproj

@@ -7,6 +7,9 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		22679D581C74188D002248FC /* Dog.m in Sources */ = {isa = PBXBuildFile; fileRef = 22679D571C74188D002248FC /* Dog.m */; };
+		22679D5C1C7418B6002248FC /* Owner.m in Sources */ = {isa = PBXBuildFile; fileRef = 22679D5B1C7418B6002248FC /* Owner.m */; };
+		22679D5D1C741A7A002248FC /* dogs.realm in Resources */ = {isa = PBXBuildFile; fileRef = 22679D551C741764002248FC /* dogs.realm */; };
 		3EC6487318FF8A5000024205 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = 3EC6487218FF8A5000024205 /* ReadMe.txt */; };
 		5356823E18F3656900BAAD62 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5356823D18F3656900BAAD62 /* Foundation.framework */; };
 		5356824018F3656900BAAD62 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5356823F18F3656900BAAD62 /* CoreGraphics.framework */; };
@@ -47,7 +50,25 @@
 		94CB4D431A97183E0054A905 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 94CB4D421A97183E0054A905 /* libz.dylib */; };
 /* End PBXBuildFile section */
 
+/* Begin PBXCopyFilesBuildPhase section */
+		22679D691C742141002248FC /* Embed Frameworks */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "";
+			dstSubfolderSpec = 10;
+			files = (
+			);
+			name = "Embed Frameworks";
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
 /* Begin PBXFileReference section */
+		22679D551C741764002248FC /* dogs.realm */ = {isa = PBXFileReference; lastKnownFileType = file; path = dogs.realm; sourceTree = "<group>"; };
+		22679D561C74188D002248FC /* Dog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dog.h; sourceTree = "<group>"; };
+		22679D571C74188D002248FC /* Dog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Dog.m; sourceTree = "<group>"; };
+		22679D5A1C7418B6002248FC /* Owner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Owner.h; sourceTree = "<group>"; };
+		22679D5B1C7418B6002248FC /* Owner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Owner.m; sourceTree = "<group>"; };
 		3EC6487218FF8A5000024205 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = SOURCE_ROOT; };
 		5356823A18F3656900BAAD62 /* UICatalog.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UICatalog.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		5356823D18F3656900BAAD62 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
@@ -134,6 +155,18 @@
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		22679D591C741891002248FC /* Realm */ = {
+			isa = PBXGroup;
+			children = (
+				22679D551C741764002248FC /* dogs.realm */,
+				22679D561C74188D002248FC /* Dog.h */,
+				22679D571C74188D002248FC /* Dog.m */,
+				22679D5A1C7418B6002248FC /* Owner.h */,
+				22679D5B1C7418B6002248FC /* Owner.m */,
+			);
+			name = Realm;
+			sourceTree = "<group>";
+		};
 		5356823118F3656900BAAD62 = {
 			isa = PBXGroup;
 			children = (
@@ -251,6 +284,7 @@
 		53874F9A18F36B6900510922 /* Application */ = {
 			isa = PBXGroup;
 			children = (
+				22679D591C741891002248FC /* Realm */,
 				5356824918F3656900BAAD62 /* main.m */,
 				5356827B18F3670300BAAD62 /* AAPLAppDelegate.h */,
 				5356827C18F3670300BAAD62 /* AAPLAppDelegate.m */,
@@ -281,6 +315,7 @@
 				5356823618F3656900BAAD62 /* Sources */,
 				5356823718F3656900BAAD62 /* Frameworks */,
 				5356823818F3656900BAAD62 /* Resources */,
+				22679D691C742141002248FC /* Embed Frameworks */,
 			);
 			buildRules = (
 			);
@@ -323,6 +358,7 @@
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				22679D5D1C741A7A002248FC /* dogs.realm in Resources */,
 				5356825418F3656900BAAD62 /* Main_iPad.storyboard in Resources */,
 				53874F9918F36B1800510922 /* Localizable.strings in Resources */,
 				5356825918F3656900BAAD62 /* Images.xcassets in Resources */,
@@ -338,6 +374,7 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				22679D5C1C7418B6002248FC /* Owner.m in Sources */,
 				535682AE18F3670300BAAD62 /* AAPLDatePickerController.m in Sources */,
 				535682AB18F3670300BAAD62 /* AAPLButtonViewController.m in Sources */,
 				535682B618F3670300BAAD62 /* AAPLSegmentedControlViewController.m in Sources */,
@@ -356,6 +393,7 @@
 				535682B918F3670300BAAD62 /* AAPLStepperViewController.m in Sources */,
 				535682AA18F3670300BAAD62 /* AAPLAppDelegate.m in Sources */,
 				535682B518F3670300BAAD62 /* AAPLProgressViewController.m in Sources */,
+				22679D581C74188D002248FC /* Dog.m in Sources */,
 				535682AD18F3670300BAAD62 /* AAPLCustomToolbarViewController.m in Sources */,
 				535682A818F3670300BAAD62 /* AAPLActivityIndicatorViewController.m in Sources */,
 				535682B818F3670300BAAD62 /* AAPLSplitViewControllerDelegate.m in Sources */,
@@ -477,9 +515,14 @@
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
 				EXCLUDED_SOURCE_FILE_NAMES = "";
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)",
+				);
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 				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_NAME = "$(TARGET_NAME)";
 				WRAPPER_EXTENSION = app;
@@ -492,9 +535,14 @@
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
 				EXCLUDED_SOURCE_FILE_NAMES = "FLEX*";
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)",
+				);
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 				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_NAME = "$(TARGET_NAME)";
 				WRAPPER_EXTENSION = app;

+ 28 - 0
Example/UICatalog/AAPLAppDelegate.m

@@ -49,6 +49,10 @@
 
 #if DEBUG
 #import <FLEX/FLEX.h>
+#if __has_include(<Realm/Realm.h>)
+#import "Dog.h"
+#import "Owner.h"
+#endif
 #endif
 
 @interface AAPLAppDelegate () <NSURLConnectionDataDelegate, NSURLSessionDataDelegate>
@@ -66,6 +70,11 @@
     [[FLEXManager sharedManager] setNetworkDebuggingEnabled:YES];
     [self sendExampleNetworkRequests];
     self.repeatingLogExampleTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(sendExampleLogMessage) userInfo:nil repeats:YES];
+
+#if __has_include(<Realm/Realm.h>)
+    [self setUpRealm];
+#endif
+    
 #endif
     return YES;
 }
@@ -173,4 +182,23 @@
     [self.connections removeObject:connection];
 }
 
+#if __has_include(<Realm/Realm.h>)
+- (void)setUpRealm
+{
+    NSString *destinationPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
+    destinationPath = [destinationPath stringByAppendingPathComponent:@"dogs.realm"];
+    if ([[NSFileManager defaultManager] fileExistsAtPath:destinationPath isDirectory:nil]) {
+        return;
+    }
+    
+    NSString *resourcePath = [[NSBundle mainBundle] pathForResource:@"dogs" ofType:@"realm"];
+    if (resourcePath == nil) {
+        return;
+    }
+    
+    NSError *error = nil;
+    [[NSFileManager defaultManager] copyItemAtPath:resourcePath toPath:destinationPath error:&error];
+}
+#endif
+
 @end

+ 22 - 0
Example/UICatalog/Dog.h

@@ -0,0 +1,22 @@
+//
+//  Dog.h
+//  UICatalog
+//
+//  Created by Tim Oliver on 17/02/2016.
+//  Copyright © 2016 Realm. All rights reserved.
+//
+
+#if __has_include(<Realm/Realm.h>)
+
+#import <Realm/Realm.h>
+#import "Owner.h"
+
+@interface Dog : RLMObject
+@property NSString *name;
+@property CGFloat height;
+@property NSDate *birthdate;
+@property BOOL vaccinated;
+@property Owner *owner;
+@end
+
+#endif

+ 16 - 0
Example/UICatalog/Dog.m

@@ -0,0 +1,16 @@
+//
+//  Dog.m
+//  UICatalog
+//
+//  Created by Tim Oliver on 17/02/2016.
+//  Copyright © 2016 Realm. All rights reserved.
+//
+
+#import "Dog.h"
+
+#if __has_include(<Realm/Realm.h>)
+
+@implementation Dog
+@end
+
+#endif

+ 17 - 0
Example/UICatalog/Owner.h

@@ -0,0 +1,17 @@
+//
+//  Owner.h
+//  UICatalog
+//
+//  Created by Tim Oliver on 17/02/2016.
+//  Copyright © 2016 Realm. All rights reserved.
+//
+
+#if __has_include(<Realm/Realm.h>)
+
+#import <Realm/Realm.h>
+
+@interface Owner : RLMObject
+@property NSString *name;
+@end
+
+#endif

+ 16 - 0
Example/UICatalog/Owner.m

@@ -0,0 +1,16 @@
+//
+//  Owner.m
+//  UICatalog
+//
+//  Created by Tim Oliver on 17/02/2016.
+//  Copyright © 2016 Realm. All rights reserved.
+//
+
+#import "Owner.h"
+
+#if __has_include(<Realm/Realm.h>)
+
+@implementation Owner
+@end
+
+#endif

BIN
Example/UICatalog/dogs.realm


+ 30 - 4
FLEX.xcodeproj/project.pbxproj

@@ -8,6 +8,11 @@
 
 /* Begin PBXBuildFile section */
 		04F1CA191C137CF1000A52B0 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 04F1CA181C137CF1000A52B0 /* LICENSE */; };
+		222C88221C7339DC007CA15F /* FLEXRealmDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 222C88211C7339DC007CA15F /* FLEXRealmDefines.h */; };
+		224D49A81C673AB5000EAB86 /* FLEXRealmDatabaseManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 224D49A41C673AB5000EAB86 /* FLEXRealmDatabaseManager.h */; };
+		224D49A91C673AB5000EAB86 /* FLEXRealmDatabaseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 224D49A51C673AB5000EAB86 /* FLEXRealmDatabaseManager.m */; };
+		224D49AA1C673AB5000EAB86 /* FLEXSQLiteDatabaseManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 224D49A61C673AB5000EAB86 /* FLEXSQLiteDatabaseManager.h */; };
+		224D49AB1C673AB5000EAB86 /* FLEXSQLiteDatabaseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 224D49A71C673AB5000EAB86 /* FLEXSQLiteDatabaseManager.m */; };
 		3A4C94251B5B20570088C3F2 /* FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A4C94241B5B20570088C3F2 /* FLEX.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		3A4C94C51B5B21410088C3F2 /* FLEXArrayExplorerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A4C943C1B5B21410088C3F2 /* FLEXArrayExplorerViewController.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		3A4C94C61B5B21410088C3F2 /* FLEXArrayExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A4C943D1B5B21410088C3F2 /* FLEXArrayExplorerViewController.m */; };
@@ -129,7 +134,6 @@
 		679F64861BD53B7B00A8C94C /* FLEXCookiesTableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 679F64841BD53B7B00A8C94C /* FLEXCookiesTableViewController.h */; };
 		679F64871BD53B7B00A8C94C /* FLEXCookiesTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 679F64851BD53B7B00A8C94C /* FLEXCookiesTableViewController.m */; };
 		779B1ECE1C0C4D7C001F5E49 /* FLEXDatabaseManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 779B1EC01C0C4D7C001F5E49 /* FLEXDatabaseManager.h */; };
-		779B1ECF1C0C4D7C001F5E49 /* FLEXDatabaseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1EC11C0C4D7C001F5E49 /* FLEXDatabaseManager.m */; };
 		779B1ED01C0C4D7C001F5E49 /* FLEXMultiColumnTableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 779B1EC21C0C4D7C001F5E49 /* FLEXMultiColumnTableView.h */; };
 		779B1ED11C0C4D7C001F5E49 /* FLEXMultiColumnTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1EC31C0C4D7C001F5E49 /* FLEXMultiColumnTableView.m */; };
 		779B1ED21C0C4D7C001F5E49 /* FLEXTableColumnHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 779B1EC41C0C4D7C001F5E49 /* FLEXTableColumnHeader.h */; };
@@ -162,6 +166,11 @@
 
 /* Begin PBXFileReference section */
 		04F1CA181C137CF1000A52B0 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
+		222C88211C7339DC007CA15F /* FLEXRealmDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRealmDefines.h; sourceTree = "<group>"; };
+		224D49A41C673AB5000EAB86 /* FLEXRealmDatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRealmDatabaseManager.h; sourceTree = "<group>"; };
+		224D49A51C673AB5000EAB86 /* FLEXRealmDatabaseManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXRealmDatabaseManager.m; sourceTree = "<group>"; };
+		224D49A61C673AB5000EAB86 /* FLEXSQLiteDatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSQLiteDatabaseManager.h; sourceTree = "<group>"; };
+		224D49A71C673AB5000EAB86 /* FLEXSQLiteDatabaseManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXSQLiteDatabaseManager.m; sourceTree = "<group>"; };
 		3A4C941F1B5B20570088C3F2 /* FLEX.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FLEX.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		3A4C94231B5B20570088C3F2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		3A4C94241B5B20570088C3F2 /* FLEX.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FLEX.h; sourceTree = "<group>"; };
@@ -286,7 +295,6 @@
 		679F64841BD53B7B00A8C94C /* FLEXCookiesTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXCookiesTableViewController.h; sourceTree = "<group>"; };
 		679F64851BD53B7B00A8C94C /* FLEXCookiesTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXCookiesTableViewController.m; sourceTree = "<group>"; };
 		779B1EC01C0C4D7C001F5E49 /* FLEXDatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXDatabaseManager.h; sourceTree = "<group>"; };
-		779B1EC11C0C4D7C001F5E49 /* FLEXDatabaseManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXDatabaseManager.m; sourceTree = "<group>"; };
 		779B1EC21C0C4D7C001F5E49 /* FLEXMultiColumnTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMultiColumnTableView.h; sourceTree = "<group>"; };
 		779B1EC31C0C4D7C001F5E49 /* FLEXMultiColumnTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMultiColumnTableView.m; sourceTree = "<group>"; };
 		779B1EC41C0C4D7C001F5E49 /* FLEXTableColumnHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableColumnHeader.h; sourceTree = "<group>"; };
@@ -589,8 +597,12 @@
 		779B1EBF1C0C4D7C001F5E49 /* DatabaseBrowser */ = {
 			isa = PBXGroup;
 			children = (
+				222C88211C7339DC007CA15F /* FLEXRealmDefines.h */,
 				779B1EC01C0C4D7C001F5E49 /* FLEXDatabaseManager.h */,
-				779B1EC11C0C4D7C001F5E49 /* FLEXDatabaseManager.m */,
+				224D49A41C673AB5000EAB86 /* FLEXRealmDatabaseManager.h */,
+				224D49A51C673AB5000EAB86 /* FLEXRealmDatabaseManager.m */,
+				224D49A61C673AB5000EAB86 /* FLEXSQLiteDatabaseManager.h */,
+				224D49A71C673AB5000EAB86 /* FLEXSQLiteDatabaseManager.m */,
 				779B1EC21C0C4D7C001F5E49 /* FLEXMultiColumnTableView.h */,
 				779B1EC31C0C4D7C001F5E49 /* FLEXMultiColumnTableView.m */,
 				779B1EC41C0C4D7C001F5E49 /* FLEXTableColumnHeader.h */,
@@ -641,6 +653,7 @@
 				3A4C95381B5B21410088C3F2 /* FLEXNetworkRecorder.h in Headers */,
 				3A4C94251B5B20570088C3F2 /* FLEX.h in Headers */,
 				3A4C95051B5B21410088C3F2 /* FLEXArgumentInputViewFactory.h in Headers */,
+				222C88221C7339DC007CA15F /* FLEXRealmDefines.h in Headers */,
 				3A4C951E1B5B21410088C3F2 /* FLEXClassesTableViewController.h in Headers */,
 				779B1ED21C0C4D7C001F5E49 /* FLEXTableColumnHeader.h in Headers */,
 				3A4C94FD1B5B21410088C3F2 /* FLEXArgumentInputStructView.h in Headers */,
@@ -672,6 +685,7 @@
 				3A4C95221B5B21410088C3F2 /* FLEXFileBrowserSearchOperation.h in Headers */,
 				3A4C94FF1B5B21410088C3F2 /* FLEXArgumentInputSwitchView.h in Headers */,
 				3A4C94E71B5B21410088C3F2 /* FLEXHierarchyTableViewCell.h in Headers */,
+				224D49AA1C673AB5000EAB86 /* FLEXSQLiteDatabaseManager.h in Headers */,
 				3A4C95031B5B21410088C3F2 /* FLEXArgumentInputView.h in Headers */,
 				94A5151D1C4CA1F10063292F /* FLEXExplorerViewController.h in Headers */,
 				3A4C94C51B5B21410088C3F2 /* FLEXArrayExplorerViewController.h in Headers */,
@@ -699,6 +713,7 @@
 				3A4C94E91B5B21410088C3F2 /* FLEXHierarchyTableViewController.h in Headers */,
 				3A4C94F31B5B21410088C3F2 /* FLEXArgumentInputFontView.h in Headers */,
 				3A4C95261B5B21410088C3F2 /* FLEXGlobalsTableViewController.h in Headers */,
+				224D49A81C673AB5000EAB86 /* FLEXRealmDatabaseManager.h in Headers */,
 				3A4C94CD1B5B21410088C3F2 /* FLEXGlobalsTableViewControllerEntry.h in Headers */,
 				3A4C94FB1B5B21410088C3F2 /* FLEXArgumentInputStringView.h in Headers */,
 				3A4C95421B5B21410088C3F2 /* FLEXNetworkObserver.h in Headers */,
@@ -783,6 +798,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				942DCD871BAE0CA300DB5DC2 /* FLEXKeyboardShortcutManager.m in Sources */,
+				224D49A91C673AB5000EAB86 /* FLEXRealmDatabaseManager.m in Sources */,
 				94A515201C4CA1F10063292F /* FLEXWindow.m in Sources */,
 				3A4C95121B5B21410088C3F2 /* FLEXPropertyEditorViewController.m in Sources */,
 				3A4C95391B5B21410088C3F2 /* FLEXNetworkRecorder.m in Sources */,
@@ -840,8 +856,8 @@
 				3A4C95001B5B21410088C3F2 /* FLEXArgumentInputSwitchView.m in Sources */,
 				3A4C94CC1B5B21410088C3F2 /* FLEXDictionaryExplorerViewController.m in Sources */,
 				3A4C953F1B5B21410088C3F2 /* FLEXNetworkTransactionDetailTableViewController.m in Sources */,
+				224D49AB1C673AB5000EAB86 /* FLEXSQLiteDatabaseManager.m in Sources */,
 				779B1ED91C0C4D7C001F5E49 /* FLEXTableLeftCell.m in Sources */,
-				779B1ECF1C0C4D7C001F5E49 /* FLEXDatabaseManager.m in Sources */,
 				3A4C94E61B5B21410088C3F2 /* FLEXUtility.m in Sources */,
 				3A4C95231B5B21410088C3F2 /* FLEXFileBrowserSearchOperation.m in Sources */,
 				3A4C950C1B5B21410088C3F2 /* FLEXFieldEditorViewController.m in Sources */,
@@ -902,6 +918,7 @@
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
 				MTL_ENABLE_DEBUG_INFO = YES;
 				ONLY_ACTIVE_ARCH = YES;
+				OTHER_LDFLAGS = "";
 				SDKROOT = iphoneos;
 				TARGETED_DEVICE_FAMILY = "1,2";
 				VERSIONING_SYSTEM = "apple-generic";
@@ -942,6 +959,7 @@
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
 				MTL_ENABLE_DEBUG_INFO = NO;
+				OTHER_LDFLAGS = "";
 				SDKROOT = iphoneos;
 				TARGETED_DEVICE_FAMILY = "1,2";
 				VALIDATE_PRODUCT = YES;
@@ -957,6 +975,10 @@
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_CURRENT_VERSION = 1;
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)",
+				);
 				INFOPLIST_FILE = Classes/Info.plist;
 				INSTALL_PATH = "@rpath";
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@@ -973,6 +995,10 @@
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_CURRENT_VERSION = 1;
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)",
+				);
 				INFOPLIST_FILE = Classes/Info.plist;
 				INSTALL_PATH = "@rpath";
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";