├── Lidenbrock.framework
├── Versions
│ ├── Current
│ └── A
│ │ ├── Headers
│ │ ├── Lidenbrock.h
│ │ ├── NSManagedObjectContext+Lidenbrock.h
│ │ ├── NSManagedObject+Lidenbrock.h
│ │ ├── LBObjectManager.h
│ │ └── JSONKit.h
│ │ ├── Lidenbrock
│ │ └── Resources
│ │ ├── Info.plist
│ │ ├── en.lproj
│ │ └── InfoPlist.strings
│ │ └── LICENSE
├── Headers
├── Lidenbrock
└── Resources
├── Lidenbrock
├── Classes
│ ├── Lidenbrock.h
│ ├── NSManagedObjectContext+Lidenbrock.h
│ ├── NSManagedObject+Lidenbrock.h
│ ├── NSManagedObjectContext+Lidenbrock.m
│ ├── LBObjectManager.h
│ ├── JSONKit.h
│ ├── NSManagedObject+Lidenbrock.m
│ └── LBObjectManager.m
├── .DS_Store
├── en.lproj
│ └── InfoPlist.strings
├── Lidenbrock-Prefix.pch
└── Lidenbrock-Info.plist
├── .gitignore
├── Lidenbrock.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── README.md
├── LICENSE
└── DOC.md
/Lidenbrock.framework/Versions/Current:
--------------------------------------------------------------------------------
1 | A
--------------------------------------------------------------------------------
/Lidenbrock.framework/Headers:
--------------------------------------------------------------------------------
1 | Versions/Current/Headers
--------------------------------------------------------------------------------
/Lidenbrock.framework/Lidenbrock:
--------------------------------------------------------------------------------
1 | Versions/Current/Lidenbrock
--------------------------------------------------------------------------------
/Lidenbrock.framework/Resources:
--------------------------------------------------------------------------------
1 | Versions/Current/Resources
--------------------------------------------------------------------------------
/Lidenbrock/Classes/Lidenbrock.h:
--------------------------------------------------------------------------------
1 | #import "NSManagedObject+Lidenbrock.h"
--------------------------------------------------------------------------------
/Lidenbrock.framework/Versions/A/Headers/Lidenbrock.h:
--------------------------------------------------------------------------------
1 | #import "NSManagedObject+Lidenbrock.h"
--------------------------------------------------------------------------------
/Lidenbrock/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feeef/lidenbrock/HEAD/Lidenbrock/.DS_Store
--------------------------------------------------------------------------------
/Lidenbrock/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | Lidenbrock.xcodeproj/project.xcworkspace/xcuserdata
3 | Lidenbrock.xcodeproj/xcuserdata
4 |
--------------------------------------------------------------------------------
/Lidenbrock.framework/Versions/A/Lidenbrock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feeef/lidenbrock/HEAD/Lidenbrock.framework/Versions/A/Lidenbrock
--------------------------------------------------------------------------------
/Lidenbrock.framework/Versions/A/Resources/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feeef/lidenbrock/HEAD/Lidenbrock.framework/Versions/A/Resources/Info.plist
--------------------------------------------------------------------------------
/Lidenbrock/Lidenbrock-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'Lidenbrock' target in the 'Lidenbrock' project
3 | //
4 |
5 | #ifdef __OBJC__
6 | #endif
7 |
--------------------------------------------------------------------------------
/Lidenbrock.framework/Versions/A/Resources/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feeef/lidenbrock/HEAD/Lidenbrock.framework/Versions/A/Resources/en.lproj/InfoPlist.strings
--------------------------------------------------------------------------------
/Lidenbrock.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Lidenbrock/Classes/NSManagedObjectContext+Lidenbrock.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSManagedObjectContext+Lidenbrock.h
3 | // Lidenbrock
4 | //
5 | // Created by feeef on 11/04/11.
6 | // Copyright 2011 Six Degrees. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 | #import "LBObjectManager.h"
13 |
14 | @interface NSManagedObjectContext (Lidenbrock)
15 |
16 | + (NSManagedObjectContext *) defaultContext;
17 |
18 | + (BOOL) saveDefaultContext;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/Lidenbrock.framework/Versions/A/Headers/NSManagedObjectContext+Lidenbrock.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSManagedObjectContext+Lidenbrock.h
3 | // Lidenbrock
4 | //
5 | // Created by feeef on 11/04/11.
6 | // Copyright 2011 Six Degrees. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 | #import "LBObjectManager.h"
13 |
14 | @interface NSManagedObjectContext (Lidenbrock)
15 |
16 | + (NSManagedObjectContext *) defaultContext;
17 |
18 | + (BOOL) saveDefaultContext;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Description
2 | ===========
3 |
4 | Lidenbrock is an add-on to Core Data. It is a solution to easily synchronize your Core Data models with some external JSON resources.
5 |
6 |
7 | This project was made as effort to build a link between CoreData and external data storage.
8 | However it lacks of a lot of key features (like an HTTP client). I realize how far this project is from some existing great libraries. Unfortunately, I have not enough time to work on it seriously and won't update it anymore.
9 |
10 | If you come to this page looking for a solution to build your connected applications, I suggest you try the great [RestKit library](http://restkit.org/).
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Lidenbrock/Lidenbrock-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | fr.oahu.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | FMWK
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | NSPrincipalClass
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2011 by Six Degrees
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
--------------------------------------------------------------------------------
/Lidenbrock.framework/Versions/A/Resources/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2011 by Six Degrees
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
--------------------------------------------------------------------------------
/Lidenbrock/Classes/NSManagedObject+Lidenbrock.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSManagedObject+Lidenbrock.h
3 | // Lidenbrock
4 | //
5 | // Created by feeef on 08/04/11.
6 | // Copyright 2011 Six Degrees. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | #import "NSManagedObjectContext+Lidenbrock.h"
13 | #import "LBObjectManager.h"
14 | #import "JSONKit.h"
15 |
16 |
17 | @interface NSManagedObject (Lidenbrock)
18 |
19 | + (void) setSyncIdAs : (NSString *) syncId;
20 |
21 | + (void) setDateFormat : (NSString *) format;
22 |
23 | + (void) setTimeZone : (NSTimeZone *) timeZone;
24 |
25 | + (void) setMapping : (NSDictionary *) mapping;
26 |
27 |
28 |
29 | + (id) newEntity;
30 |
31 | + (id) entityWithId : (NSString *) newId;
32 |
33 | + (id) entityFromJson : (NSString *) json;
34 |
35 |
36 |
37 | + (NSArray *) fetch : (NSString *) format, ...;
38 |
39 |
40 |
41 | + (NSArray *) entitiesFromJson : (NSString *) json;
42 |
43 | + (NSArray *) entitiesFromPlist : (NSArray *) array;
44 |
45 | - (void) loadFromJson : (NSString *) json;
46 |
47 | - (void) loadFromDictionary : (NSDictionary *) dictionary;
48 |
49 |
50 |
51 | - (NSDictionary *) toDictionary : (NSString *) parentName;
52 |
53 | - (NSString *) toJson;
54 |
55 |
56 | - (BOOL) save;
57 |
58 |
59 |
60 | - (NSString *) getClassNameForKey : (NSString *) key;
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/Lidenbrock.framework/Versions/A/Headers/NSManagedObject+Lidenbrock.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSManagedObject+Lidenbrock.h
3 | // Lidenbrock
4 | //
5 | // Created by feeef on 08/04/11.
6 | // Copyright 2011 Six Degrees. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | #import "NSManagedObjectContext+Lidenbrock.h"
13 | #import "LBObjectManager.h"
14 | #import "JSONKit.h"
15 |
16 |
17 | @interface NSManagedObject (Lidenbrock)
18 |
19 | + (void) setSyncIdAs : (NSString *) syncId;
20 |
21 | + (void) setDateFormat : (NSString *) format;
22 |
23 | + (void) setTimeZone : (NSTimeZone *) timeZone;
24 |
25 | + (void) setMapping : (NSDictionary *) mapping;
26 |
27 |
28 |
29 | + (id) newEntity;
30 |
31 | + (id) entityWithId : (NSString *) newId;
32 |
33 | + (id) entityFromJson : (NSString *) json;
34 |
35 |
36 |
37 | + (NSArray *) fetch : (NSString *) format, ...;
38 |
39 |
40 |
41 | + (NSArray *) entitiesFromJson : (NSString *) json;
42 |
43 | + (NSArray *) entitiesFromPlist : (NSArray *) array;
44 |
45 | - (void) loadFromJson : (NSString *) json;
46 |
47 | - (void) loadFromDictionary : (NSDictionary *) dictionary;
48 |
49 |
50 |
51 | - (NSDictionary *) toDictionary : (NSString *) parentName;
52 |
53 | - (NSString *) toJson;
54 |
55 |
56 | - (BOOL) save;
57 |
58 |
59 |
60 | - (NSString *) getClassNameForKey : (NSString *) key;
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/Lidenbrock/Classes/NSManagedObjectContext+Lidenbrock.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSManagedObjectContext+Lidenbrock.m
3 | // Lidenbrock
4 | //
5 | // Created by feeef on 11/04/11.
6 | // Copyright 2011 Six Degrees. All rights reserved.
7 | //
8 |
9 | #import "NSManagedObjectContext+Lidenbrock.h"
10 |
11 | @implementation NSManagedObjectContext (Lidenbrock)
12 |
13 | /***********************************************************************************************************
14 | */
15 | + (NSManagedObjectContext *) defaultContext
16 | {
17 | // Get context
18 | //
19 | NSError *error = NULL;
20 | NSManagedObjectContext *context = (NSManagedObjectContext*)[LBObjectManager getValueFromProperty: @"managedObjectContext"
21 | inObject: [[UIApplication sharedApplication] delegate]
22 | error: &error];
23 |
24 | return context;
25 | }
26 |
27 | /***********************************************************************************************************
28 | */
29 | + (BOOL) saveDefaultContext
30 | {
31 | // Save the objects in the data store
32 | //
33 | NSManagedObjectContext *context = [NSManagedObjectContext defaultContext];
34 |
35 | NSError *error = nil;
36 | if (![context save: &error]) {
37 | NSLog(@"Error saving data context: %@", [error localizedDescription]);
38 | return NO;
39 | }
40 | else {
41 | return YES;
42 | }
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/Lidenbrock/Classes/LBObjectManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // LBObjectManager.h
3 | // Lidenbrock
4 | //
5 | // Created by feeef on 02/02/11.
6 | // Copyright 2011 Six Degrees. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 | #import "JSONKit.h"
13 |
14 | @interface LBObjectManager : NSObject
15 | {
16 |
17 | }
18 |
19 | #pragma mark -
20 | #pragma mark Utils
21 |
22 | + (NSString *) evalPattern : (NSString *) pattern
23 | withObject : (id) object
24 | error : (NSError **) error;
25 |
26 | + (NSString *) getClassNameFromClass : (id) object;
27 |
28 |
29 | #pragma mark -
30 | #pragma mark Handle Properties
31 |
32 | + (void) setSyncIdAs : (NSString *) syncId
33 | forClassName : (NSString *) className;
34 |
35 | + (NSString *) syncIdForClassName : (NSString *) className;
36 |
37 | + (void) setDateFormat : (NSString *) format
38 | forClassName : (NSString *) className;
39 |
40 | + (NSString *) dateFormatForClassName : (NSString *) className;
41 |
42 |
43 | + (void) setTimeZone : (NSTimeZone *) timeZone
44 | forClassName : (NSString *) className;
45 |
46 | + (NSTimeZone *) timeZoneForClassName : (NSString *) className;
47 |
48 |
49 | + (void) setMapping : (NSDictionary *) mapping
50 | forClassName : (NSString *) className;
51 |
52 | + (NSDictionary *) mappingForClassName : (NSString *) className;
53 |
54 | + (NSDictionary *) inverseMappingForClassName : (NSString *) className;
55 |
56 |
57 |
58 | + (NSString *) getValueFromProperty : (NSString *) propertyName
59 | inObject : (id) object
60 | error : (NSError **) error;
61 |
62 | + (NSString *) getClassNameFromProperty : (NSString *) propertyName
63 | inObject : (id) object;
64 |
65 | + (BOOL) object : (id) object
66 | hasProperty : (NSString *) propertyName;
67 |
68 | + (NSDictionary *) propertiesFromObject : (id) object;
69 |
70 |
71 |
72 | #pragma mark -
73 | #pragma mark Data Type
74 |
75 | + (BOOL) isDictionary : (id) object;
76 |
77 | + (BOOL) isArray : (id) object;
78 |
79 | + (BOOL) isSet : (id) object;
80 |
81 | + (BOOL) isString : (id) object;
82 |
83 | + (BOOL) isDate : (id) object;
84 |
85 | + (BOOL) isNumber : (id) object;
86 |
87 | + (BOOL) isModel : (id) object;
88 |
89 |
90 |
91 | #pragma mark -
92 | #pragma mark Handle Serialization
93 |
94 | + (NSData *) dataFromObject : (id) object;
95 |
96 | + (NSString *) jsonFromObject : (id) object;
97 |
98 | + (NSString *) plistFromString : (NSString *) string;
99 |
100 | + (NSNumber *) plistFromNumber : (NSNumber *) number;
101 |
102 | + (NSDate *) plistFromDate : (NSDate *) date;
103 |
104 | + (NSString *) stringFromDate : (NSDate *) date
105 | withFormat : (NSString *) format
106 | andTimeZone : (NSTimeZone *) timeZone;
107 |
108 | + (NSDictionary *) plistFromDictionary : (NSDictionary *) dictionary
109 | withEntityName : (NSString *) entityName;
110 |
111 | + (NSArray *) plistFromArray : (NSArray *) array
112 | withParentName : (NSString *) parentName;
113 |
114 | + (NSDictionary *) plistFromModel : (id) model;
115 |
116 | + (NSDictionary *) plistFromModel : (id) model
117 | withParentName : (NSString *) parentName;
118 |
119 |
120 |
121 | #pragma mark -
122 | #pragma mark Handle Deserialization
123 |
124 | + (NSArray *) objectsWithClassName : (NSString *) className
125 | fromJson : (NSString *) json;
126 |
127 | + (NSArray *) objectsWithClassName : (NSString *) className
128 | fromArray : (NSArray *) array;
129 |
130 | + (id) objectWithClassName : (NSString *) className
131 | fromDictionary : (NSDictionary *) dictionary;
132 |
133 |
134 |
135 |
136 | @end
137 |
--------------------------------------------------------------------------------
/Lidenbrock.framework/Versions/A/Headers/LBObjectManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // LBObjectManager.h
3 | // Lidenbrock
4 | //
5 | // Created by feeef on 02/02/11.
6 | // Copyright 2011 Six Degrees. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 | #import "JSONKit.h"
13 |
14 | @interface LBObjectManager : NSObject
15 | {
16 |
17 | }
18 |
19 | #pragma mark -
20 | #pragma mark Utils
21 |
22 | + (NSString *) evalPattern : (NSString *) pattern
23 | withObject : (id) object
24 | error : (NSError **) error;
25 |
26 | + (NSString *) getClassNameFromClass : (id) object;
27 |
28 |
29 | #pragma mark -
30 | #pragma mark Handle Properties
31 |
32 | + (void) setSyncIdAs : (NSString *) syncId
33 | forClassName : (NSString *) className;
34 |
35 | + (NSString *) syncIdForClassName : (NSString *) className;
36 |
37 | + (void) setDateFormat : (NSString *) format
38 | forClassName : (NSString *) className;
39 |
40 | + (NSString *) dateFormatForClassName : (NSString *) className;
41 |
42 |
43 | + (void) setTimeZone : (NSTimeZone *) timeZone
44 | forClassName : (NSString *) className;
45 |
46 | + (NSTimeZone *) timeZoneForClassName : (NSString *) className;
47 |
48 |
49 | + (void) setMapping : (NSDictionary *) mapping
50 | forClassName : (NSString *) className;
51 |
52 | + (NSDictionary *) mappingForClassName : (NSString *) className;
53 |
54 | + (NSDictionary *) inverseMappingForClassName : (NSString *) className;
55 |
56 |
57 |
58 | + (NSString *) getValueFromProperty : (NSString *) propertyName
59 | inObject : (id) object
60 | error : (NSError **) error;
61 |
62 | + (NSString *) getClassNameFromProperty : (NSString *) propertyName
63 | inObject : (id) object;
64 |
65 | + (BOOL) object : (id) object
66 | hasProperty : (NSString *) propertyName;
67 |
68 | + (NSDictionary *) propertiesFromObject : (id) object;
69 |
70 |
71 |
72 | #pragma mark -
73 | #pragma mark Data Type
74 |
75 | + (BOOL) isDictionary : (id) object;
76 |
77 | + (BOOL) isArray : (id) object;
78 |
79 | + (BOOL) isSet : (id) object;
80 |
81 | + (BOOL) isString : (id) object;
82 |
83 | + (BOOL) isDate : (id) object;
84 |
85 | + (BOOL) isNumber : (id) object;
86 |
87 | + (BOOL) isModel : (id) object;
88 |
89 |
90 |
91 | #pragma mark -
92 | #pragma mark Handle Serialization
93 |
94 | + (NSData *) dataFromObject : (id) object;
95 |
96 | + (NSString *) jsonFromObject : (id) object;
97 |
98 | + (NSString *) plistFromString : (NSString *) string;
99 |
100 | + (NSNumber *) plistFromNumber : (NSNumber *) number;
101 |
102 | + (NSDate *) plistFromDate : (NSDate *) date;
103 |
104 | + (NSString *) stringFromDate : (NSDate *) date
105 | withFormat : (NSString *) format
106 | andTimeZone : (NSTimeZone *) timeZone;
107 |
108 | + (NSDictionary *) plistFromDictionary : (NSDictionary *) dictionary
109 | withEntityName : (NSString *) entityName;
110 |
111 | + (NSArray *) plistFromArray : (NSArray *) array
112 | withParentName : (NSString *) parentName;
113 |
114 | + (NSDictionary *) plistFromModel : (id) model;
115 |
116 | + (NSDictionary *) plistFromModel : (id) model
117 | withParentName : (NSString *) parentName;
118 |
119 |
120 |
121 | #pragma mark -
122 | #pragma mark Handle Deserialization
123 |
124 | + (NSArray *) objectsWithClassName : (NSString *) className
125 | fromJson : (NSString *) json;
126 |
127 | + (NSArray *) objectsWithClassName : (NSString *) className
128 | fromArray : (NSArray *) array;
129 |
130 | + (id) objectWithClassName : (NSString *) className
131 | fromDictionary : (NSDictionary *) dictionary;
132 |
133 |
134 |
135 |
136 | @end
137 |
--------------------------------------------------------------------------------
/DOC.md:
--------------------------------------------------------------------------------
1 | Description
2 | ===========
3 |
4 | Lidenbrock is an add-on to Core Data. It is a solution to easily synchronize your Core Data models with some external JSON resources.
5 |
6 |
7 | Features
8 | ==============
9 |
10 | * Load new models and synchronize existing ones from a JSON string
11 | * Fetch your data with a single line of code
12 | * Sort your result directly from the predicate format (the SQL way)
13 |
14 |
15 | Installation
16 | =======
17 |
18 | 1. git clone git@github.com:sixdegrees/lidenbrock.git
19 | 2. Import Lidenbrock.framework to your XCode project
20 | 3. Add -ObjC and -all_load to Other Link Flags in your project
21 | 4. You can now import the framework within your code :
22 |
23 | #### Code
24 | #import
25 |
26 |
27 | Using Lidenbrock
28 | ========
29 |
30 | Lidenbrock only uses one Managed Object Context defined (by default when you create a Core Data project) as YourAppDelegate.managedObjectContext, so make sure this is your Context.
31 |
32 | Let's assume the following DB Model (as your .xcdatamodel). All Models are generated as NSManagedObject classes in your source code :
33 |
34 | Recipe
35 | ----------------
36 | name (NSString)
37 | details (NSString)
38 | ------------
39 | ingredients (NSSet)
40 |
41 |
42 | Igredient
43 | ----------------
44 | name (NSString)
45 | ------------
46 | recipes (NSSet)
47 |
48 |
49 | The following jsonObject variable :
50 |
51 | {
52 | "id" : "REC1",
53 | "name" : "pancake",
54 | "details" : "In a large bowl, sift together the flour, egg, milk...",
55 | "createdOn" : "2011-08-26"
56 | "ingredients" : [
57 | {
58 | "id" : "INGR1",
59 | "name" : "flour"
60 | },
61 | {
62 | "id" : "INGR2",
63 | "name" : "egg"
64 | },
65 | {
66 | "id" : "INGR3",
67 | "name" : "milk"
68 | }
69 | ]
70 | }
71 |
72 | And the following jsonArray variable :
73 |
74 | [
75 | {"name" : "flour"},
76 | {"name" : "egg"},
77 | {"name" : "milk"}
78 | ]
79 |
80 |
81 |
82 | ### Load from JSON
83 |
84 | In order to load a model from a JSON string, you can use the class method entityFromJson on any of your NSManagedObject class.
85 |
86 | Recipe *recipe = [Recipe entityFromJson: jsonObject];
87 |
88 | You may also use the instance method :
89 |
90 | Recipe *recipe = [Recipe newEntity];
91 | [recipe loadFromJson: jsonObject];
92 |
93 | Loading is recursive so you can now access your ingredients through the ingredients attribute :
94 |
95 | NSArray *ingredients = [recipe.ingredients allObjects];
96 |
97 |
98 | You can also load an array of objects :
99 |
100 | NSArray *ingredients = [Ingredient entitiesFromJson: jsonArray];
101 |
102 |
103 | ### Sync from JSON
104 |
105 | The previous exemple creates a new entity for every single load.
106 |
107 | If you want to retrieve and synchronise existing data, you need to add an attribute called syncID (NSString) to your model.
108 | Lidenbrock will then look at any id, _id or syncID attribute in your JSON data and try to retreive an existing entity based on its value.
109 | You can also specify a custom attribute, in your json data, to be your syncID :
110 |
111 | [Recipe setSyncIdAs: @"myCustomAttribute"];
112 |
113 | If no match can be made, a new entity is created.
114 |
115 | The new model is as follow :
116 |
117 | Recipe
118 | ----------------
119 | syncID (NSString)
120 | name (NSString)
121 | details (NSString)
122 | createdOn (NSDate)
123 | ------------
124 | ingredients (NSSet)
125 |
126 |
127 | Igredient
128 | ----------------
129 | syncID (NSString)
130 | name (NSString)
131 | ------------
132 | recipes (NSSet)
133 |
134 |
135 | entityFromJson will now sync existing data
136 |
137 | Recipe *recipe = [Recipe entityFromJson: jsonObject];
138 |
139 |
140 | ### Mapping
141 |
142 | If some of your JSON fields names don't match your models names, you can apply a specific mapping to you CoreData entity.
143 |
144 | NSDictionary *mapping = [NSDictionary dictionaryWithObjectsAndKeys:
145 | @"model_name", @"json_name",
146 | @"model_details", @"json_details", nil];
147 |
148 | [Recipe setMapping: mapping];
149 |
150 | The keys of your mapping dictionnary represent the JSON fields and the values represent the CoreData model fields.
151 |
152 |
153 |
154 | ### Working with dates
155 |
156 | If a Core Data entity defines one or more attributes as NSDate, you will have to specify the format used to load the NSDate object from the JSON string. If none is specified, the following is used by default : 'yyyy-MM-dd HH:mm:ss'
157 |
158 | [Recipe setDateFormat: @"yyyy-MM-dd"];
159 |
160 |
161 | You can also specify a time zone to be used on each date on your object. If none is specified, no time zone is set to the date formatter.
162 |
163 | NSTimeZone *timeZone = [NSTimeZone timeZoneWithAbbreviation: @"UTC"];
164 | [Recipe setTimeZone: timeZone];
165 |
166 |
167 |
168 | ### Serialize to JSON
169 |
170 | You can serialize your Core Data models into JSON by calling the method toJson on your instance.
171 |
172 | NSString *jsonString = [recipe toJson];
173 |
174 |
175 |
176 | ### Save
177 |
178 | You may save your data by calling the save method on your NSManagedObject instance. This is in fact a shortcut that performs a save on the context, saving any other unsaved data.
179 |
180 | [recipe save];
181 |
182 | You can also perform a save directly on the context.
183 |
184 | [[NSManagedObjectContext defaultContext] saveDefaultContext];
185 |
186 |
187 |
188 | ### Fetch
189 |
190 | You can fetch an entity directly from its id (matching syncID).
191 | If no match can be found, a new entity is created and returned with the new id set as syncID.
192 |
193 | Recipe *recipe = [Recipe entityWithId: @"REC1"];
194 |
195 |
196 |
197 | You can also easily fetch entities from a predicate format.
198 |
199 | NSString *ingredientName = @"egg";
200 | NSArray *recipes = [Recipe fetch: @"ANY ingredients.name == %@", ingredientName];
201 |
202 |
203 |
204 | ### Fetch & sort
205 |
206 | You can sort your fetched data by adding a "ORDER BY" statement at the end of your predicate format.
207 |
208 | NSArray *recipes = [Recipe fetch: @"ANY ingredients.name == %@ ORDER BY name DESC", ingredientName];
209 |
210 | IMPORTANT NOTE : You should not use any "%@" variables in your "ORDER BY" statement as the fetch method extracts this statment out of the rest of the format and only apply variables to the real predicate format, as defined by Apple.
211 |
212 |
213 | What's coming next ?
214 | ==============
215 |
216 | Lidenbrock is at an early stage of development so a lot of important features are still missing. They should be available in future releases.
217 |
218 | * Ability to use more than one Context
219 | * Add a "Limit" statmament to the fetch method
220 | * Delete data
221 | * Load from URL
222 | * Send to URL
223 |
224 | Stay tuned!
225 |
226 |
227 |
--------------------------------------------------------------------------------
/Lidenbrock/Classes/JSONKit.h:
--------------------------------------------------------------------------------
1 | //
2 | // JSONKit.h
3 | // http://github.com/johnezang/JSONKit
4 | // Licensed under the terms of the BSD License, as specified below.
5 | //
6 |
7 | /*
8 | Copyright (c) 2011, John Engelhart
9 |
10 | All rights reserved.
11 |
12 | Redistribution and use in source and binary forms, with or without
13 | modification, are permitted provided that the following conditions are met:
14 |
15 | * Redistributions of source code must retain the above copyright
16 | notice, this list of conditions and the following disclaimer.
17 |
18 | * Redistributions in binary form must reproduce the above copyright
19 | notice, this list of conditions and the following disclaimer in the
20 | documentation and/or other materials provided with the distribution.
21 |
22 | * Neither the name of the Zang Industries nor the names of its
23 | contributors may be used to endorse or promote products derived from
24 | this software without specific prior written permission.
25 |
26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
32 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 | */
38 |
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 |
45 | #ifdef __OBJC__
46 | #import
47 | #import
48 | #import
49 | #import
50 | #import
51 | #import
52 | #endif // __OBJC__
53 |
54 | #ifdef __cplusplus
55 | extern "C" {
56 | #endif
57 |
58 |
59 | // For Mac OS X < 10.5.
60 | #ifndef NSINTEGER_DEFINED
61 | #define NSINTEGER_DEFINED
62 | #if defined(__LP64__) || defined(NS_BUILD_32_LIKE_64)
63 | typedef long NSInteger;
64 | typedef unsigned long NSUInteger;
65 | #define NSIntegerMin LONG_MIN
66 | #define NSIntegerMax LONG_MAX
67 | #define NSUIntegerMax ULONG_MAX
68 | #else // defined(__LP64__) || defined(NS_BUILD_32_LIKE_64)
69 | typedef int NSInteger;
70 | typedef unsigned int NSUInteger;
71 | #define NSIntegerMin INT_MIN
72 | #define NSIntegerMax INT_MAX
73 | #define NSUIntegerMax UINT_MAX
74 | #endif // defined(__LP64__) || defined(NS_BUILD_32_LIKE_64)
75 | #endif // NSINTEGER_DEFINED
76 |
77 |
78 | #ifndef _JSONKIT_H_
79 | #define _JSONKIT_H_
80 |
81 | #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__APPLE_CC__) && (__APPLE_CC__ >= 5465)
82 | #define JK_DEPRECATED_ATTRIBUTE __attribute__((deprecated))
83 | #else
84 | #define JK_DEPRECATED_ATTRIBUTE
85 | #endif
86 |
87 | #define JSONKIT_VERSION_MAJOR 1
88 | #define JSONKIT_VERSION_MINOR 4
89 |
90 | typedef NSUInteger JKFlags;
91 |
92 | /*
93 | JKParseOptionComments : Allow C style // and /_* ... *_/ (without a _, obviously) comments in JSON.
94 | JKParseOptionUnicodeNewlines : Allow Unicode recommended (?:\r\n|[\n\v\f\r\x85\p{Zl}\p{Zp}]) newlines.
95 | JKParseOptionLooseUnicode : Normally the decoder will stop with an error at any malformed Unicode.
96 | This option allows JSON with malformed Unicode to be parsed without reporting an error.
97 | Any malformed Unicode is replaced with \uFFFD, or "REPLACEMENT CHARACTER".
98 | */
99 |
100 | enum {
101 | JKParseOptionNone = 0,
102 | JKParseOptionStrict = 0,
103 | JKParseOptionComments = (1 << 0),
104 | JKParseOptionUnicodeNewlines = (1 << 1),
105 | JKParseOptionLooseUnicode = (1 << 2),
106 | JKParseOptionPermitTextAfterValidJSON = (1 << 3),
107 | JKParseOptionValidFlags = (JKParseOptionComments | JKParseOptionUnicodeNewlines | JKParseOptionLooseUnicode | JKParseOptionPermitTextAfterValidJSON),
108 | };
109 | typedef JKFlags JKParseOptionFlags;
110 |
111 | enum {
112 | JKSerializeOptionNone = 0,
113 | JKSerializeOptionPretty = (1 << 0),
114 | JKSerializeOptionEscapeUnicode = (1 << 1),
115 | JKSerializeOptionValidFlags = (JKSerializeOptionPretty | JKSerializeOptionEscapeUnicode),
116 | };
117 | typedef JKFlags JKSerializeOptionFlags;
118 |
119 | #ifdef __OBJC__
120 |
121 | typedef struct JKParseState JKParseState; // Opaque internal, private type.
122 |
123 | // As a general rule of thumb, if you use a method that doesn't accept a JKParseOptionFlags argument, it defaults to JKParseOptionStrict
124 |
125 | @interface JSONDecoder : NSObject {
126 | JKParseState *parseState;
127 | }
128 | + (id)decoder;
129 | + (id)decoderWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
130 | - (id)initWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
131 | - (void)clearCache;
132 |
133 | // The parse... methods were deprecated in v1.4 in favor of the v1.4 objectWith... methods.
134 | - (id)parseUTF8String:(const unsigned char *)string length:(size_t)length JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithUTF8String:length: instead.
135 | - (id)parseUTF8String:(const unsigned char *)string length:(size_t)length error:(NSError **)error JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithUTF8String:length:error: instead.
136 | // The NSData MUST be UTF8 encoded JSON.
137 | - (id)parseJSONData:(NSData *)jsonData JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithData: instead.
138 | - (id)parseJSONData:(NSData *)jsonData error:(NSError **)error JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithData:error: instead.
139 |
140 | // Methods that return immutable collection objects.
141 | - (id)objectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length;
142 | - (id)objectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length error:(NSError **)error;
143 | // The NSData MUST be UTF8 encoded JSON.
144 | - (id)objectWithData:(NSData *)jsonData;
145 | - (id)objectWithData:(NSData *)jsonData error:(NSError **)error;
146 |
147 | // Methods that return mutable collection objects.
148 | - (id)mutableObjectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length;
149 | - (id)mutableObjectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length error:(NSError **)error;
150 | // The NSData MUST be UTF8 encoded JSON.
151 | - (id)mutableObjectWithData:(NSData *)jsonData;
152 | - (id)mutableObjectWithData:(NSData *)jsonData error:(NSError **)error;
153 |
154 | @end
155 |
156 | ////////////
157 | #pragma mark Deserializing methods
158 | ////////////
159 |
160 | @interface NSString (JSONKitDeserializing)
161 | - (id)objectFromJSONString;
162 | - (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
163 | - (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
164 | - (id)mutableObjectFromJSONString;
165 | - (id)mutableObjectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
166 | - (id)mutableObjectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
167 | @end
168 |
169 | @interface NSData (JSONKitDeserializing)
170 | // The NSData MUST be UTF8 encoded JSON.
171 | - (id)objectFromJSONData;
172 | - (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
173 | - (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
174 | - (id)mutableObjectFromJSONData;
175 | - (id)mutableObjectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
176 | - (id)mutableObjectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
177 | @end
178 |
179 | ////////////
180 | #pragma mark Serializing methods
181 | ////////////
182 |
183 | @interface NSString (JSONKitSerializing)
184 | // Convenience methods for those that need to serialize the receiving NSString (i.e., instead of having to serialize a NSArray with a single NSString, you can "serialize to JSON" just the NSString).
185 | // Normally, a string that is serialized to JSON has quotation marks surrounding it, which you may or may not want when serializing a single string, and can be controlled with includeQuotes:
186 | // includeQuotes:YES `a "test"...` -> `"a \"test\"..."`
187 | // includeQuotes:NO `a "test"...` -> `a \"test\"...`
188 | - (NSData *)JSONData; // Invokes JSONDataWithOptions:JKSerializeOptionNone includeQuotes:YES
189 | - (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions includeQuotes:(BOOL)includeQuotes error:(NSError **)error;
190 | - (NSString *)JSONString; // Invokes JSONStringWithOptions:JKSerializeOptionNone includeQuotes:YES
191 | - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions includeQuotes:(BOOL)includeQuotes error:(NSError **)error;
192 | @end
193 |
194 | @interface NSArray (JSONKitSerializing)
195 | - (NSData *)JSONData;
196 | - (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
197 | - (NSString *)JSONString;
198 | - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
199 | @end
200 |
201 | @interface NSDictionary (JSONKitSerializing)
202 | - (NSData *)JSONData;
203 | - (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
204 | - (NSString *)JSONString;
205 | - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
206 | @end
207 |
208 | #endif // __OBJC__
209 |
210 | #endif // _JSONKIT_H_
211 |
212 | #ifdef __cplusplus
213 | } // extern "C"
214 | #endif
215 |
--------------------------------------------------------------------------------
/Lidenbrock.framework/Versions/A/Headers/JSONKit.h:
--------------------------------------------------------------------------------
1 | //
2 | // JSONKit.h
3 | // http://github.com/johnezang/JSONKit
4 | // Licensed under the terms of the BSD License, as specified below.
5 | //
6 |
7 | /*
8 | Copyright (c) 2011, John Engelhart
9 |
10 | All rights reserved.
11 |
12 | Redistribution and use in source and binary forms, with or without
13 | modification, are permitted provided that the following conditions are met:
14 |
15 | * Redistributions of source code must retain the above copyright
16 | notice, this list of conditions and the following disclaimer.
17 |
18 | * Redistributions in binary form must reproduce the above copyright
19 | notice, this list of conditions and the following disclaimer in the
20 | documentation and/or other materials provided with the distribution.
21 |
22 | * Neither the name of the Zang Industries nor the names of its
23 | contributors may be used to endorse or promote products derived from
24 | this software without specific prior written permission.
25 |
26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
32 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 | */
38 |
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 |
45 | #ifdef __OBJC__
46 | #import
47 | #import
48 | #import
49 | #import
50 | #import
51 | #import
52 | #endif // __OBJC__
53 |
54 | #ifdef __cplusplus
55 | extern "C" {
56 | #endif
57 |
58 |
59 | // For Mac OS X < 10.5.
60 | #ifndef NSINTEGER_DEFINED
61 | #define NSINTEGER_DEFINED
62 | #if defined(__LP64__) || defined(NS_BUILD_32_LIKE_64)
63 | typedef long NSInteger;
64 | typedef unsigned long NSUInteger;
65 | #define NSIntegerMin LONG_MIN
66 | #define NSIntegerMax LONG_MAX
67 | #define NSUIntegerMax ULONG_MAX
68 | #else // defined(__LP64__) || defined(NS_BUILD_32_LIKE_64)
69 | typedef int NSInteger;
70 | typedef unsigned int NSUInteger;
71 | #define NSIntegerMin INT_MIN
72 | #define NSIntegerMax INT_MAX
73 | #define NSUIntegerMax UINT_MAX
74 | #endif // defined(__LP64__) || defined(NS_BUILD_32_LIKE_64)
75 | #endif // NSINTEGER_DEFINED
76 |
77 |
78 | #ifndef _JSONKIT_H_
79 | #define _JSONKIT_H_
80 |
81 | #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__APPLE_CC__) && (__APPLE_CC__ >= 5465)
82 | #define JK_DEPRECATED_ATTRIBUTE __attribute__((deprecated))
83 | #else
84 | #define JK_DEPRECATED_ATTRIBUTE
85 | #endif
86 |
87 | #define JSONKIT_VERSION_MAJOR 1
88 | #define JSONKIT_VERSION_MINOR 4
89 |
90 | typedef NSUInteger JKFlags;
91 |
92 | /*
93 | JKParseOptionComments : Allow C style // and /_* ... *_/ (without a _, obviously) comments in JSON.
94 | JKParseOptionUnicodeNewlines : Allow Unicode recommended (?:\r\n|[\n\v\f\r\x85\p{Zl}\p{Zp}]) newlines.
95 | JKParseOptionLooseUnicode : Normally the decoder will stop with an error at any malformed Unicode.
96 | This option allows JSON with malformed Unicode to be parsed without reporting an error.
97 | Any malformed Unicode is replaced with \uFFFD, or "REPLACEMENT CHARACTER".
98 | */
99 |
100 | enum {
101 | JKParseOptionNone = 0,
102 | JKParseOptionStrict = 0,
103 | JKParseOptionComments = (1 << 0),
104 | JKParseOptionUnicodeNewlines = (1 << 1),
105 | JKParseOptionLooseUnicode = (1 << 2),
106 | JKParseOptionPermitTextAfterValidJSON = (1 << 3),
107 | JKParseOptionValidFlags = (JKParseOptionComments | JKParseOptionUnicodeNewlines | JKParseOptionLooseUnicode | JKParseOptionPermitTextAfterValidJSON),
108 | };
109 | typedef JKFlags JKParseOptionFlags;
110 |
111 | enum {
112 | JKSerializeOptionNone = 0,
113 | JKSerializeOptionPretty = (1 << 0),
114 | JKSerializeOptionEscapeUnicode = (1 << 1),
115 | JKSerializeOptionValidFlags = (JKSerializeOptionPretty | JKSerializeOptionEscapeUnicode),
116 | };
117 | typedef JKFlags JKSerializeOptionFlags;
118 |
119 | #ifdef __OBJC__
120 |
121 | typedef struct JKParseState JKParseState; // Opaque internal, private type.
122 |
123 | // As a general rule of thumb, if you use a method that doesn't accept a JKParseOptionFlags argument, it defaults to JKParseOptionStrict
124 |
125 | @interface JSONDecoder : NSObject {
126 | JKParseState *parseState;
127 | }
128 | + (id)decoder;
129 | + (id)decoderWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
130 | - (id)initWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
131 | - (void)clearCache;
132 |
133 | // The parse... methods were deprecated in v1.4 in favor of the v1.4 objectWith... methods.
134 | - (id)parseUTF8String:(const unsigned char *)string length:(size_t)length JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithUTF8String:length: instead.
135 | - (id)parseUTF8String:(const unsigned char *)string length:(size_t)length error:(NSError **)error JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithUTF8String:length:error: instead.
136 | // The NSData MUST be UTF8 encoded JSON.
137 | - (id)parseJSONData:(NSData *)jsonData JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithData: instead.
138 | - (id)parseJSONData:(NSData *)jsonData error:(NSError **)error JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithData:error: instead.
139 |
140 | // Methods that return immutable collection objects.
141 | - (id)objectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length;
142 | - (id)objectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length error:(NSError **)error;
143 | // The NSData MUST be UTF8 encoded JSON.
144 | - (id)objectWithData:(NSData *)jsonData;
145 | - (id)objectWithData:(NSData *)jsonData error:(NSError **)error;
146 |
147 | // Methods that return mutable collection objects.
148 | - (id)mutableObjectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length;
149 | - (id)mutableObjectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length error:(NSError **)error;
150 | // The NSData MUST be UTF8 encoded JSON.
151 | - (id)mutableObjectWithData:(NSData *)jsonData;
152 | - (id)mutableObjectWithData:(NSData *)jsonData error:(NSError **)error;
153 |
154 | @end
155 |
156 | ////////////
157 | #pragma mark Deserializing methods
158 | ////////////
159 |
160 | @interface NSString (JSONKitDeserializing)
161 | - (id)objectFromJSONString;
162 | - (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
163 | - (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
164 | - (id)mutableObjectFromJSONString;
165 | - (id)mutableObjectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
166 | - (id)mutableObjectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
167 | @end
168 |
169 | @interface NSData (JSONKitDeserializing)
170 | // The NSData MUST be UTF8 encoded JSON.
171 | - (id)objectFromJSONData;
172 | - (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
173 | - (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
174 | - (id)mutableObjectFromJSONData;
175 | - (id)mutableObjectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
176 | - (id)mutableObjectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
177 | @end
178 |
179 | ////////////
180 | #pragma mark Serializing methods
181 | ////////////
182 |
183 | @interface NSString (JSONKitSerializing)
184 | // Convenience methods for those that need to serialize the receiving NSString (i.e., instead of having to serialize a NSArray with a single NSString, you can "serialize to JSON" just the NSString).
185 | // Normally, a string that is serialized to JSON has quotation marks surrounding it, which you may or may not want when serializing a single string, and can be controlled with includeQuotes:
186 | // includeQuotes:YES `a "test"...` -> `"a \"test\"..."`
187 | // includeQuotes:NO `a "test"...` -> `a \"test\"...`
188 | - (NSData *)JSONData; // Invokes JSONDataWithOptions:JKSerializeOptionNone includeQuotes:YES
189 | - (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions includeQuotes:(BOOL)includeQuotes error:(NSError **)error;
190 | - (NSString *)JSONString; // Invokes JSONStringWithOptions:JKSerializeOptionNone includeQuotes:YES
191 | - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions includeQuotes:(BOOL)includeQuotes error:(NSError **)error;
192 | @end
193 |
194 | @interface NSArray (JSONKitSerializing)
195 | - (NSData *)JSONData;
196 | - (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
197 | - (NSString *)JSONString;
198 | - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
199 | @end
200 |
201 | @interface NSDictionary (JSONKitSerializing)
202 | - (NSData *)JSONData;
203 | - (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
204 | - (NSString *)JSONString;
205 | - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
206 | @end
207 |
208 | #endif // __OBJC__
209 |
210 | #endif // _JSONKIT_H_
211 |
212 | #ifdef __cplusplus
213 | } // extern "C"
214 | #endif
215 |
--------------------------------------------------------------------------------
/Lidenbrock/Classes/NSManagedObject+Lidenbrock.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSManagedObject+Lidenbrock.m
3 | // Lidenbrock
4 | //
5 | // Created by feeef on 08/04/11.
6 | // Copyright 2011 Six Degrees. All rights reserved.
7 | //
8 |
9 | #import "NSManagedObject+Lidenbrock.h"
10 |
11 |
12 | @implementation NSManagedObject (Lidenbrock)
13 |
14 |
15 | /***********************************************************************************************************
16 | */
17 | + (void) setSyncIdAs : (NSString *) syncId
18 | {
19 | NSString *className = [LBObjectManager getClassNameFromClass: self];
20 |
21 | [LBObjectManager setSyncIdAs : syncId
22 | forClassName : className];
23 | }
24 |
25 | /***********************************************************************************************************
26 | */
27 | + (void) setDateFormat : (NSString *) format
28 | {
29 | NSString *className = [LBObjectManager getClassNameFromClass: self];
30 |
31 | [LBObjectManager setDateFormat : format
32 | forClassName : className];
33 | }
34 |
35 | /***********************************************************************************************************
36 | */
37 | + (void) setTimeZone : (NSTimeZone *) timeZone
38 | {
39 | NSString *className = [LBObjectManager getClassNameFromClass: self];
40 |
41 | [LBObjectManager setTimeZone : timeZone
42 | forClassName : className];
43 | }
44 |
45 | /***********************************************************************************************************
46 | */
47 | + (void) setMapping : (NSDictionary *) mapping
48 | {
49 | NSString *className = [LBObjectManager getClassNameFromClass: self];
50 |
51 | [LBObjectManager setMapping : mapping
52 | forClassName : className];
53 | }
54 |
55 | /***********************************************************************************************************
56 | */
57 | + (id) newEntity
58 | {
59 | // Get context
60 | //
61 | NSManagedObjectContext *context = [NSManagedObjectContext defaultContext];
62 |
63 | return [NSEntityDescription insertNewObjectForEntityForName: [LBObjectManager getClassNameFromClass: self]
64 | inManagedObjectContext: context];
65 | }
66 |
67 | /***********************************************************************************************************
68 | */
69 | + (id) entityWithId : (NSString *) newId
70 | {
71 | id entity = nil;
72 |
73 | // Make sure the model has the syncId property.
74 | // Otherwise, instanciate a new entity.
75 | //
76 | BOOL isSyncable = (class_getProperty(self, [@"syncID" UTF8String]) != NULL);
77 |
78 | if ([LBObjectManager isString: newId] && isSyncable) {
79 | NSArray *result = [self fetch: @"syncID == %@", newId];
80 | if (result != nil && result.count > 0) {
81 | entity = [result objectAtIndex: 0];
82 | }
83 | else {
84 | entity = [self newEntity];
85 | [entity setValue: newId
86 | forKey: @"syncID"];
87 | NSLog(@"OHData : Insert new %@ with syncID = \"%@\"", [LBObjectManager getClassNameFromClass: self], newId);
88 | }
89 |
90 | return entity;
91 | }
92 | else {
93 |
94 | return [self newEntity];
95 | }
96 | }
97 |
98 | /***********************************************************************************************************
99 | */
100 | + (id) entityFromJson : (NSString *) json
101 | {
102 | NSString *entityName = [LBObjectManager getClassNameFromClass: self];
103 |
104 | return [LBObjectManager objectWithClassName: entityName
105 | fromDictionary: [json mutableObjectFromJSONString]];
106 | }
107 |
108 | /***********************************************************************************************************
109 | */
110 | + (NSArray *) fetch : (NSString *) format, ...
111 | {
112 | // TODO : make an easy way to pass the folloing information to the fetch method :
113 | //
114 | // includes subentities
115 | //
116 | // limit
117 | // offset
118 | // batch size
119 | // affetced stores
120 | // relashionship key path
121 |
122 | // result type
123 | // includes pending changes
124 | // properties to fetch
125 | // distinct results
126 | // includes property values
127 | // returnsObjectsAsFaults
128 |
129 |
130 | ///////////////////////////////////////////////////////////
131 | // Get context and init Request
132 | //
133 | NSManagedObjectContext *context = [NSManagedObjectContext defaultContext];
134 |
135 | NSString *entityName = [LBObjectManager getClassNameFromClass: self];
136 |
137 | NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
138 | NSEntityDescription *entity = [NSEntityDescription entityForName: entityName
139 | inManagedObjectContext: context];
140 | [fetchRequest setEntity: entity];
141 | [fetchRequest setIncludesSubentities: YES];
142 | [fetchRequest setIncludesPropertyValues: YES];
143 | [fetchRequest setReturnsDistinctResults: YES];
144 |
145 |
146 |
147 | ///////////////////////////////////////////////////////////
148 | // Extract Sorting order from the format
149 | //
150 | __block NSRange sortMatchRange;
151 | __block NSString *sortKey = nil;
152 | __block BOOL sortAscending = YES;
153 |
154 | NSError *error = nil;
155 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern: @"ORDER BY ([\\w\\.]*)(\\sDESC|\\sASC)?"
156 | options: NSRegularExpressionCaseInsensitive
157 | error: &error];
158 |
159 | [regex enumerateMatchesInString: format
160 | options: 0
161 | range: NSMakeRange(0, [format length])
162 | usingBlock: ^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop) {
163 |
164 | sortMatchRange = [match range];
165 | NSRange capture1Range = [match rangeAtIndex: 1];
166 | NSRange capture2Range = [match rangeAtIndex: 2];
167 |
168 | if (capture1Range.length > 0) {
169 | sortKey = [format substringWithRange: capture1Range];
170 | }
171 |
172 | if (capture2Range.length > 0) {
173 | NSString *direction = [format substringWithRange: capture2Range];
174 | if ([direction isEqualToString: @"DESC"]) {
175 | sortAscending = NO;
176 | }
177 | }
178 | }];
179 |
180 | if (sortMatchRange.location != NSNotFound) {
181 | format = [format stringByReplacingCharactersInRange: sortMatchRange
182 | withString: @""];
183 | }
184 |
185 |
186 |
187 | ///////////////////////////////////////////////////////////
188 | // Set Predicate
189 | //
190 | format = [format stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
191 |
192 | // If the format is represented by '*' it means we want to list all elements.
193 | // We don't set the predicate for that purpose
194 | //
195 | if ([format isEqualToString: @"*"]) {
196 | NSLog(@"OHData : Fetch from %@ : All", entity.name);
197 | }
198 | else {
199 | va_list args;
200 | va_start(args, format);
201 |
202 | NSPredicate *predicate = [NSPredicate predicateWithFormat: format
203 | arguments: args];
204 | va_end(args);
205 |
206 | [fetchRequest setPredicate: predicate];
207 |
208 | NSLog(@"OHData : Fetch from %@ : %@", entity.name, [predicate predicateFormat]);
209 | }
210 |
211 |
212 |
213 | ///////////////////////////////////////////////////////////
214 | // Set Sort Descriptor
215 | //
216 | if (sortKey != nil) {
217 | NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey: sortKey
218 | ascending: sortAscending];
219 |
220 | [fetchRequest setSortDescriptors: [NSArray arrayWithObject: sortDescriptor]];
221 |
222 | NSString *sortDirection = @"ASC";
223 | if (!sortAscending) {
224 | sortDirection = @"DESC";
225 | }
226 | NSLog(@"OHData : ORDER BY %@ %@", sortKey, sortDirection);
227 | }
228 |
229 |
230 | ///////////////////////////////////////////////////////////
231 | // Run fetch request
232 | //
233 | NSArray *array = [context executeFetchRequest: fetchRequest
234 | error: &error];
235 |
236 | [fetchRequest release];
237 |
238 | return array;
239 | }
240 |
241 |
242 | /***********************************************************************************************************
243 | */
244 | + (NSArray *) entitiesFromJson : (NSString *) json
245 | {
246 | // If the JSON data represents an NSArray, the list is processed
247 | // otherwise, an empty array is returned.
248 | //
249 | id plist = [json mutableObjectFromJSONString];
250 |
251 | if ([LBObjectManager isArray: plist]) {
252 | return [self entitiesFromPlist: [json mutableObjectFromJSONString]];
253 | }
254 | else {
255 | return [NSArray array];
256 | }
257 |
258 | }
259 |
260 | /***********************************************************************************************************
261 | */
262 | + (NSArray *) entitiesFromPlist : (NSArray *) array {
263 |
264 | // If the Array is valid, the list is processed
265 | // otherwise, an empty array is returned.
266 | //
267 | if ([LBObjectManager isArray: array]) {
268 | return [LBObjectManager objectsWithClassName: [LBObjectManager getClassNameFromClass: self]
269 | fromArray: array];
270 | }
271 | else {
272 | return [NSArray array];
273 | }
274 |
275 | }
276 |
277 | /***********************************************************************************************************
278 | */
279 | - (void) loadFromJson : (NSString *) json
280 | {
281 | // TODO : Make sure it is a dictionary
282 | //
283 | [self loadFromDictionary: [json mutableObjectFromJSONString]];
284 | }
285 |
286 | /***********************************************************************************************************
287 | */
288 | - (void) loadFromDictionary : (NSDictionary *) dictionary
289 | {
290 | if (dictionary != nil)
291 | {
292 | NSString *className = [LBObjectManager getClassNameFromClass: [self class]];
293 | NSString *customSyncId = [LBObjectManager syncIdForClassName: className];
294 | NSDictionary *mapping = [LBObjectManager mappingForClassName: className];
295 |
296 | NSArray *keys = [dictionary allKeys];
297 |
298 | NSString *key;
299 | id value;
300 | int i;
301 |
302 | // Read each key/value pairs from the dictionary and set
303 | // the properties of the current object with them
304 | //
305 | for (i = 0; i < [keys count]; i++)
306 | {
307 | BOOL shouldUpdate = YES;
308 |
309 | // Load property
310 | //
311 | key = (NSString *)[keys objectAtIndex: i];
312 | value = [dictionary objectForKey: key];
313 |
314 | if (mapping != nil) {
315 | id mapKey = [mapping objectForKey: key];
316 | if (mapKey != nil) {
317 | key = mapKey;
318 | }
319 | }
320 |
321 |
322 |
323 |
324 | if (customSyncId != nil && [key isEqualToString: customSyncId])
325 | {
326 | key = @"syncID";
327 | }
328 | else if ([key isEqualToString: @"id"] || [key isEqualToString: @"_id"])
329 | {
330 | key = @"syncID";
331 | }
332 |
333 | if ([LBObjectManager isDictionary: value]) {
334 | // Parse dictionary
335 | //
336 | NSString *className = [self getClassNameForKey: key];
337 | if (className != nil) {
338 | value = [LBObjectManager objectWithClassName: [self getClassNameForKey: key]
339 | fromDictionary: value];
340 | }
341 | }
342 | else if ([LBObjectManager isArray: value]) {
343 |
344 | NSDictionary *relations = [[self entity] relationshipsByName];
345 | NSRelationshipDescription *rel = [relations objectForKey: key];
346 |
347 | if (rel) {
348 | NSString *subClassName = [[rel destinationEntity] managedObjectClassName];
349 |
350 | NSArray *array = [LBObjectManager objectsWithClassName: subClassName
351 | fromArray: value];
352 |
353 |
354 | NSEnumerator* enumerator = [array objectEnumerator];
355 | id model;
356 | while ((model = [enumerator nextObject]))
357 | {
358 | NSSet *changedObjects = [[NSSet alloc] initWithObjects:&model count:1];
359 | [self willChangeValueForKey: key
360 | withSetMutation: NSKeyValueUnionSetMutation
361 | usingObjects: changedObjects];
362 |
363 | [[self primitiveValueForKey: key] addObject: model];
364 |
365 | [self didChangeValueForKey: key
366 | withSetMutation: NSKeyValueUnionSetMutation
367 | usingObjects: changedObjects];
368 | [changedObjects release];
369 | }
370 | }
371 |
372 | shouldUpdate = NO;
373 | }
374 |
375 | // Set property
376 | //
377 | if (shouldUpdate && [LBObjectManager object: self
378 | hasProperty: key]) {
379 |
380 | NSAttributeDescription *prop = (NSAttributeDescription *)[[[self entity] propertiesByName] objectForKey: key];
381 |
382 | if ([prop attributeType] == NSDateAttributeType) {
383 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
384 |
385 | // Set Format
386 | //
387 | NSString *dateFormat = [LBObjectManager dateFormatForClassName: className];
388 | if (dateFormat == nil) {
389 | dateFormat = @"yyyy-MM-dd HH:mm:ss";
390 | }
391 | NSLog(@"OHData : Using date format on %@ : %@", className, dateFormat);
392 | [formatter setDateFormat: dateFormat];
393 |
394 | // Set timezone
395 | //
396 | NSTimeZone *timeZone = [LBObjectManager timeZoneForClassName: className];
397 | if (timeZone != nil) {
398 | [formatter setTimeZone: timeZone];
399 | NSLog(@"OHData : Using time zone on %@ : %@", className, [timeZone name]);
400 | }
401 |
402 | NSDate *dateFromString = [formatter dateFromString: value];
403 |
404 | [formatter release];
405 |
406 | [self setValue: dateFromString
407 | forKey: key];
408 | }
409 | else {
410 | [self setValue: value
411 | forKey: key];
412 | }
413 | }
414 | }
415 | }
416 | }
417 |
418 |
419 | /***********************************************************************************************************
420 | */
421 | - (NSDictionary *) toDictionary : (NSString *) parentName
422 | {
423 | NSString *className = [LBObjectManager getClassNameFromClass: [self class]];
424 |
425 | // Load real object properties
426 | //
427 | NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithDictionary: [LBObjectManager propertiesFromObject: self]];
428 |
429 |
430 | // remove any backward relationship
431 | //
432 | if (parentName != nil) {
433 |
434 | NSArray *props = [[self entity] properties];
435 |
436 |
437 | NSEnumerator* enumerator = [props objectEnumerator];
438 | id value;
439 | while ((value = [enumerator nextObject]))
440 | {
441 | if ([value isKindOfClass: [NSRelationshipDescription class]]) {
442 |
443 | if ([[[value destinationEntity] name] isEqualToString: parentName]) {
444 | [attributes removeObjectForKey: [value name]];
445 | }
446 | }
447 | }
448 | }
449 |
450 |
451 |
452 | return [LBObjectManager plistFromDictionary: attributes
453 | withEntityName: className];
454 | }
455 |
456 |
457 | /***********************************************************************************************************
458 | */
459 | - (NSString *) toJson
460 | {
461 | return [LBObjectManager jsonFromObject: self];
462 | }
463 |
464 |
465 | /***********************************************************************************************************
466 | */
467 | - (BOOL) save
468 | {
469 | // Save the objects in the data store
470 | //
471 | return [NSManagedObjectContext saveDefaultContext];
472 | }
473 |
474 | /***********************************************************************************************************
475 | */
476 | - (NSString *) getClassNameForKey : (NSString *) key
477 | {
478 | // If the dictionary represents a property in this object,
479 | // we make sure to load its class name and get the object
480 | // from the dictionary.
481 | //
482 | NSString *className = [LBObjectManager getClassNameFromProperty: key
483 | inObject: self];
484 |
485 | return className;
486 | }
487 |
488 | @end
489 |
--------------------------------------------------------------------------------
/Lidenbrock.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXAggregateTarget section */
10 | C771B694137D6F1200FA004C /* Universal_Framework */ = {
11 | isa = PBXAggregateTarget;
12 | buildConfigurationList = C771B6A1137D6F1200FA004C /* Build configuration list for PBXAggregateTarget "Universal_Framework" */;
13 | buildPhases = (
14 | C771B693137D6F1200FA004C /* ShellScript */,
15 | );
16 | dependencies = (
17 | );
18 | name = Universal_Framework;
19 | productName = Universal_Framework;
20 | };
21 | /* End PBXAggregateTarget section */
22 |
23 | /* Begin PBXBuildFile section */
24 | C771B692137D6F1200FA004C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C771B691137D6F1200FA004C /* Foundation.framework */; };
25 | C771B69A137D6F1200FA004C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C771B698137D6F1200FA004C /* InfoPlist.strings */; };
26 | C771B6AE137D6F7A00FA004C /* JSONKit.h in Headers */ = {isa = PBXBuildFile; fileRef = C771B6A5137D6F7A00FA004C /* JSONKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
27 | C771B6AF137D6F7A00FA004C /* JSONKit.m in Sources */ = {isa = PBXBuildFile; fileRef = C771B6A6137D6F7A00FA004C /* JSONKit.m */; };
28 | C771B6B0137D6F7A00FA004C /* LBObjectManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C771B6A7137D6F7A00FA004C /* LBObjectManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
29 | C771B6B1137D6F7A00FA004C /* LBObjectManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C771B6A8137D6F7A00FA004C /* LBObjectManager.m */; };
30 | C771B6B2137D6F7A00FA004C /* Lidenbrock.h in Headers */ = {isa = PBXBuildFile; fileRef = C771B6A9137D6F7A00FA004C /* Lidenbrock.h */; settings = {ATTRIBUTES = (Public, ); }; };
31 | C771B6B3137D6F7A00FA004C /* NSManagedObject+Lidenbrock.h in Headers */ = {isa = PBXBuildFile; fileRef = C771B6AA137D6F7A00FA004C /* NSManagedObject+Lidenbrock.h */; settings = {ATTRIBUTES = (Public, ); }; };
32 | C771B6B4137D6F7A00FA004C /* NSManagedObject+Lidenbrock.m in Sources */ = {isa = PBXBuildFile; fileRef = C771B6AB137D6F7A00FA004C /* NSManagedObject+Lidenbrock.m */; };
33 | C771B6B5137D6F7A00FA004C /* NSManagedObjectContext+Lidenbrock.h in Headers */ = {isa = PBXBuildFile; fileRef = C771B6AC137D6F7A00FA004C /* NSManagedObjectContext+Lidenbrock.h */; settings = {ATTRIBUTES = (Public, ); }; };
34 | C771B6B6137D6F7A00FA004C /* NSManagedObjectContext+Lidenbrock.m in Sources */ = {isa = PBXBuildFile; fileRef = C771B6AD137D6F7A00FA004C /* NSManagedObjectContext+Lidenbrock.m */; };
35 | C771B6BA137D6FD400FA004C /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C771B6B8137D6FD400FA004C /* CoreData.framework */; };
36 | C771B6BB137D6FD400FA004C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C771B6B9137D6FD400FA004C /* UIKit.framework */; };
37 | C791ABE214A2261F00484241 /* DOC.md in Resources */ = {isa = PBXBuildFile; fileRef = C791ABE114A2261F00484241 /* DOC.md */; };
38 | C7C5820B1393D1AE00C207B5 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = C7C5820A1393D1AE00C207B5 /* LICENSE */; };
39 | /* End PBXBuildFile section */
40 |
41 | /* Begin PBXFileReference section */
42 | C771B68E137D6F1200FA004C /* Lidenbrock.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework.static; includeInIndex = 0; path = Lidenbrock.framework; sourceTree = BUILT_PRODUCTS_DIR; };
43 | C771B691137D6F1200FA004C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
44 | C771B697137D6F1200FA004C /* Lidenbrock-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Lidenbrock-Info.plist"; sourceTree = ""; };
45 | C771B699137D6F1200FA004C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
46 | C771B69B137D6F1200FA004C /* Lidenbrock-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Lidenbrock-Prefix.pch"; sourceTree = ""; };
47 | C771B6A5137D6F7A00FA004C /* JSONKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONKit.h; sourceTree = ""; };
48 | C771B6A6137D6F7A00FA004C /* JSONKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSONKit.m; sourceTree = ""; };
49 | C771B6A7137D6F7A00FA004C /* LBObjectManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LBObjectManager.h; sourceTree = ""; };
50 | C771B6A8137D6F7A00FA004C /* LBObjectManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LBObjectManager.m; sourceTree = ""; };
51 | C771B6A9137D6F7A00FA004C /* Lidenbrock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Lidenbrock.h; sourceTree = ""; };
52 | C771B6AA137D6F7A00FA004C /* NSManagedObject+Lidenbrock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+Lidenbrock.h"; sourceTree = ""; };
53 | C771B6AB137D6F7A00FA004C /* NSManagedObject+Lidenbrock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+Lidenbrock.m"; sourceTree = ""; };
54 | C771B6AC137D6F7A00FA004C /* NSManagedObjectContext+Lidenbrock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+Lidenbrock.h"; sourceTree = ""; };
55 | C771B6AD137D6F7A00FA004C /* NSManagedObjectContext+Lidenbrock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+Lidenbrock.m"; sourceTree = ""; };
56 | C771B6B7137D6FB400FA004C /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.md; sourceTree = ""; };
57 | C771B6B8137D6FD400FA004C /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
58 | C771B6B9137D6FD400FA004C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
59 | C791ABE114A2261F00484241 /* DOC.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DOC.md; sourceTree = ""; };
60 | C7C5820A1393D1AE00C207B5 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; };
61 | /* End PBXFileReference section */
62 |
63 | /* Begin PBXFrameworksBuildPhase section */
64 | C771B68A137D6F1200FA004C /* Frameworks */ = {
65 | isa = PBXFrameworksBuildPhase;
66 | buildActionMask = 2147483647;
67 | files = (
68 | C771B692137D6F1200FA004C /* Foundation.framework in Frameworks */,
69 | C771B6BA137D6FD400FA004C /* CoreData.framework in Frameworks */,
70 | C771B6BB137D6FD400FA004C /* UIKit.framework in Frameworks */,
71 | );
72 | runOnlyForDeploymentPostprocessing = 0;
73 | };
74 | /* End PBXFrameworksBuildPhase section */
75 |
76 | /* Begin PBXGroup section */
77 | C771B682137D6F1200FA004C = {
78 | isa = PBXGroup;
79 | children = (
80 | C791ABE114A2261F00484241 /* DOC.md */,
81 | C7C5820A1393D1AE00C207B5 /* LICENSE */,
82 | C771B6B7137D6FB400FA004C /* README.md */,
83 | C771B695137D6F1200FA004C /* Lidenbrock */,
84 | C771B690137D6F1200FA004C /* Frameworks */,
85 | C771B68F137D6F1200FA004C /* Products */,
86 | );
87 | sourceTree = "";
88 | };
89 | C771B68F137D6F1200FA004C /* Products */ = {
90 | isa = PBXGroup;
91 | children = (
92 | C771B68E137D6F1200FA004C /* Lidenbrock.framework */,
93 | );
94 | name = Products;
95 | sourceTree = "";
96 | };
97 | C771B690137D6F1200FA004C /* Frameworks */ = {
98 | isa = PBXGroup;
99 | children = (
100 | C771B6B8137D6FD400FA004C /* CoreData.framework */,
101 | C771B6B9137D6FD400FA004C /* UIKit.framework */,
102 | C771B691137D6F1200FA004C /* Foundation.framework */,
103 | );
104 | name = Frameworks;
105 | sourceTree = "";
106 | };
107 | C771B695137D6F1200FA004C /* Lidenbrock */ = {
108 | isa = PBXGroup;
109 | children = (
110 | C771B6A4137D6F7A00FA004C /* Classes */,
111 | C771B696137D6F1200FA004C /* Supporting Files */,
112 | );
113 | path = Lidenbrock;
114 | sourceTree = "";
115 | };
116 | C771B696137D6F1200FA004C /* Supporting Files */ = {
117 | isa = PBXGroup;
118 | children = (
119 | C771B697137D6F1200FA004C /* Lidenbrock-Info.plist */,
120 | C771B698137D6F1200FA004C /* InfoPlist.strings */,
121 | C771B69B137D6F1200FA004C /* Lidenbrock-Prefix.pch */,
122 | );
123 | name = "Supporting Files";
124 | sourceTree = "";
125 | };
126 | C771B6A4137D6F7A00FA004C /* Classes */ = {
127 | isa = PBXGroup;
128 | children = (
129 | C771B6A9137D6F7A00FA004C /* Lidenbrock.h */,
130 | C771B6AA137D6F7A00FA004C /* NSManagedObject+Lidenbrock.h */,
131 | C771B6AB137D6F7A00FA004C /* NSManagedObject+Lidenbrock.m */,
132 | C771B6AC137D6F7A00FA004C /* NSManagedObjectContext+Lidenbrock.h */,
133 | C771B6AD137D6F7A00FA004C /* NSManagedObjectContext+Lidenbrock.m */,
134 | C771B6A7137D6F7A00FA004C /* LBObjectManager.h */,
135 | C771B6A8137D6F7A00FA004C /* LBObjectManager.m */,
136 | C771B6A5137D6F7A00FA004C /* JSONKit.h */,
137 | C771B6A6137D6F7A00FA004C /* JSONKit.m */,
138 | );
139 | path = Classes;
140 | sourceTree = "";
141 | };
142 | /* End PBXGroup section */
143 |
144 | /* Begin PBXHeadersBuildPhase section */
145 | C771B68B137D6F1200FA004C /* Headers */ = {
146 | isa = PBXHeadersBuildPhase;
147 | buildActionMask = 2147483647;
148 | files = (
149 | C771B6AE137D6F7A00FA004C /* JSONKit.h in Headers */,
150 | C771B6B0137D6F7A00FA004C /* LBObjectManager.h in Headers */,
151 | C771B6B2137D6F7A00FA004C /* Lidenbrock.h in Headers */,
152 | C771B6B3137D6F7A00FA004C /* NSManagedObject+Lidenbrock.h in Headers */,
153 | C771B6B5137D6F7A00FA004C /* NSManagedObjectContext+Lidenbrock.h in Headers */,
154 | );
155 | runOnlyForDeploymentPostprocessing = 0;
156 | };
157 | /* End PBXHeadersBuildPhase section */
158 |
159 | /* Begin PBXNativeTarget section */
160 | C771B68D137D6F1200FA004C /* Lidenbrock */ = {
161 | isa = PBXNativeTarget;
162 | buildConfigurationList = C771B69E137D6F1200FA004C /* Build configuration list for PBXNativeTarget "Lidenbrock" */;
163 | buildPhases = (
164 | C771B689137D6F1200FA004C /* Sources */,
165 | C771B68A137D6F1200FA004C /* Frameworks */,
166 | C771B68B137D6F1200FA004C /* Headers */,
167 | C771B68C137D6F1200FA004C /* Resources */,
168 | );
169 | buildRules = (
170 | );
171 | dependencies = (
172 | );
173 | name = Lidenbrock;
174 | productName = Lidenbrock;
175 | productReference = C771B68E137D6F1200FA004C /* Lidenbrock.framework */;
176 | productType = "com.apple.product-type.framework.static";
177 | };
178 | /* End PBXNativeTarget section */
179 |
180 | /* Begin PBXProject section */
181 | C771B684137D6F1200FA004C /* Project object */ = {
182 | isa = PBXProject;
183 | attributes = {
184 | ORGANIZATIONNAME = "Six Degrees";
185 | };
186 | buildConfigurationList = C771B687137D6F1200FA004C /* Build configuration list for PBXProject "Lidenbrock" */;
187 | compatibilityVersion = "Xcode 3.2";
188 | developmentRegion = English;
189 | hasScannedForEncodings = 0;
190 | knownRegions = (
191 | en,
192 | );
193 | mainGroup = C771B682137D6F1200FA004C;
194 | productRefGroup = C771B68F137D6F1200FA004C /* Products */;
195 | projectDirPath = "";
196 | projectRoot = "";
197 | targets = (
198 | C771B68D137D6F1200FA004C /* Lidenbrock */,
199 | C771B694137D6F1200FA004C /* Universal_Framework */,
200 | );
201 | };
202 | /* End PBXProject section */
203 |
204 | /* Begin PBXResourcesBuildPhase section */
205 | C771B68C137D6F1200FA004C /* Resources */ = {
206 | isa = PBXResourcesBuildPhase;
207 | buildActionMask = 2147483647;
208 | files = (
209 | C771B69A137D6F1200FA004C /* InfoPlist.strings in Resources */,
210 | C7C5820B1393D1AE00C207B5 /* LICENSE in Resources */,
211 | C791ABE214A2261F00484241 /* DOC.md in Resources */,
212 | );
213 | runOnlyForDeploymentPostprocessing = 0;
214 | };
215 | /* End PBXResourcesBuildPhase section */
216 |
217 | /* Begin PBXShellScriptBuildPhase section */
218 | C771B693137D6F1200FA004C /* ShellScript */ = {
219 | isa = PBXShellScriptBuildPhase;
220 | buildActionMask = 2147483647;
221 | files = (
222 | );
223 | inputPaths = (
224 | );
225 | outputPaths = (
226 | );
227 | runOnlyForDeploymentPostprocessing = 0;
228 | shellPath = /bin/sh;
229 | shellScript = "\n# Assume the target name is the same as the project name\nUFW_TARGET=${PROJECT}\n\nif [ -z ${SDK_NAME} ]; then\n# Use the latest iphoneos SDK available\nUFW_GREP_RESULT=$(xcodebuild -showsdks | grep -o \"iphoneos.*$\")\nwhile read -r line; do\nUFW_SDK_VERSION=\"${line}\"\ndone <<< \"${UFW_GREP_RESULT}\"\nelse\n# Use the SDK specified by XCode\nUFW_SDK_VERSION=\"${SDK_NAME}\"\nfi\n\nUFW_SDK_VERSION=$(echo \"${UFW_SDK_VERSION}\" | grep -o \"[0-9].*$\")\nUFW_FMWK_DIRNAME=\"${UFW_TARGET}.framework\"\nUFW_EMBEDDED_DIRNAME=\"${UFW_TARGET}.embeddedframework\"\nUFW_EXE_PATH=\"${UFW_FMWK_DIRNAME}/Versions/Current/${UFW_TARGET}\"\nUFW_IPHONE_DIR=\"${BUILD_DIR}/${CONFIGURATION}-iphoneos\"\nUFW_SIMULATOR_DIR=\"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator\"\nUFW_UNIVERSAL_DIR=\"${BUILD_DIR}/${CONFIGURATION}-universal\"\n\n\n# Build Framework\n\nrm -rf \"${UFW_UNIVERSAL_DIR}\"\n\nxcodebuild -target \"${UFW_TARGET}\" -configuration ${CONFIGURATION} -sdk iphoneos${UFW_SDK_VERSION} BUILD_DIR=${BUILD_DIR} CONFIGURATION_TEMP_DIR=${CONFIGURATION_TEMP_DIR} clean build\nif [ \"$?\" != \"0\" ]; then echo >&2 \"Error: xcodebuild failed\"; exit 1; fi\nxcodebuild -target \"${UFW_TARGET}\" -configuration ${CONFIGURATION} -sdk iphonesimulator${UFW_SDK_VERSION} BUILD_DIR=${BUILD_DIR} CONFIGURATION_TEMP_DIR=${CONFIGURATION_TEMP_DIR} clean build\nif [ \"$?\" != \"0\" ]; then echo >&2 \"Error: xcodebuild failed\"; exit 1; fi\n\nif [ ! -f \"${UFW_IPHONE_DIR}/${UFW_EXE_PATH}\" ]; then\necho \"Framework target \\\"${UFW_TARGET}\\\" had no source files to build from. Make sure your source files have the correct target membership\"\nexit 1\nfi\n\nmkdir -p \"${UFW_UNIVERSAL_DIR}\"\nif [ \"$?\" != \"0\" ]; then echo >&2 \"Error: mkdir failed\"; exit 1; fi\n\ncp -a \"${UFW_IPHONE_DIR}/${UFW_FMWK_DIRNAME}\" \"${UFW_UNIVERSAL_DIR}/${UFW_FMWK_DIRNAME}\"\nif [ \"$?\" != \"0\" ]; then echo >&2 \"Error: cp failed\"; exit 1; fi\n\nlipo -create -output \"${UFW_UNIVERSAL_DIR}/${UFW_EXE_PATH}\" \"${UFW_IPHONE_DIR}/${UFW_EXE_PATH}\" \"${UFW_SIMULATOR_DIR}/${UFW_EXE_PATH}\"\nif [ \"$?\" != \"0\" ]; then echo >&2 \"Error: lipo failed\"; exit 1; fi\n\n\n# Build Embedded Framework\n\nmkdir -p \"${UFW_UNIVERSAL_DIR}/${UFW_EMBEDDED_DIRNAME}/Resources\"\nif [ \"$?\" != \"0\" ]; then echo >&2 \"Error: mkdir failed\"; exit 1; fi\n\ncp -a \"${UFW_UNIVERSAL_DIR}/${UFW_FMWK_DIRNAME}\" \"${UFW_UNIVERSAL_DIR}/${UFW_EMBEDDED_DIRNAME}/\"\nif [ \"$?\" != \"0\" ]; then echo >&2 \"Error: cp failed\"; exit 1; fi\n\ncd \"${UFW_UNIVERSAL_DIR}/${UFW_FMWK_DIRNAME}/Resources\"\nif [ \"$?\" != \"0\" ]; then echo >&2 \"Error: cd failed\"; exit 1; fi\n\nUFW_RESOURCE_LIST=$(ls)\n\ncd \"${UFW_UNIVERSAL_DIR}/${UFW_EMBEDDED_DIRNAME}/Resources\"\nif [ \"$?\" != \"0\" ]; then echo >&2 \"Error: cd failed\"; exit 1; fi\n\nwhile read -r filename; do\nif [ \"${filename}\" != \"Info.plist\" ]; then\nln -s \"../${UFW_FMWK_DIRNAME}/Resources/${filename}\"\nif [ \"$?\" != \"0\" ]; then echo >&2 \"Error: link failed\"; exit 1; fi\nfi\ndone <<< \"${UFW_RESOURCE_LIST}\"\n\t\t\t\t\t";
230 | };
231 | /* End PBXShellScriptBuildPhase section */
232 |
233 | /* Begin PBXSourcesBuildPhase section */
234 | C771B689137D6F1200FA004C /* Sources */ = {
235 | isa = PBXSourcesBuildPhase;
236 | buildActionMask = 2147483647;
237 | files = (
238 | C771B6AF137D6F7A00FA004C /* JSONKit.m in Sources */,
239 | C771B6B1137D6F7A00FA004C /* LBObjectManager.m in Sources */,
240 | C771B6B4137D6F7A00FA004C /* NSManagedObject+Lidenbrock.m in Sources */,
241 | C771B6B6137D6F7A00FA004C /* NSManagedObjectContext+Lidenbrock.m in Sources */,
242 | );
243 | runOnlyForDeploymentPostprocessing = 0;
244 | };
245 | /* End PBXSourcesBuildPhase section */
246 |
247 | /* Begin PBXVariantGroup section */
248 | C771B698137D6F1200FA004C /* InfoPlist.strings */ = {
249 | isa = PBXVariantGroup;
250 | children = (
251 | C771B699137D6F1200FA004C /* en */,
252 | );
253 | name = InfoPlist.strings;
254 | sourceTree = "";
255 | };
256 | /* End PBXVariantGroup section */
257 |
258 | /* Begin XCBuildConfiguration section */
259 | C771B69C137D6F1200FA004C /* Debug */ = {
260 | isa = XCBuildConfiguration;
261 | buildSettings = {
262 | ARCHS = "$(ARCHS_STANDARD_32_BIT)";
263 | GCC_C_LANGUAGE_STANDARD = gnu99;
264 | GCC_OPTIMIZATION_LEVEL = 0;
265 | GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
266 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
267 | GCC_VERSION = com.apple.compilers.llvmgcc42;
268 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
269 | GCC_WARN_UNUSED_VARIABLE = YES;
270 | IPHONEOS_DEPLOYMENT_TARGET = 4.3;
271 | SDKROOT = iphoneos;
272 | };
273 | name = Debug;
274 | };
275 | C771B69D137D6F1200FA004C /* Release */ = {
276 | isa = XCBuildConfiguration;
277 | buildSettings = {
278 | ARCHS = "$(ARCHS_STANDARD_32_BIT)";
279 | GCC_C_LANGUAGE_STANDARD = gnu99;
280 | GCC_VERSION = com.apple.compilers.llvmgcc42;
281 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
282 | GCC_WARN_UNUSED_VARIABLE = YES;
283 | IPHONEOS_DEPLOYMENT_TARGET = 4.3;
284 | SDKROOT = iphoneos;
285 | };
286 | name = Release;
287 | };
288 | C771B69F137D6F1200FA004C /* Debug */ = {
289 | isa = XCBuildConfiguration;
290 | buildSettings = {
291 | ALWAYS_SEARCH_USER_PATHS = NO;
292 | DYLIB_COMPATIBILITY_VERSION = 1;
293 | DYLIB_CURRENT_VERSION = 1;
294 | FRAMEWORK_VERSION = A;
295 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
296 | GCC_PREFIX_HEADER = "Lidenbrock/Lidenbrock-Prefix.pch";
297 | INFOPLIST_FILE = "Lidenbrock/Lidenbrock-Info.plist";
298 | PRODUCT_NAME = "$(TARGET_NAME)";
299 | SKIP_INSTALL = YES;
300 | WRAPPER_EXTENSION = framework;
301 | };
302 | name = Debug;
303 | };
304 | C771B6A0137D6F1200FA004C /* Release */ = {
305 | isa = XCBuildConfiguration;
306 | buildSettings = {
307 | ALWAYS_SEARCH_USER_PATHS = NO;
308 | DYLIB_COMPATIBILITY_VERSION = 1;
309 | DYLIB_CURRENT_VERSION = 1;
310 | FRAMEWORK_VERSION = A;
311 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
312 | GCC_PREFIX_HEADER = "Lidenbrock/Lidenbrock-Prefix.pch";
313 | INFOPLIST_FILE = "Lidenbrock/Lidenbrock-Info.plist";
314 | PRODUCT_NAME = "$(TARGET_NAME)";
315 | SKIP_INSTALL = YES;
316 | WRAPPER_EXTENSION = framework;
317 | };
318 | name = Release;
319 | };
320 | C771B6A2137D6F1200FA004C /* Debug */ = {
321 | isa = XCBuildConfiguration;
322 | buildSettings = {
323 | PRODUCT_NAME = UniversalFramework;
324 | };
325 | name = Debug;
326 | };
327 | C771B6A3137D6F1200FA004C /* Release */ = {
328 | isa = XCBuildConfiguration;
329 | buildSettings = {
330 | PRODUCT_NAME = UniversalFramework;
331 | };
332 | name = Release;
333 | };
334 | /* End XCBuildConfiguration section */
335 |
336 | /* Begin XCConfigurationList section */
337 | C771B687137D6F1200FA004C /* Build configuration list for PBXProject "Lidenbrock" */ = {
338 | isa = XCConfigurationList;
339 | buildConfigurations = (
340 | C771B69C137D6F1200FA004C /* Debug */,
341 | C771B69D137D6F1200FA004C /* Release */,
342 | );
343 | defaultConfigurationIsVisible = 0;
344 | defaultConfigurationName = Release;
345 | };
346 | C771B69E137D6F1200FA004C /* Build configuration list for PBXNativeTarget "Lidenbrock" */ = {
347 | isa = XCConfigurationList;
348 | buildConfigurations = (
349 | C771B69F137D6F1200FA004C /* Debug */,
350 | C771B6A0137D6F1200FA004C /* Release */,
351 | );
352 | defaultConfigurationIsVisible = 0;
353 | defaultConfigurationName = Release;
354 | };
355 | C771B6A1137D6F1200FA004C /* Build configuration list for PBXAggregateTarget "Universal_Framework" */ = {
356 | isa = XCConfigurationList;
357 | buildConfigurations = (
358 | C771B6A2137D6F1200FA004C /* Debug */,
359 | C771B6A3137D6F1200FA004C /* Release */,
360 | );
361 | defaultConfigurationIsVisible = 0;
362 | defaultConfigurationName = Release;
363 | };
364 | /* End XCConfigurationList section */
365 | };
366 | rootObject = C771B684137D6F1200FA004C /* Project object */;
367 | }
368 |
--------------------------------------------------------------------------------
/Lidenbrock/Classes/LBObjectManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // LBObjectManager.m
3 | // Lidenbrock
4 | //
5 | // Created by feeef on 02/02/11.
6 | // Copyright 2011 Six Degrees. All rights reserved.
7 | //
8 |
9 | #import "LBObjectManager.h"
10 |
11 | @implementation LBObjectManager
12 |
13 | static NSMutableDictionary* syncIDs = nil;
14 | static NSMutableDictionary* dateFormats = nil;
15 | static NSMutableDictionary* timeZones = nil;
16 | static NSMutableDictionary* mappings = nil;
17 | static NSMutableDictionary* inverseMappings = nil;
18 |
19 | const char *kInitSelectorName = "entityWithId:";
20 | const char *kSerializeSelectorName = "toDictionary:";
21 | const char *kLoadSelectorName = "loadFromDictionary:";
22 |
23 | /*
24 | -----------------------------------------------------------------------------------------------------------------------------
25 | Utils
26 | -----------------------------------------------------------------------------------------------------------------------------
27 | */
28 |
29 | #pragma mark -
30 | #pragma mark Utils
31 |
32 | /***********************************************************************************************************
33 | */
34 | + (NSString *) evalPattern : (NSString *) pattern
35 | withObject : (id) object
36 | error : (NSError **) error
37 | {
38 |
39 | __block NSString *processed = [NSString stringWithString: pattern];
40 |
41 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern: @"#\\{([^\\{]+)\\}"
42 | options: NSRegularExpressionCaseInsensitive
43 | error: error];
44 |
45 | [regex enumerateMatchesInString: pattern
46 | options: 0
47 | range: NSMakeRange(0, [pattern length])
48 | usingBlock: ^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop) {
49 |
50 | NSRange matchRange = [match range];
51 | NSRange captureRange = [match rangeAtIndex:1];
52 |
53 | NSString *valueString = @"";
54 | NSString *matchString = [pattern substringWithRange: matchRange];
55 | NSString *capturedString = [pattern substringWithRange: captureRange];
56 |
57 | NSError *sysError = nil;
58 |
59 | // Get value from property
60 | //
61 | id propertyValue = [LBObjectManager getValueFromProperty: capturedString
62 | inObject: object
63 | error: &sysError];
64 |
65 | // Handle error
66 | //
67 | if (sysError != nil) {
68 | NSString *errorDescription = [NSString stringWithFormat:
69 | @"Pattern eval failure processing key #{%@}\n - pattern : \"%@\"\n\n%@",
70 | capturedString,
71 | pattern,
72 | [sysError localizedDescription]];
73 |
74 | *error = [NSError errorWithDomain: @"OHSystemError"
75 | code: 2
76 | userInfo: [NSDictionary dictionaryWithObjectsAndKeys:
77 | errorDescription, NSLocalizedDescriptionKey, nil]];
78 | }
79 |
80 | // Process value
81 | //
82 | if ([LBObjectManager isString: propertyValue]) {
83 | valueString = (NSString *)propertyValue;
84 | }
85 | else if ([LBObjectManager isNumber: propertyValue]) {
86 | valueString = [(NSNumber *)propertyValue stringValue];
87 | }
88 | else {
89 | valueString = [LBObjectManager getClassNameFromClass: propertyValue];
90 | }
91 |
92 | processed = [processed stringByReplacingOccurrencesOfString: matchString
93 | withString: valueString];
94 | }];
95 |
96 |
97 | return processed;
98 | }
99 |
100 | /***********************************************************************************************************
101 | */
102 | + (NSString *) getClassNameFromClass : (id) object
103 | {
104 | return [NSString stringWithCString:object_getClassName(object) encoding: NSUTF8StringEncoding];
105 | }
106 |
107 |
108 | /*
109 | -----------------------------------------------------------------------------------------------------------------------------
110 | Handle Properties
111 | -----------------------------------------------------------------------------------------------------------------------------
112 | */
113 |
114 | #pragma mark -
115 | #pragma mark Handle Properties
116 |
117 | /***********************************************************************************************************
118 | */
119 | + (void) setSyncIdAs : (NSString *) syncId
120 | forClassName : (NSString *) className
121 | {
122 | if (nil == syncIDs) {
123 | syncIDs = [NSMutableDictionary dictionary];
124 | }
125 |
126 | [syncIDs setObject: syncId
127 | forKey: className];
128 | }
129 |
130 | /***********************************************************************************************************
131 | */
132 | + (NSString *) syncIdForClassName : (NSString *) className
133 | {
134 | if (nil == syncIDs) {
135 | return nil;
136 | }
137 | else {
138 | return [syncIDs objectForKey: className];
139 | }
140 |
141 | }
142 |
143 | /***********************************************************************************************************
144 | */
145 | + (void) setDateFormat : (NSString *) format
146 | forClassName : (NSString *) className
147 | {
148 | if (nil == dateFormats) {
149 | dateFormats = [NSMutableDictionary dictionary];
150 | }
151 |
152 | [dateFormats setObject: format
153 | forKey: className];
154 | }
155 |
156 | /***********************************************************************************************************
157 | */
158 | + (NSString *) dateFormatForClassName : (NSString *) className
159 | {
160 | if (nil == dateFormats) {
161 | return nil;
162 | }
163 | else {
164 | return [dateFormats objectForKey: className];
165 | }
166 |
167 | }
168 |
169 | /***********************************************************************************************************
170 | */
171 | + (void) setTimeZone : (NSTimeZone *) timeZone
172 | forClassName : (NSString *) className
173 | {
174 | if (nil == timeZones) {
175 | timeZones = [NSMutableDictionary dictionary];
176 | }
177 |
178 | [timeZones setObject: timeZone
179 | forKey: className];
180 | }
181 |
182 |
183 | /***********************************************************************************************************
184 | */
185 | + (NSTimeZone *) timeZoneForClassName : (NSString *) className
186 | {
187 | if (nil == timeZones) {
188 | return nil;
189 | }
190 | else {
191 | return [timeZones objectForKey: className];
192 | }
193 | }
194 |
195 |
196 | /***********************************************************************************************************
197 | */
198 | + (void) setMapping : (NSDictionary *) mapping
199 | forClassName : (NSString *) className
200 | {
201 | if (nil == mappings) {
202 | mappings = [NSMutableDictionary dictionary];
203 | }
204 |
205 | [mappings setObject: mapping
206 | forKey: className];
207 |
208 | // Generate inverse mapping for deserialization
209 | //
210 | NSMutableDictionary *inverseMapping = [NSMutableDictionary dictionary];
211 | NSArray *keys = [mapping allKeys];
212 | id key;
213 | id value;
214 | int i;
215 | for (i = 0; i < [keys count]; i++)
216 | {
217 | key = [keys objectAtIndex: i];
218 | value = [mapping objectForKey: key];
219 |
220 | [inverseMapping setObject: key
221 | forKey: value];
222 | }
223 |
224 | if (nil == inverseMappings) {
225 | inverseMappings = [NSMutableDictionary dictionary];
226 | }
227 |
228 | [inverseMappings setObject: inverseMapping
229 | forKey: className];
230 | }
231 |
232 |
233 | /***********************************************************************************************************
234 | */
235 | + (NSDictionary *) mappingForClassName : (NSString *) className
236 | {
237 | if (nil == mappings) {
238 | return nil;
239 | }
240 | else {
241 | return [mappings objectForKey: className];
242 | }
243 | }
244 |
245 | /***********************************************************************************************************
246 | */
247 | + (NSDictionary *) inverseMappingForClassName : (NSString *) className
248 | {
249 | if (nil == inverseMappings) {
250 | return nil;
251 | }
252 | else {
253 | return [inverseMappings objectForKey: className];
254 | }
255 | }
256 |
257 | /***********************************************************************************************************
258 | This method can accept properties with the following format :
259 | property
260 | property.subProperty
261 | property[index]
262 |
263 | They can also be combined : property.subProperty[index].anotherProperty
264 | */
265 | + (NSString *) getValueFromProperty : (NSString *) propertyName
266 | inObject : (id) object
267 | error : (NSError **) error
268 | {
269 | NSString *errorDescription = nil;
270 |
271 | id value = nil;
272 | if (object != nil) {
273 |
274 | // if there is a call to a sub property, we get to it
275 | //
276 | id parent = object;
277 | NSArray *elems = [propertyName componentsSeparatedByString: @"."];
278 | for(NSString *elem in elems)
279 | {
280 | @try {
281 |
282 | NSString *varName = nil;
283 | NSString *varKey = nil;
284 |
285 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"([^\\[]+)\\[\"?'?([^\\]\\\"\\']+)\"?'?\\]"
286 | options:NSRegularExpressionCaseInsensitive
287 | error:error];
288 |
289 | NSUInteger numberOfMatches = [regex numberOfMatchesInString: elem
290 | options: 0
291 | range: NSMakeRange(0, [elem length])];
292 | if (numberOfMatches > 0) {
293 | NSArray *matches = [regex matchesInString: elem
294 | options: 0
295 | range: NSMakeRange(0, [elem length])];
296 |
297 | NSTextCheckingResult *match = [matches objectAtIndex: 0];
298 |
299 | varName = [elem substringWithRange: [match rangeAtIndex:1]];
300 | varKey = [elem substringWithRange: [match rangeAtIndex:2]];
301 | }
302 |
303 | if (varName == nil) {
304 | varName = elem;
305 | }
306 |
307 | value = [parent valueForKey: varName];
308 |
309 | if ([LBObjectManager isArray: value] && [LBObjectManager isString: varKey]) {
310 | NSNumberFormatter * format = [[NSNumberFormatter alloc] init];
311 | [format setNumberStyle:NSNumberFormatterDecimalStyle];
312 |
313 | value = [(NSArray *)value objectAtIndex: [[format numberFromString: varKey] integerValue]];
314 | [format release];
315 | }
316 |
317 | if ([LBObjectManager isDictionary: value] && [LBObjectManager isString: varKey]) {
318 |
319 | value = [(NSDictionary *)value objectForKey: varKey];
320 | }
321 |
322 | }
323 | @catch (NSException * e) {
324 | value = nil;
325 | }
326 |
327 | if (value == nil) {
328 | if (elem != nil && parent != nil) {
329 | errorDescription = [NSString stringWithFormat:@"Cannot find property '%@' in '%@' object", elem, [LBObjectManager getClassNameFromClass: parent]];
330 | }
331 | else {
332 | errorDescription = [NSString stringWithFormat:@"Cannot find property '%@' in '%@' object", propertyName, [LBObjectManager getClassNameFromClass: object]];
333 | }
334 | break;
335 | }
336 |
337 | parent = value;
338 | }
339 | }
340 | else {
341 | errorDescription = @"Cannot get value from nil object";
342 | }
343 |
344 |
345 | if (errorDescription != nil) {
346 | *error = [NSError errorWithDomain: @"OHSystemError"
347 | code: 1
348 | userInfo: [NSDictionary dictionaryWithObjectsAndKeys:
349 | errorDescription, NSLocalizedDescriptionKey, nil]];
350 | }
351 |
352 | return value;
353 | }
354 |
355 | /***********************************************************************************************************
356 | */
357 | + (NSString *) getClassNameFromProperty : (NSString *) propertyName
358 | inObject : (id) object
359 | {
360 | NSString *className = nil;
361 |
362 | objc_property_t property = class_getProperty([object class], [propertyName UTF8String]);
363 |
364 | if(property != NULL)
365 | {
366 | NSString *propAttr = [NSString stringWithCString: property_getAttributes(property) encoding: NSUTF8StringEncoding];
367 |
368 | NSError *error = NULL;
369 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"@\"([^\"]+)\""
370 | options:NSRegularExpressionCaseInsensitive
371 | error:&error];
372 |
373 | NSArray *matches = [regex matchesInString: propAttr
374 | options: 0
375 | range: NSMakeRange(0, [propAttr length])];
376 |
377 | if (matches != nil && [matches count] > 0) {
378 | NSTextCheckingResult *match = [matches objectAtIndex: 0];
379 | className = [propAttr substringWithRange: [match rangeAtIndex: 1]];
380 | }
381 | };
382 |
383 | return className;
384 | }
385 |
386 | /***********************************************************************************************************
387 | */
388 | + (BOOL) object : (id) object
389 | hasProperty : (NSString *) propertyName
390 | {
391 | BOOL foundProperty = NO;
392 | if (object != nil) {
393 | foundProperty = class_getProperty([object class], [propertyName UTF8String]) != NULL;
394 | }
395 | return foundProperty;
396 | }
397 |
398 | /***********************************************************************************************************
399 | */
400 | + (NSDictionary *) propertiesFromObject : (id) object
401 | {
402 | NSMutableDictionary *propDict = [NSMutableDictionary dictionary];
403 |
404 | if (object != nil) {
405 | unsigned int outCount, i;
406 | objc_property_t *properties = class_copyPropertyList([object class], &outCount);
407 | for(i = 0; i < outCount; i++)
408 | {
409 | objc_property_t property = properties[i];
410 | const char *propName = property_getName(property);
411 | if(propName)
412 | {
413 | NSString *propertyName = [NSString stringWithCString: propName encoding: NSUTF8StringEncoding];
414 | id propertyValue = [object valueForKey: propertyName];
415 |
416 | if (propertyValue != nil)
417 | {
418 | if ([LBObjectManager isModel: propertyValue])
419 | {
420 | propertyValue = objc_msgSend(propertyValue, sel_registerName(kSerializeSelectorName), nil);
421 | }
422 |
423 | [propDict setObject: propertyValue
424 | forKey: propertyName];
425 | }
426 | }
427 | }
428 | free(properties);
429 | }
430 |
431 | return propDict;
432 | }
433 |
434 |
435 | /*
436 | -----------------------------------------------------------------------------------------------------------------------------
437 | Data Type
438 | -----------------------------------------------------------------------------------------------------------------------------
439 | */
440 |
441 | #pragma mark -
442 | #pragma mark Data Type
443 |
444 |
445 | /***********************************************************************************************************
446 | */
447 | + (BOOL) isDictionary : (id) object
448 | {
449 | return (object != nil && [object isKindOfClass: [NSDictionary class]]) ? YES : NO;
450 | }
451 |
452 | /***********************************************************************************************************
453 | */
454 | + (BOOL) isArray : (id) object
455 | {
456 | return (object != nil && [object isKindOfClass: [NSArray class]]) ? YES : NO;
457 | }
458 |
459 | /***********************************************************************************************************
460 | */
461 | + (BOOL) isSet : (id) object
462 | {
463 | return (object != nil && [object isKindOfClass: [NSSet class]]) ? YES : NO;
464 | }
465 |
466 | /***********************************************************************************************************
467 | */
468 | + (BOOL) isString : (id) object
469 | {
470 | return (object != nil && [object isKindOfClass: [NSString class]]) ? YES : NO;
471 | }
472 |
473 | /***********************************************************************************************************
474 | */
475 | + (BOOL) isDate : (id) object
476 | {
477 | return (object != nil && [object isKindOfClass: [NSDate class]]) ? YES : NO;
478 | }
479 |
480 | /***********************************************************************************************************
481 | */
482 | + (BOOL) isNumber : (id) object
483 | {
484 | return (object != nil && [object isKindOfClass: [NSNumber class]]) ? YES : NO;
485 | }
486 |
487 | /***********************************************************************************************************
488 | */
489 | + (BOOL) isModel : (id) object
490 | {
491 | if (object != nil) {
492 | BOOL isSerializable = class_getInstanceMethod([object class], sel_registerName(kSerializeSelectorName)) != NULL;
493 | BOOL isLoadable = class_getInstanceMethod([object class], sel_registerName(kLoadSelectorName)) != NULL;
494 |
495 | return (isSerializable && isLoadable) ? YES : NO;
496 | }
497 | else {
498 | return NO;
499 | }
500 | }
501 |
502 |
503 |
504 | /*
505 | -----------------------------------------------------------------------------------------------------------------------------
506 | Handle Serialization
507 | -----------------------------------------------------------------------------------------------------------------------------
508 | */
509 |
510 | #pragma mark -
511 | #pragma mark Handle Serialization
512 |
513 | /***********************************************************************************************************
514 | */
515 | + (NSData *) dataFromObject : (id) object
516 | {
517 | NSData *xmlData = nil;
518 |
519 | id plist = nil;
520 |
521 | if ([LBObjectManager isModel: object]) {
522 | plist = objc_msgSend(object, sel_registerName(kSerializeSelectorName), nil);
523 | }
524 | else {
525 | plist = object;
526 | }
527 |
528 | if (plist != nil) {
529 | NSString *errorString;
530 |
531 | xmlData = [NSPropertyListSerialization dataFromPropertyList: plist
532 | format: NSPropertyListBinaryFormat_v1_0
533 | errorDescription: &errorString];
534 | if (errorString != nil) {
535 | NSLog(errorString, nil);
536 | [errorString release];
537 | }
538 | }
539 |
540 |
541 | return xmlData;
542 | }
543 |
544 | /***********************************************************************************************************
545 | */
546 | + (NSString *) jsonFromObject : (id) object
547 | {
548 | NSString *json = nil;
549 | NSMutableDictionary *dict = nil;
550 |
551 | if ([LBObjectManager isModel: object]) {
552 | dict = objc_msgSend(object, sel_registerName(kSerializeSelectorName), nil);
553 | }
554 | else if ([LBObjectManager isDictionary: object]) {
555 | dict = object;
556 | }
557 |
558 | if (dict != nil) {
559 | json = [dict JSONString];
560 | }
561 |
562 | return json;
563 | }
564 |
565 | /***********************************************************************************************************
566 | */
567 | + (NSString *) plistFromString : (NSString *) string
568 | {
569 | if (string == nil) {
570 | return @"";
571 | }
572 | else {
573 | return string;
574 | }
575 | }
576 |
577 | /***********************************************************************************************************
578 | */
579 | + (NSNumber *) plistFromNumber : (NSNumber *) number
580 | {
581 | if (number == nil) {
582 | return [NSNumber numberWithInt: 0];
583 | }
584 | else {
585 | return number;
586 | }
587 | }
588 |
589 | /***********************************************************************************************************
590 | */
591 | + (NSDate *) plistFromDate : (NSDate *) date
592 | {
593 | if (date == nil) {
594 | return [NSDate date];
595 | }
596 | else {
597 | return date;
598 | }
599 | }
600 |
601 | /***********************************************************************************************************
602 | */
603 | + (NSString *) stringFromDate : (NSDate *) date
604 | withFormat : (NSString *) format
605 | andTimeZone : (NSTimeZone *) timeZone
606 | {
607 | if (date == nil) {
608 | date = [NSDate date];
609 | }
610 |
611 | if (format == nil) {
612 | format = @"yyyy-MM-dd HH:mm:ss";
613 | }
614 |
615 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
616 | [formatter setDateFormat: format];
617 |
618 | if (timeZone != nil) {
619 | [formatter setTimeZone: timeZone];
620 | }
621 |
622 | NSString *dateString = [formatter stringFromDate: date];
623 |
624 | [formatter release];
625 |
626 | return dateString;
627 | }
628 |
629 |
630 | /***********************************************************************************************************
631 | */
632 | + (NSDictionary *) plistFromModel : (id) model
633 | {
634 | return [LBObjectManager plistFromModel: model
635 | withParentName: nil];
636 | }
637 |
638 | /***********************************************************************************************************
639 | */
640 | + (NSDictionary *) plistFromModel : (id) model
641 | withParentName : (NSString *) parentName
642 | {
643 | if ([LBObjectManager isModel: model]) {
644 | return objc_msgSend(model, sel_registerName(kSerializeSelectorName), parentName);
645 | }
646 | else {
647 | return nil;
648 | }
649 | }
650 |
651 | /***********************************************************************************************************
652 | */
653 | + (NSDictionary *) plistFromDictionary : (NSDictionary *) dictionary
654 | withEntityName : (NSString *) entityName
655 | {
656 | if (dictionary == nil)
657 | {
658 | return [NSDictionary dictionary];
659 | }
660 | else
661 | {
662 | NSDictionary *mapping = [LBObjectManager inverseMappingForClassName: entityName];
663 |
664 | NSMutableDictionary *plistObject = [NSMutableDictionary dictionary];
665 |
666 | NSArray *keys = [dictionary allKeys];
667 |
668 | id key;
669 | id value;
670 | int i;
671 | for (i = 0; i < [keys count]; i++)
672 | {
673 | key = [keys objectAtIndex: i];
674 | value = [dictionary objectForKey: key];
675 |
676 | if (mapping != nil) {
677 | id mapKey = [mapping objectForKey: key];
678 | if (mapKey != nil) {
679 | key = mapKey;
680 | }
681 | }
682 |
683 |
684 | if ([LBObjectManager isString: value]) {
685 | [plistObject setObject: [LBObjectManager plistFromString: value]
686 | forKey: key];
687 |
688 | }
689 | else if ([LBObjectManager isNumber: value]) {
690 | [plistObject setObject: [LBObjectManager plistFromNumber: value]
691 | forKey: key];
692 |
693 | }
694 | else if ([LBObjectManager isDate: value]) {
695 | NSString *format = nil;
696 | NSTimeZone *timeZone = nil;
697 | if (entityName != nil) {
698 | format = [LBObjectManager dateFormatForClassName: entityName];
699 | timeZone = [LBObjectManager timeZoneForClassName: entityName];
700 | }
701 | [plistObject setObject: [LBObjectManager stringFromDate: value
702 | withFormat: format
703 | andTimeZone: timeZone]
704 | forKey: key];
705 |
706 | }
707 | else if ([LBObjectManager isDictionary: value]) {
708 | [plistObject setObject: [LBObjectManager plistFromDictionary: value
709 | withEntityName: nil]
710 | forKey: key];
711 |
712 | }
713 | else if ([LBObjectManager isArray: value]) {
714 | [plistObject setObject: [LBObjectManager plistFromArray: value
715 | withParentName: entityName]
716 | forKey: key];
717 |
718 | }
719 | else if ([LBObjectManager isSet: value]) {
720 | [plistObject setObject: [LBObjectManager plistFromArray: [value allObjects]
721 | withParentName: entityName]
722 | forKey: key];
723 |
724 | }
725 | else if ([LBObjectManager isModel: value]) {
726 | [plistObject setObject: [LBObjectManager plistFromModel: value]
727 | forKey: key];
728 | }
729 |
730 | }
731 |
732 | return plistObject;
733 | }
734 | }
735 |
736 |
737 | /***********************************************************************************************************
738 | */
739 | + (NSArray *) plistFromArray : (NSArray *) array
740 | withParentName : (NSString *) parentName
741 | {
742 | if (array == nil)
743 | {
744 | return [NSArray array];
745 | }
746 | else
747 | {
748 | NSMutableArray *plistObject = [NSMutableArray array];
749 |
750 | NSEnumerator* enumerator = [array objectEnumerator];
751 | id value;
752 | while ((value = [enumerator nextObject]))
753 | {
754 | if ([LBObjectManager isString: value]) {
755 | [plistObject addObject: [LBObjectManager plistFromString: value]];
756 |
757 | }
758 | else if ([LBObjectManager isNumber: value]) {
759 | [plistObject addObject: [LBObjectManager plistFromNumber: value]];
760 |
761 | }
762 | else if ([LBObjectManager isDate: value]) {
763 | [plistObject addObject: [LBObjectManager plistFromDate: value]];
764 |
765 | }
766 | else if ([LBObjectManager isDictionary: value]) {
767 | [plistObject addObject: [LBObjectManager plistFromDictionary: value
768 | withEntityName: nil]];
769 |
770 | }
771 | else if ([LBObjectManager isArray: value]) {
772 | [plistObject addObject: [LBObjectManager plistFromArray: value
773 | withParentName: nil]];
774 |
775 | }
776 | else if ([LBObjectManager isSet: value]) {
777 | [plistObject addObject: [LBObjectManager plistFromArray: [value allObjects]
778 | withParentName: nil]];
779 |
780 | }
781 | else if ([LBObjectManager isModel: value]) {
782 | [plistObject addObject: [LBObjectManager plistFromModel: value
783 | withParentName: parentName]];
784 | }
785 | }
786 |
787 | return plistObject;
788 | }
789 | }
790 |
791 |
792 | /*
793 | -----------------------------------------------------------------------------------------------------------------------------
794 | Handle Deserialization
795 | -----------------------------------------------------------------------------------------------------------------------------
796 | */
797 |
798 | #pragma mark -
799 | #pragma mark Handle Deserialization
800 |
801 | /***********************************************************************************************************
802 | */
803 | + (NSArray *) objectsWithClassName : (NSString *) className
804 | fromJson : (NSString *) json
805 | {
806 | NSArray *objects = [NSArray array];
807 |
808 | // Convert json string into NSDictionary
809 | //
810 | id data = [json JSONString];
811 |
812 |
813 | if ([LBObjectManager isArray: data])
814 | {
815 | objects = [LBObjectManager objectsWithClassName: className
816 | fromArray: (NSArray *)data];
817 | }
818 |
819 | return objects;
820 | }
821 |
822 | /***********************************************************************************************************
823 | */
824 | + (NSArray *) objectsWithClassName : (NSString *) className
825 | fromArray : (NSArray *) array
826 | {
827 | NSMutableArray *objectInstance = nil;
828 |
829 | if (array != nil)
830 | {
831 | objectInstance = [NSMutableArray array];
832 |
833 | NSEnumerator* enumerator = [array objectEnumerator];
834 | id value;
835 | while ((value = [enumerator nextObject]))
836 | {
837 | if ([LBObjectManager isDictionary: value])
838 | {
839 | [objectInstance addObject: [LBObjectManager objectWithClassName: className
840 | fromDictionary: value]];
841 | }
842 | else if ([LBObjectManager isArray: value])
843 | {
844 | [objectInstance addObject: [LBObjectManager objectsWithClassName: nil
845 | fromArray: value]];
846 | }
847 | else
848 | {
849 | [objectInstance addObject: value];
850 | }
851 | }
852 | }
853 | return objectInstance;
854 | }
855 |
856 | /***********************************************************************************************************
857 | */
858 | + (id) objectWithClassName : (NSString *) className
859 | fromDictionary : (NSDictionary *) dictionary
860 | {
861 | id objectInstance = nil;
862 |
863 | if (dictionary != nil)
864 | {
865 | // try to instanciate the model
866 | //
867 | Class objectClass = nil;
868 |
869 | if ([LBObjectManager isString: className]) {
870 | objectClass = NSClassFromString(className);
871 | }
872 |
873 | if (objectClass != nil) {
874 |
875 | // If the Class has a specific object selector, we use it
876 | // Otherwise, we use the default object instantiating process
877 | //
878 | if (class_getClassMethod(objectClass, sel_registerName(kInitSelectorName)) != NULL) {
879 |
880 | NSString *newId = nil;
881 |
882 | NSString *customSyncId = [LBObjectManager syncIdForClassName: className];
883 |
884 | if (customSyncId != nil) {
885 | newId = [dictionary objectForKey: customSyncId];
886 | }
887 | if (newId == nil) {
888 | newId = [dictionary objectForKey: @"_id"];
889 | }
890 | if (newId == nil) {
891 | newId = [dictionary objectForKey: @"id"];
892 | }
893 | if (newId == nil) {
894 | newId = [dictionary objectForKey: @"syncID"];
895 | }
896 | objectInstance = objc_msgSend(objectClass, sel_registerName(kInitSelectorName), newId);
897 | }
898 | else {
899 | objectInstance = [[[objectClass alloc] init] autorelease];
900 | }
901 | }
902 |
903 | if ([LBObjectManager isModel: objectInstance]) {
904 | objc_msgSend(objectInstance, sel_registerName(kLoadSelectorName), dictionary);
905 | }
906 |
907 | // Otherwise, parse the dictionnary data
908 | //
909 | else {
910 | objectInstance = [NSMutableDictionary dictionaryWithDictionary: dictionary];
911 |
912 | NSArray *keys = [dictionary allKeys];
913 |
914 | id key;
915 | id value;
916 | int i;
917 | for (i = 0; i < [keys count]; i++)
918 | {
919 | key = [keys objectAtIndex: i];
920 | value = [dictionary objectForKey: key];
921 |
922 | if ([LBObjectManager isDictionary: value])
923 | {
924 | [objectInstance setObject: [LBObjectManager objectWithClassName: nil
925 | fromDictionary: value]
926 | forKey: key];
927 | }
928 | else if ([LBObjectManager isArray: value])
929 | {
930 | [objectInstance setObject: [LBObjectManager objectsWithClassName: nil
931 | fromArray: value]
932 | forKey: key];
933 | }
934 | }
935 | }
936 | }
937 |
938 | return objectInstance;
939 | }
940 |
941 |
942 |
943 |
944 |
945 | @end
946 |
--------------------------------------------------------------------------------