gyro 0.4.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +42 -797
- data/bin/gyro +91 -84
- data/documentation/enum.png +0 -0
- data/documentation/enum_json.png +0 -0
- data/documentation/ignored.png +0 -0
- data/documentation/json.png +0 -0
- data/documentation/primary_key.png +0 -0
- data/documentation/read_only.png +0 -0
- data/documentation/simple_entity.png +0 -0
- data/documentation/support_annotation.png +0 -0
- data/documentation/transformer.png +0 -0
- data/documentation/transformers.png +0 -0
- data/lib/gyro.rb +18 -29
- data/lib/gyro/generator/json.rb +30 -0
- data/lib/gyro/generator/liquid.rb +22 -0
- data/lib/gyro/generator/liquid/filters.rb +53 -0
- data/lib/gyro/generator/liquid/liquid.rb +124 -0
- data/lib/gyro/generator/liquid/whitespace_patch.rb +61 -0
- data/lib/gyro/log.rb +46 -0
- data/lib/gyro/parser/xcdatamodel.rb +20 -0
- data/lib/gyro/parser/xcdatamodel/attribute.rb +129 -0
- data/lib/gyro/parser/xcdatamodel/entity.rb +195 -0
- data/lib/gyro/parser/xcdatamodel/relationship.rb +84 -0
- data/lib/gyro/parser/xcdatamodel/xcdatamodel.rb +65 -0
- data/lib/gyro/template.rb +68 -0
- data/lib/gyro/version.rb +19 -0
- data/lib/templates/android/README.md +164 -0
- data/lib/templates/android/entity.liquid +49 -0
- data/lib/templates/android/entity_filename.liquid +1 -0
- data/lib/templates/android/enum.liquid +44 -0
- data/lib/templates/android/enum_filename.liquid +1 -0
- data/lib/templates/android/inc/_attributes_enum.liquid +17 -0
- data/lib/templates/android/inc/_attributes_getter_setter.liquid +58 -0
- data/lib/templates/android/inc/_attributes_properties.liquid +35 -0
- data/lib/templates/android/inc/_enum_getter_setter.liquid +19 -0
- data/lib/templates/android/inc/_primitives.liquid +30 -0
- data/lib/templates/android/inc/_relationships_enum.liquid +14 -0
- data/lib/templates/android/inc/_relationships_getter_setter.liquid +47 -0
- data/lib/templates/android/inc/_relationships_properties.liquid +27 -0
- data/lib/templates/android/inc/_type_converter.liquid +22 -0
- data/lib/templates/android/inc/_wrapper_type_converter.liquid +22 -0
- data/lib/templates/decodable/README.md +34 -0
- data/lib/templates/decodable/entity.liquid +57 -0
- data/lib/templates/decodable/entity_filename.liquid +1 -0
- data/lib/templates/decodable/enum.liquid +0 -0
- data/lib/templates/decodable/enum_filename.liquid +0 -0
- data/lib/templates/object-mapper/README.md +40 -0
- data/lib/templates/object-mapper/entity.liquid +66 -0
- data/lib/templates/object-mapper/entity_filename.liquid +1 -0
- data/lib/templates/object-mapper/enum.liquid +0 -0
- data/lib/templates/object-mapper/enum_filename.liquid +0 -0
- data/lib/templates/swift3-variant/README.md +60 -0
- data/lib/templates/swift3-variant/entity.liquid +12 -0
- data/lib/templates/swift3-variant/entity_filename.liquid +1 -0
- data/lib/templates/swift3-variant/enum.liquid +15 -0
- data/lib/templates/swift3-variant/enum_filename.liquid +1 -0
- data/lib/templates/swift3-variant/inc/_attributes_enum.liquid +13 -0
- data/lib/templates/swift3-variant/inc/_attributes_properties.liquid +32 -0
- data/lib/templates/swift3-variant/inc/_default_value_converter.liquid +14 -0
- data/lib/templates/swift3-variant/inc/_enum_attribute_property.liquid +26 -0
- data/lib/templates/swift3-variant/inc/_ignored_properties.liquid +24 -0
- data/lib/templates/swift3-variant/inc/_indexed_properties.liquid +19 -0
- data/lib/templates/swift3-variant/inc/_inverse_properties.liquid +11 -0
- data/lib/templates/swift3-variant/inc/_optional_attribute_property.liquid +5 -0
- data/lib/templates/swift3-variant/inc/_primary_key.liquid +5 -0
- data/lib/templates/swift3-variant/inc/_relationship_properties.liquid +9 -0
- data/lib/templates/swift3-variant/inc/_relationships_enum.liquid +17 -0
- data/lib/templates/swift3-variant/inc/_type_converter.liquid +20 -0
- data/lib/templates/swift3/README.md +60 -0
- data/lib/templates/swift3/entity.liquid +12 -0
- data/lib/templates/swift3/entity_filename.liquid +1 -0
- data/lib/templates/swift3/enum.liquid +15 -0
- data/lib/templates/swift3/enum_filename.liquid +1 -0
- data/lib/templates/swift3/inc/_attributes_enum.liquid +13 -0
- data/lib/templates/swift3/inc/_attributes_properties.liquid +32 -0
- data/lib/templates/swift3/inc/_default_value_converter.liquid +14 -0
- data/lib/templates/swift3/inc/_enum_attribute_property.liquid +26 -0
- data/lib/templates/swift3/inc/_ignored_properties.liquid +24 -0
- data/lib/templates/swift3/inc/_indexed_properties.liquid +19 -0
- data/lib/templates/swift3/inc/_inverse_properties.liquid +11 -0
- data/lib/templates/swift3/inc/_optional_attribute_property.liquid +5 -0
- data/lib/templates/swift3/inc/_primary_key.liquid +5 -0
- data/lib/templates/swift3/inc/_relationship_properties.liquid +9 -0
- data/lib/templates/swift3/inc/_relationships_enum.liquid +17 -0
- data/lib/templates/swift3/inc/_type_converter.liquid +20 -0
- metadata +134 -31
- data/lib/gyro/realm/java/converter.rb +0 -63
- data/lib/gyro/realm/java/enum_generator.rb +0 -128
- data/lib/gyro/realm/java/generator.rb +0 -183
- data/lib/gyro/realm/java/templates.rb +0 -67
- data/lib/gyro/realm/objc/converter.rb +0 -63
- data/lib/gyro/realm/objc/enum_generator.rb +0 -86
- data/lib/gyro/realm/objc/generator.rb +0 -373
- data/lib/gyro/realm/objc/json_category_generator.rb +0 -172
- data/lib/gyro/realm/objc/protocol_generator.rb +0 -59
- data/lib/gyro/realm/objc/templates.rb +0 -100
- data/lib/gyro/realm/swift/converter.rb +0 -74
- data/lib/gyro/realm/swift/enum_generator.rb +0 -73
- data/lib/gyro/realm/swift/generator.rb +0 -265
- data/lib/gyro/realm/swift/object_mapper_generator.rb +0 -124
- data/lib/gyro/realm/swift/templates.rb +0 -64
- data/lib/gyro/utils/file_utils.rb +0 -31
- data/lib/gyro/utils/log.rb +0 -68
- data/lib/gyro/utils/raise.rb +0 -23
- data/lib/gyro/utils/string_xcdatamodel.rb +0 -58
- data/lib/gyro/xcdatamodel/parser/attribute.rb +0 -98
- data/lib/gyro/xcdatamodel/parser/entity.rb +0 -234
- data/lib/gyro/xcdatamodel/parser/relationship.rb +0 -70
- data/lib/gyro/xcdatamodel/parser/xcdatamodel.rb +0 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1db016a0a566471d730df382014b89f0d0dc1d9b
|
4
|
+
data.tar.gz: 8ac5c0522b051b9f61382f2c6332c5c1a3884efd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24a479c020eadc633a9114ab6ce3d111961677a851fec2f34fcded5425bc6ff037bcac1184411dcc55b8e91674d41d68698cab4e5770b7d93640d881b3017a92
|
7
|
+
data.tar.gz: 891fcb7c000c6c044a5aaccf875a5bf73e320613c72e3bf055f63dbcbf75a6c321bfe820efbeb6782af33f00b031afe79eefdc32ddb446cdebf070b2e8561199
|
data/README.md
CHANGED
@@ -1,9 +1,22 @@
|
|
1
|
+
|
1
2
|
# Gyro
|
2
3
|
|
3
|
-
|
4
|
+
[![gem version](https://img.shields.io/gem/v/gyro.svg?style=flat-square)](https://rubygems.org/gems/gyro)
|
5
|
+
[![build circle ci](https://img.shields.io/circleci/project/github/NijiDigital/gyro.svg?style=flat-square)](https://circleci.com/gh/NijiDigital/gyro)
|
6
|
+
[![Twitter](https://img.shields.io/badge/twitter-@Niji_Digital-blue.svg?style=flat-square)](http://twitter.com/Niji_Digital)
|
4
7
|
|
5
|
-
|
8
|
+
Gyro is a tool to generate [Realm](https://realm.io) model classes, for both Android (Java) and iOS/macOS (Swift), from an `.xcdatamodel` file.
|
6
9
|
|
10
|
+
---
|
11
|
+
<center><table><tr>
|
12
|
+
<td><img src='logo.png' width='200' height='200' /></td>
|
13
|
+
<td>
|
14
|
+
<strong>G</strong> enerate<br/>
|
15
|
+
<strong>Y</strong> our<br/>
|
16
|
+
<strong>R</strong> ealm<br/>
|
17
|
+
<strong>O</strong> bjects
|
18
|
+
</td>
|
19
|
+
</tr></table></center>
|
7
20
|
|
8
21
|
## Introduction
|
9
22
|
|
@@ -17,47 +30,41 @@ This will allow you to design your model in a visual way (rather than by code),
|
|
17
30
|
|
18
31
|
The `.xcdatamodel` file is the input of the script.
|
19
32
|
|
20
|
-
|
21
|
-
## License
|
22
|
-
|
23
|
-
This tool is under [the Apache 2 License](LICENSE).
|
24
|
-
|
25
|
-
It has been initially developed by [Niji](http://www.niji.fr) and is in no way affiliated to the [Realm](https://realm.io) company.
|
26
|
-
|
27
|
-
|
28
33
|
## Installation
|
29
34
|
|
30
|
-
|
35
|
+
Gyro is on RubyGems, so this means you can simply install it by using this command in your terminal:
|
31
36
|
|
32
|
-
```
|
33
|
-
|
37
|
+
```bash
|
38
|
+
gem install gyro
|
34
39
|
```
|
35
40
|
|
41
|
+
_Alternativly, you could also clone this repository anywhere you want on your machine, then build and install the local gem_
|
36
42
|
|
43
|
+
```bash
|
44
|
+
gem build gyro.gemspec
|
45
|
+
gem install gyro-1.0.0.gem
|
46
|
+
```
|
37
47
|
|
48
|
+
## Usage
|
38
49
|
|
39
|
-
|
50
|
+
Invoke it with the appropriate options like this:
|
40
51
|
|
41
|
-
|
52
|
+
```bash
|
53
|
+
gyro --model <model> --template <template-name> --output <output-dir> --param <key>:<value>
|
54
|
+
```
|
55
|
+
`<model>` is the path to the xcdatamodel file
|
42
56
|
|
43
|
-
|
44
|
-
| ---------- | --------- | ----------- |:-------:|:---:|
|
45
|
-
| `-m` | `--model` | Path to the `.xcdatamodel` file. If this parameter is not given, Gyro will look for a `.xcdatamodel` | ✅ | ✅ |
|
46
|
-
| `-a` | `--android` | Path to the directory where the generated files for Android will be created (e.g.: home/documents/dev/android/realm_project/com/niji/data) | ✅ | ➖ |
|
47
|
-
| `-p` | `--package` | Full name of the Android "data" package (e.g.: com.niji.data) | ✅ | ➖ |
|
48
|
-
| `-i` | `--ios` | Path to the directory where the generated files for iOS/macOS will be created | ➖ | ✅ |
|
49
|
-
| `-j` | `--json` | Create the Realm-JSON categories (https://github.com/matthewcheok/Realm-JSON) | ➖ | ☑️ |
|
50
|
-
| `-f` | `--framework` | Tells whether the project uses CocoaPods Frameworks | ➖ | ☑️ |
|
51
|
-
| `-s` | `--swift` | Use Swift for the iOS/macOS generation | ➖ | ☑️ |
|
52
|
-
| `-n` | `--nsnumber` | Generate `NSNumber`s instead of Int/BOOL/Float types | ➖ | ☑️ |
|
53
|
-
| `-w` | `--wrappers` | Use type wrappers for Java (Integer, Double, …) for optional attributes instead of primitive types (int, double, …) | ☑️ | ➖ |
|
54
|
-
| `-x` | `--annotations` | Annotate the getters/setters of the generated classes with `@Nullable` for any optional attribute/relationship, and with `@NonNull` for any non-optional attribute/relationship | ☑️ | ➖ |
|
55
|
-
| `-h` | `--help` | Show help | ☑️ | ☑️ |
|
56
|
-
| `-v` | `--version` | Show the current version number of Gyro | ☑️ | ☑️ |
|
57
|
+
`<output-dir>` is the path to the output directory file
|
57
58
|
|
58
|
-
|
59
|
+
`<template-name>` is the name of the template. Below you have the list of templates.
|
59
60
|
|
61
|
+
If you want additional information about templates you can go to the documentation for each :
|
60
62
|
|
63
|
+
- [android](lib/templates/android/README.md)
|
64
|
+
- [swift3](lib/templates/swift3/README.md)
|
65
|
+
- [decodable](lib/templates/decodable/README.md)
|
66
|
+
- [swift3-variant](lib/templates/swift3-variant/README.md)
|
67
|
+
- [object-mapper](lib/templates/object-mapper/README.md)
|
61
68
|
|
62
69
|
## Annotating your `xcdatamodel`
|
63
70
|
|
@@ -65,776 +72,14 @@ The `.xcdatamodel` Xcode editor allows you to add "user infos" to your entities,
|
|
65
72
|
|
66
73
|
_To define a User Info key in Xcode's xcdatamodel editor, select the entity or attribute you want to add a User Info to, then select the 3rd tab in the inspector on the right ("Data Model Inspector", or Cmd-Alt-3), and fill the information you want in the "User Info" section there._
|
67
74
|
|
68
|
-
With the help of these "user infos", you will be able to give Gyro extra information about your model classes. For example, you can tell which attribute is the primary key, the attributes to ignore, the JSON mappings, …
|
69
|
-
|
70
|
-
Below are details about how to annotate your `.xcdatamodel` entities and attributes to be able to leverage each Realm features when generating your Realm models with Gyro.
|
71
|
-
|
72
|
-
|
73
|
-
---
|
74
|
-
|
75
|
-
|
76
|
-
### Primary key
|
77
|
-
|
78
|
-
To tell which attribute will be used as a primary key, add the following 'user info' to **the entity**:
|
79
|
-
|
80
|
-
| Key | Value |
|
81
|
-
|-----|-------|
|
82
|
-
| `identityAttribute` | `name_of_the_attribute` |
|
83
|
-
|
84
|
-
|
85
|
-
__Example__: On the "FidelityCard" entity:
|
86
|
-
|
87
|
-
![Primary Key](documentation/primary_key.png)
|
88
|
-
|
89
|
-
|
90
|
-
<details>
|
91
|
-
<summary>📑 Sample of the generated code in Java (Android)</summary>
|
92
|
-
|
93
|
-
```java
|
94
|
-
package com.niji.data;
|
95
|
-
|
96
|
-
import io.realm.RealmObject;
|
97
|
-
import io.realm.annotations.PrimaryKey;
|
98
|
-
|
99
|
-
/* DO NOT EDIT | Generated by gyro */
|
100
|
-
|
101
|
-
public class FidelityCard extends RealmObject {
|
102
|
-
|
103
|
-
@PrimaryKey
|
104
|
-
private short identifier;
|
105
|
-
private int points;
|
106
|
-
private User user;
|
107
|
-
[...]
|
108
|
-
}
|
109
|
-
```
|
110
|
-
</details>
|
111
|
-
|
112
|
-
<details>
|
113
|
-
<summary>📑 Sample of the generated code in Objective-C (iOS)</summary>
|
114
|
-
|
115
|
-
```objc
|
116
|
-
// DO NOT EDIT | Generated by gyro
|
117
|
-
|
118
|
-
////////////////////////////////////////////////////////////////////////////////
|
119
|
-
|
120
|
-
#pragma mark - Imports
|
121
|
-
|
122
|
-
#import "RLMFidelityCard.h"
|
123
|
-
|
124
|
-
////////////////////////////////////////////////////////////////////////////////
|
125
|
-
|
126
|
-
#pragma mark - Implementation
|
127
|
-
|
128
|
-
@implementation RLMFidelityCard
|
129
|
-
|
130
|
-
#pragma mark - Superclass Overrides
|
131
|
-
|
132
|
-
+ (NSString *)primaryKey
|
133
|
-
{
|
134
|
-
return @"identifier";
|
135
|
-
}
|
136
|
-
|
137
|
-
@end
|
138
|
-
```
|
139
|
-
</details>
|
140
|
-
|
141
|
-
|
142
|
-
---
|
143
|
-
|
144
|
-
|
145
|
-
### Ignore attribute
|
146
|
-
|
147
|
-
You can decide to ignore some attributes of the `.xcdatamodel` file. They will not be persisted to Realm. To do so, add the following 'user info' to **the attribute**:
|
148
|
-
|
149
|
-
| Key | Value |
|
150
|
-
|-----|-------|
|
151
|
-
| `realmIgnored` | `value` |
|
152
|
-
|
153
|
-
|
154
|
-
__Example__: on the attribute `ignored` of the entity `Shop`:
|
155
|
-
|
156
|
-
![Ignored Attribute](documentation/ignored.png)
|
157
|
-
|
158
|
-
|
159
|
-
<details>
|
160
|
-
<summary>📑 Sample of the generated code in Java (Android)</summary>
|
161
|
-
|
162
|
-
```java
|
163
|
-
package com.niji.data;
|
164
|
-
|
165
|
-
import io.realm.RealmList;
|
166
|
-
import io.realm.RealmObject;
|
167
|
-
import io.realm.annotations.Ignore;
|
168
|
-
|
169
|
-
/* DO NOT EDIT | Generated by gyro */
|
170
|
-
|
171
|
-
public class Shop extends RealmObject {
|
172
|
-
|
173
|
-
private String name;
|
174
|
-
private String readOnly;
|
175
|
-
private RealmList<Product> products;
|
176
|
-
@Ignore
|
177
|
-
private String ignored;
|
178
|
-
[...]
|
179
|
-
}
|
180
|
-
```
|
181
|
-
</details>
|
182
|
-
|
183
|
-
<details>
|
184
|
-
<summary>📑 Sample of the generated code in Objective-C (iOS)</summary>
|
185
|
-
|
186
|
-
```objc
|
187
|
-
// DO NOT EDIT | Generated by gyro
|
188
|
-
|
189
|
-
////////////////////////////////////////////////////////////////////////////////
|
190
|
-
|
191
|
-
#pragma mark - Imports
|
192
|
-
|
193
|
-
#import "RLMShop.h"
|
194
|
-
|
195
|
-
////////////////////////////////////////////////////////////////////////////////
|
196
|
-
|
197
|
-
#pragma mark - Implementation
|
198
|
-
|
199
|
-
@implementation RLMShop
|
200
|
-
|
201
|
-
#pragma mark - Superclass Overrides
|
202
|
-
|
203
|
-
// Specify properties to ignore (Realm won't persist these)
|
204
|
-
+ (NSArray *)ignoredProperties
|
205
|
-
{
|
206
|
-
return @[@"ignored"];
|
207
|
-
}
|
208
|
-
@end
|
209
|
-
```
|
210
|
-
</details>
|
211
|
-
|
212
|
-
|
213
|
-
---
|
214
|
-
|
215
|
-
|
216
|
-
### Read only
|
217
|
-
|
218
|
-
On iOS/macOS, you can define attributes which are not persisted and whose value is computed dynamically.
|
219
|
-
To do so, add the following 'user info' to **the attribute**
|
220
|
-
|
221
|
-
| Key | Value |
|
222
|
-
|-----|-------|
|
223
|
-
| `realmReadOnly` | `the_code_source_to_generate` |
|
224
|
-
|
225
|
-
|
226
|
-
__Example__: On the `readOnly` attribute of the `Shop` entity:
|
227
|
-
|
228
|
-
![Read Only](documentation/read_only.png)
|
229
|
-
|
230
|
-
|
231
|
-
<details>
|
232
|
-
<summary>📑 Sample of the generated code in Objective-C (iOS)</summary>
|
233
|
-
|
234
|
-
```objc
|
235
|
-
// DO NOT EDIT | Generated by gyro
|
236
|
-
|
237
|
-
////////////////////////////////////////////////////////////////////////////////
|
238
|
-
|
239
|
-
#pragma mark - Imports
|
240
|
-
|
241
|
-
#import "RLMShop.h"
|
242
|
-
|
243
|
-
////////////////////////////////////////////////////////////////////////////////
|
244
|
-
|
245
|
-
#pragma mark - Implementation
|
246
|
-
|
247
|
-
@implementation RLMShop
|
248
|
-
|
249
|
-
#pragma mark - Superclass Overrides
|
250
|
-
|
251
|
-
- (NSString *)readOnly
|
252
|
-
{
|
253
|
-
return self.name;
|
254
|
-
}
|
255
|
-
|
256
|
-
@end
|
257
|
-
```
|
258
|
-
</details>
|
259
|
-
|
260
|
-
|
261
|
-
---
|
262
|
-
|
263
|
-
|
264
|
-
### Inverse Relationships
|
265
|
-
|
266
|
-
In realm, when you have both A -> B and B -> A relationships, you have to choose one of those relationships to be the primary one (e.g. A -> B) — that will be stored in Realm — and the other inverse relationship will then be **computed** by code. [For more information, see the related RealmSwift documentation on Inverse Relationships](https://realm.io/docs/swift/latest/#inverse-relationships).
|
267
|
-
|
268
|
-
To mark a relationship as being an inverse relationship (the B -> A relationship and not the primary A -> B one), the convention in `gyro` is to **suffix the name of the relationship with an underscore `_`** .
|
269
|
-
|
270
|
-
This will then generate the following code in Swift for that inverse relationship:
|
271
|
-
|
272
|
-
```swift
|
273
|
-
LinkingObjects(fromType: A.self, property: "b")`
|
274
|
-
```
|
275
|
-
|
276
|
-
If your inverse relationship is defined to point to a unique object (inverse of a `1-*` relationship for exemple, and not a `*-*` one), the generated code will contain both the plural form of the computed variable and a singular form returning its first element, for convenience:
|
277
|
-
|
278
|
-
```swift
|
279
|
-
let owners = LinkingObjects(fromType: Person.self, property: "dogs")`
|
280
|
-
var owner: Person? { return owners.first }
|
281
|
-
```
|
282
|
-
|
283
|
-
|
284
|
-
---
|
285
|
-
|
286
|
-
|
287
|
-
### Optionnals fields and wrapper types
|
288
|
-
|
289
|
-
On Android, the `-w`/`--wrappers` flag allows you to use wrapper types (`Double`, `Short`, …) for optional fields instead of primitive types (`double`, `short`, …).
|
290
|
-
|
291
|
-
<details>
|
292
|
-
<summary>📑 Sample of the generated code in Java (Android)</summary>
|
293
|
-
|
294
|
-
```java
|
295
|
-
package com.niji.data;
|
296
|
-
|
297
|
-
import io.realm.RealmObject;
|
298
|
-
import io.realm.annotations.PrimaryKey;
|
299
|
-
|
300
|
-
/* DO NOT EDIT | Generated by gyro */
|
301
|
-
|
302
|
-
public class FidelityCard extends RealmObject {
|
303
|
-
|
304
|
-
@PrimaryKey
|
305
|
-
private short identifier; // "optional" checkbox not checked in the xcdatamodel
|
306
|
-
private Integer points; // "optional" checkbox checked in the xcdatamodel
|
307
|
-
private User user;
|
308
|
-
[...]
|
309
|
-
}
|
310
|
-
```
|
311
|
-
</details>
|
312
|
-
|
313
|
-
|
314
|
-
---
|
315
|
-
|
316
|
-
|
317
|
-
### Support Annotations
|
318
|
-
|
319
|
-
On Android, the flag `-x`/`--annotations` allows you to annotate class attributes' getters & setters with `@Nullable` (if the attribute is optional) or `@NonNull` (if it isn't) attributes.
|
320
|
-
This option can be combined with the `-w` wrapper flag to generate a safer and more secure code in Android Studio, generating proper warnings if misused.
|
321
|
-
|
322
|
-
<details>
|
323
|
-
<summary>📑 Sample of the generated code in Java (Android)</summary>
|
324
|
-
|
325
|
-
```java
|
326
|
-
package com.niji.data;
|
327
|
-
|
328
|
-
import io.realm.RealmObject;
|
329
|
-
import io.realm.annotations.PrimaryKey;
|
330
|
-
|
331
|
-
/* DO NOT EDIT | Generated by gyro */
|
332
|
-
|
333
|
-
public class FidelityCard extends RealmObject {
|
334
|
-
|
335
|
-
@PrimaryKey
|
336
|
-
private short identifier; // "optional" checkbox not checked in the xcdatamodel
|
337
|
-
private Integer points; // "optional" checkbox checked in the xcdatamodel
|
338
|
-
private User user;
|
339
|
-
[...]
|
340
|
-
|
341
|
-
@android.support.annotation.Nullable
|
342
|
-
public Integer getPoints() {
|
343
|
-
return points;
|
344
|
-
}
|
345
|
-
|
346
|
-
public void setPoints(@android.support.annotation.Nullable final Integer points) {
|
347
|
-
this.points = points;
|
348
|
-
}
|
349
|
-
|
350
|
-
}
|
351
|
-
```
|
352
|
-
</details>
|
353
|
-
|
354
|
-
Furthermore, it's possible to add custom annotations to your fields.
|
355
|
-
To do that, simply add the key/value pair to the UserInfos of the attribute to annotate:
|
356
|
-
|
357
|
-
| Key | Value |
|
358
|
-
|-----|-------|
|
359
|
-
| `supportAnnotation` | `AnnotationToAdd` |
|
360
|
-
|
361
|
-
|
362
|
-
__Example__: If you wish to add the `IntRange(from=0,to=255)` annotation to an attribute, use the following:
|
363
|
-
|
364
|
-
![Support Annotation](documentation/support_annotation.png)
|
365
|
-
|
366
|
-
|
367
|
-
<details>
|
368
|
-
<summary>📑 Sample of the generated code in Java (Android)</summary>
|
369
|
-
|
370
|
-
```java
|
371
|
-
package com.gyro.tests;
|
372
|
-
|
373
|
-
import io.realm.RealmObject;
|
374
|
-
|
375
|
-
/* DO NOT EDIT | Generated by gyro */
|
376
|
-
|
377
|
-
public class FidelityCard extends RealmObject {
|
378
|
-
|
379
|
-
public interface Attributes {
|
380
|
-
String IDENTIFIER = "identifier";
|
381
|
-
String POINTS = "points";
|
382
|
-
}
|
383
|
-
|
384
|
-
private short identifier;
|
385
|
-
@android.support.annotation.IntRange(from=0,to=255)
|
386
|
-
private int points;
|
387
|
-
|
388
|
-
public short getIdentifier() {
|
389
|
-
return identifier;
|
390
|
-
}
|
391
|
-
|
392
|
-
public void setIdentifier(final short identifier) {
|
393
|
-
this.identifier = identifier;
|
394
|
-
}
|
395
|
-
|
396
|
-
@android.support.annotation.IntRange(from=0,to=255)
|
397
|
-
public int getPoints() {
|
398
|
-
return points;
|
399
|
-
}
|
400
|
-
|
401
|
-
public void setPoints(@android.support.annotation.IntRange(from=0,to=255) final int points) {
|
402
|
-
this.points = points;
|
403
|
-
}
|
404
|
-
}
|
405
|
-
```
|
406
|
-
</details>
|
407
|
-
|
408
|
-
|
409
|
-
---
|
410
|
-
|
411
|
-
|
412
|
-
### Handling enums
|
413
|
-
|
414
|
-
Sometimes, an `Int` attribute in the model actually represents an `enum` member in your model. To deal with this case, you can add the following two key/value pairs to this **attribute**:
|
415
|
-
|
416
|
-
| Key | Value |
|
417
|
-
|-----|-------|
|
418
|
-
| `enumType` | `my_type` |
|
419
|
-
| `enumValues` | `my_value_1, my_value_2, my_value_3` |
|
420
|
-
|
421
|
-
> _Note: If you also add the `JSONKeyPath` User Info key to your attribute in addition to enums, you'll have to add the `JSONValues` to also tell the mapping between the `enumValues` and the matching possible values found in the JSON. See the [JSON Mapping](#json-mapping) below for more details._
|
422
|
-
|
423
|
-
__Example__: On the attribute `type` of the `Shop` entity.
|
424
|
-
|
425
|
-
![enum](documentation/enum.png)
|
426
|
-
|
427
|
-
|
428
|
-
<details>
|
429
|
-
<summary>📑 Sample of the generated code in Java (Android)</summary>
|
430
|
-
|
431
|
-
`Shop.java`:
|
432
|
-
|
433
|
-
```java
|
434
|
-
package com.niji.data;
|
435
|
-
|
436
|
-
import io.realm.RealmObject;
|
437
|
-
|
438
|
-
/* DO NOT EDIT | Generated by gyro */
|
439
|
-
|
440
|
-
public class Shop extends RealmObject {
|
441
|
-
private String name;
|
442
|
-
private Type type;
|
443
|
-
[...]
|
444
|
-
}
|
445
|
-
```
|
446
|
-
|
447
|
-
`Type.java`:
|
448
|
-
|
449
|
-
```java
|
450
|
-
package com.niji.data;
|
451
|
-
|
452
|
-
/* DO NOT EDIT | Generated by gyro */
|
453
|
-
|
454
|
-
public enum Type {
|
455
|
-
TYPE_ONE,
|
456
|
-
TYPE_TWO,
|
457
|
-
TYPE_THREE
|
458
|
-
}
|
459
|
-
```
|
460
|
-
</details>
|
461
|
-
|
462
|
-
<details>
|
463
|
-
<summary>📑 Sample of the generated code in Objective-C (iOS)</summary>
|
464
|
-
|
465
|
-
`RLMShop.h`:
|
466
|
-
|
467
|
-
```objc
|
468
|
-
// DO NOT EDIT | Generated by gyro
|
469
|
-
|
470
|
-
////////////////////////////////////////////////////////////////////////////////
|
471
|
-
|
472
|
-
#pragma mark - Imports
|
473
|
-
|
474
|
-
#import <Realm/Realm.h>
|
475
|
-
#import "RLMTypes.h"
|
476
|
-
|
477
|
-
////////////////////////////////////////////////////////////////////////////////
|
478
|
-
|
479
|
-
#pragma mark - Interface
|
480
|
-
|
481
|
-
@interface RLMShop : RLMObject
|
482
|
-
|
483
|
-
#pragma mark - Properties
|
484
|
-
|
485
|
-
@property NSString *name;
|
486
|
-
@property RLMType type;
|
487
|
-
|
488
|
-
@end
|
489
|
-
```
|
490
|
-
|
491
|
-
`RLMTypes.h`:
|
492
|
-
|
493
|
-
```objc
|
494
|
-
// DO NOT EDIT | Generated by gyro
|
495
|
-
|
496
|
-
////////////////////////////////////////////////////////////////////////////////
|
497
|
-
|
498
|
-
#pragma mark - Types
|
499
|
-
|
500
|
-
typedef NS_ENUM(int, RLMType) {
|
501
|
-
RLMTypeOne = 0,
|
502
|
-
RLMTypeTwo,
|
503
|
-
RLMTypeThree
|
504
|
-
};
|
505
|
-
```
|
506
|
-
</details>
|
507
|
-
|
508
|
-
<details>
|
509
|
-
<summary>📑 Sample of the generated code in Swift (iOS)</summary>
|
510
|
-
|
511
|
-
`Shop.swift`:
|
512
|
-
|
513
|
-
```swift
|
514
|
-
/* DO NOT EDIT | Generated by gyro */
|
515
|
-
|
516
|
-
import RealmSwift
|
517
|
-
|
518
|
-
final class Shop: Object {
|
519
|
-
|
520
|
-
enum Attributes: String {
|
521
|
-
case Name = "name"
|
522
|
-
case OptionalValue = "optionalValue"
|
523
|
-
case Type = "type"
|
524
|
-
}
|
525
|
-
|
526
|
-
dynamic var name: String = ""
|
527
|
-
dynamic var optionalValue: String? = nil
|
528
|
-
var optionalValueEnum: OptValue? {
|
529
|
-
get {
|
530
|
-
guard let optionalValue = optionalValue,
|
531
|
-
let enumValue = OptValue(rawValue: optionalValue)
|
532
|
-
else { return nil }
|
533
|
-
return enumValue
|
534
|
-
}
|
535
|
-
set { optionalValue = newValue?.rawValue ?? nil }
|
536
|
-
}
|
537
|
-
|
538
|
-
dynamic var type: String = ""
|
539
|
-
var typeEnum: Type? {
|
540
|
-
get {
|
541
|
-
guard let enumValue = Type(rawValue: type) else { return nil }
|
542
|
-
return enumValue
|
543
|
-
}
|
544
|
-
set { type = newValue?.rawValue ?? "" }
|
545
|
-
}
|
546
|
-
}
|
547
|
-
```
|
548
|
-
|
549
|
-
`Type.swift`:
|
550
|
-
|
551
|
-
```swift
|
552
|
-
/* DO NOT EDIT | Generated by gyro */
|
553
|
-
|
554
|
-
enum Type: String {
|
555
|
-
case TypeOne = "type_one"
|
556
|
-
case TypeTwo = "type_two"
|
557
|
-
case TypeThree = "type_three"
|
558
|
-
}
|
559
|
-
```
|
560
|
-
|
561
|
-
`OptValue.swift`
|
562
|
-
|
563
|
-
```swift
|
564
|
-
/* DO NOT EDIT | Generated by gyro */
|
565
|
-
|
566
|
-
enum OptValue: String {
|
567
|
-
case OptValueOne = "opt_value_one"
|
568
|
-
case OptValueTwo = "opt_value_two"
|
569
|
-
case OptValueThree = "opt_value_three"
|
570
|
-
}
|
571
|
-
```
|
572
|
-
</details>
|
573
|
-
|
574
|
-
> **Note**: For Android and Swift, each enum is created in a separate file. For ObjC, all the enums are created in the file RLMTypes.h
|
575
|
-
|
576
|
-
|
577
|
-
---
|
578
|
-
|
579
|
-
|
580
|
-
### Add comments to the generated classes
|
581
|
-
|
582
|
-
To make the generated code more readable, it's possible to add comments on an entity — e.g. to provide a short description of what this entity is supposed to represent.
|
583
|
-
|
584
|
-
To do so, simply add the following key/value pair to your **entity** in your `.xcdatamodel`:
|
585
|
-
|
586
|
-
| Key | Value |
|
587
|
-
|-----|-------|
|
588
|
-
| `comment` | `the_comment_text_here` |
|
589
|
-
|
590
|
-
A code commend (`/** … */`) will then be generated (in the `.h` (ObjC), `.swift` (Swift) or `.java` (Android)) just before the class declaration, e.g. to help the developer understand what this class is for.
|
591
|
-
|
592
|
-
|
593
|
-
---
|
594
|
-
|
595
|
-
|
596
|
-
### JSON Mapping
|
597
|
-
|
598
|
-
You can also add the json mapping for each **attribute** or **relationship** with the following key/value pair:
|
599
|
-
|
600
|
-
| Key | Value |
|
601
|
-
|-----|-------|
|
602
|
-
| `JSONKeyPath` | `json_field_name` |
|
603
|
-
|
604
|
-
This key is only used when using the `--json` flag.
|
605
|
-
|
606
|
-
Currently, this will then generate:
|
607
|
-
|
608
|
-
* Code for `ObjectMapper` on iOS (in the future we plan to generate `Sourcery` annotations instead so that people can choose whatever JSON library they prefer).
|
609
|
-
* `GSON` annotations (`@SerializedName(…)`) for Android
|
610
|
-
|
611
|
-
__Example__: On the 'name' attribute of the 'Shop' entity:
|
612
|
-
|
613
|
-
![JSONKeyPath](documentation/json.png)
|
614
|
-
|
615
|
-
|
616
|
-
<details>
|
617
|
-
<summary>📑 Sample of the generated code in Java (Android)</summary>
|
618
|
-
|
619
|
-
Sur Android, nous utilisons la librairie GSON
|
620
|
-
|
621
|
-
```java
|
622
|
-
package com.niji.data;
|
623
|
-
|
624
|
-
import com.google.gson.annotations.SerializedName;
|
625
|
-
|
626
|
-
import io.realm.RealmList;
|
627
|
-
import io.realm.RealmObject;
|
628
|
-
|
629
|
-
/* DO NOT EDIT | Generated by gyro */
|
630
|
-
|
631
|
-
public class Shop extends RealmObject {
|
632
|
-
|
633
|
-
@SerializedName("json_name")
|
634
|
-
private String name;
|
635
|
-
private RealmList<Product> products;
|
636
|
-
[...]
|
637
|
-
}
|
638
|
-
```
|
639
|
-
</details>
|
640
|
-
|
641
|
-
<details>
|
642
|
-
<summary>📑 Sample of the generated code in Objective-C (iOS)</summary>
|
643
|
-
|
644
|
-
On iOS, we use the Realm-JSON library and generate them in `MyEntity+JSON.m` category files.
|
645
|
-
|
646
|
-
`RLMShop+JSON.m`:
|
647
|
-
|
648
|
-
```objc
|
649
|
-
// DO NOT EDIT | Generated by gyro
|
650
|
-
|
651
|
-
////////////////////////////////////////////////////////////////////////////////
|
652
|
-
|
653
|
-
#pragma mark - Imports
|
654
|
-
|
655
|
-
#import "RLMShop+JSON.h"
|
656
|
-
|
657
|
-
////////////////////////////////////////////////////////////////////////////////
|
658
|
-
|
659
|
-
#pragma mark - Implementation
|
660
|
-
|
661
|
-
@implementation RLMShop (JSON)
|
662
|
-
|
663
|
-
+ (NSDictionary *)JSONInboundMappingDictionary
|
664
|
-
{
|
665
|
-
return @{
|
666
|
-
@"json_name" : @"name"
|
667
|
-
};
|
668
|
-
}
|
669
|
-
|
670
|
-
+ (NSDictionary *)JSONOutboundMappingDictionary
|
671
|
-
{
|
672
|
-
return @{
|
673
|
-
@"name" : @"json_name"
|
674
|
-
};
|
675
|
-
}
|
676
|
-
|
677
|
-
@end
|
678
|
-
```
|
679
|
-
</details>
|
680
|
-
|
681
|
-
#### Combine JSONKeyPath and enums
|
682
|
-
|
683
|
-
Note that you can **combine that `JSONKeyPath` key with enums** (see [Handling enums](#handling-enums) above). If you declared the User Info keys to make your attribute an enum (`enumType` + `enumValues`) in addition to `JSONKeyPath`, you'll have to also add the `JSONValues` key to list the corresponding values in the JSON for those `enumValues`.
|
684
|
-
|
685
|
-
| Key | Value |
|
686
|
-
|-----|-------|
|
687
|
-
| `JSONValues` | `valeur_json_1,valeur_json_2,valeur_json_3` |
|
688
|
-
|
689
|
-
The number of items listed for that `JSONValues` key must be the same as the number of items listed for the `enumValues` keys, obviously.
|
690
|
-
|
691
|
-
__Example__:
|
692
|
-
|
693
75
|
![enum_json](documentation/enum_json.png)
|
694
76
|
|
77
|
+
With the help of these "user infos", you will be able to give Gyro extra information about your model classes. For example, you can tell which attribute is the primary key, the attributes to ignore, the JSON mappings, …
|
695
78
|
|
696
|
-
|
697
|
-
<summary>📑 Sample of the generated code in Java (Android)</summary>
|
698
|
-
|
699
|
-
```java
|
700
|
-
package com.niji.data;
|
701
|
-
|
702
|
-
import com.google.gson.annotations.SerializedName;
|
703
|
-
|
704
|
-
/* DO NOT EDIT | Generated by gyro */
|
705
|
-
|
706
|
-
public enum Type {
|
707
|
-
|
708
|
-
@SerializedName("json_type_one")TYPE_ONE,
|
709
|
-
@SerializedName("json_type_two")TYPE_TWO,
|
710
|
-
@SerializedName("json_type_three")TYPE_THREE
|
711
|
-
}
|
712
|
-
```
|
713
|
-
</details>
|
714
|
-
|
715
|
-
<details>
|
716
|
-
<summary>📑 Sample of the generated code in Objective-C (iOS)</summary>
|
717
|
-
|
718
|
-
`RLMShop+JSON.m`:
|
719
|
-
|
720
|
-
```objc
|
721
|
-
// DO NOT EDIT | Generated by gyro
|
722
|
-
|
723
|
-
////////////////////////////////////////////////////////////////////////////////
|
724
|
-
|
725
|
-
#pragma mark - Imports
|
726
|
-
|
727
|
-
#import "RLMShop+JSON.h"
|
728
|
-
#import "RLMTypes.h"
|
729
|
-
|
730
|
-
////////////////////////////////////////////////////////////////////////////////
|
731
|
-
|
732
|
-
#pragma mark - Implementation
|
733
|
-
|
734
|
-
@implementation RLMShop (JSON)
|
735
|
-
|
736
|
-
+ (NSValueTransformer *)typeJSONTransformer
|
737
|
-
{
|
738
|
-
return [MCJSONValueTransformer valueTransformerWithMappingDictionary:@{
|
739
|
-
@"json_type_one" : @(RLMTypeOne),
|
740
|
-
@"json_type_two" : @(RLMTypeTwo),
|
741
|
-
@"json_type_three" : @(RLMTypeThree)
|
742
|
-
}];
|
743
|
-
}
|
744
|
-
|
745
|
-
@end
|
746
|
-
```
|
747
|
-
</details>
|
748
|
-
|
749
|
-
|
750
|
-
---
|
751
|
-
|
752
|
-
|
753
|
-
### Custom ValueTransformers
|
754
|
-
|
755
|
-
Only available on iOS (as Android uses the GSON library), custom `ValueTransformers` allows you to e.g. convrt a `String` into an `Int` or a `Date` when parsing the JSON. They are only used when using the `--json` flag.
|
756
|
-
|
757
|
-
To create a specific `ValueTransformer` for a field:
|
758
|
-
|
759
|
-
* Create your `ValueTransformer` custom class inheriting `NSValueTransformer` and add it to your project
|
760
|
-
* Select the attribute that will need this transformer, and in the UserInfo field, add a pair for the **transformer** key whose value should be the name of the `ValueTransformer` class to use:
|
761
|
-
|
762
|
-
| Key | Value |
|
763
|
-
|-----|-------|
|
764
|
-
| `transformer` | `NameOfTheTransformerClass` |
|
765
|
-
|
766
|
-
__Example__:
|
767
|
-
|
768
|
-
![transformer](documentation/transformer.png)
|
769
|
-
|
770
|
-
|
771
|
-
<details>
|
772
|
-
<summary>📑 Sample of the generated code in Objective-C (iOS)</summary>
|
773
|
-
|
774
|
-
`gyro` will produce the following code. (In this example, attributes `attrDouble` and `attrInteger32` don't have a **transformer** key set in their UserInfo).
|
775
|
-
|
776
|
-
```objc
|
777
|
-
// DO NOT EDIT | Generated by gyro
|
778
|
-
|
779
|
-
////////////////////////////////////////////////////////////////////////////////
|
780
|
-
|
781
|
-
#pragma mark - Imports
|
782
|
-
|
783
|
-
#import "RLMShop+JSON.h"
|
784
|
-
#import "MPDecimalTransformer.h"
|
785
|
-
#import "MPIntegerTransformer.h"
|
786
|
-
|
787
|
-
////////////////////////////////////////////////////////////////////////////////
|
788
|
-
|
789
|
-
#pragma mark - Implementation
|
790
|
-
|
791
|
-
@implementation RLMShop (JSON)
|
792
|
-
|
793
|
-
+ (NSDictionary *)JSONInboundMappingDictionary
|
794
|
-
{
|
795
|
-
return @{
|
796
|
-
@"attrDecimal" : @"attrDecimal",
|
797
|
-
@"attrDouble" : @"attrDouble",
|
798
|
-
@"attrFloat" : @"attrFloat",
|
799
|
-
@"attrInteger16" : @"attrInteger16",
|
800
|
-
@"attrInteger32" : @"attrInteger32",
|
801
|
-
@"attrInteger64" : @"attrInteger64"
|
802
|
-
};
|
803
|
-
}
|
804
|
-
|
805
|
-
+ (NSDictionary *)JSONOutboundMappingDictionary
|
806
|
-
{
|
807
|
-
return @{
|
808
|
-
@"attrDecimal" : @"attrDecimal",
|
809
|
-
@"attrDouble" : @"attrDouble",
|
810
|
-
@"attrFloat" : @"attrFloat",
|
811
|
-
@"attrInteger16" : @"attrInteger16",
|
812
|
-
@"attrInteger32" : @"attrInteger32",
|
813
|
-
@"attrInteger64" : @"attrInteger64"
|
814
|
-
};
|
815
|
-
}
|
816
|
-
|
817
|
-
+ (NSValueTransformer *)attrDecimalJSONTransformer
|
818
|
-
{
|
819
|
-
return [[MPDecimalTransformer alloc] init];
|
820
|
-
}
|
821
|
-
|
822
|
-
+ (NSValueTransformer *)attrFloatJSONTransformer
|
823
|
-
{
|
824
|
-
return [[MPDecimalTransformer alloc] init];
|
825
|
-
}
|
826
|
-
|
827
|
-
+ (NSValueTransformer *)attrInteger16JSONTransformer
|
828
|
-
{
|
829
|
-
return [[MPIntegerTransformer alloc] init];
|
830
|
-
}
|
79
|
+
**For more information about "user infos", you can see the dedicated documentation [here](USER-INFO.md).**
|
831
80
|
|
832
|
-
|
833
|
-
{
|
834
|
-
return [[MPIntegerTransformer alloc] init];
|
835
|
-
}
|
81
|
+
## License
|
836
82
|
|
837
|
-
|
83
|
+
This tool is under [the Apache 2 License](LICENSE).
|
838
84
|
|
839
|
-
|
840
|
-
</details>
|
85
|
+
It has been initially developed by [Niji](http://www.niji.fr) and is in no way affiliated to the [Realm](https://realm.io) company.
|