@@ -27,7 +27,12 @@ typealias GenerateFileComplete = (Bool, String) -> ()
27
27
class SKCodeBuilder : NSObject {
28
28
29
29
var config = SKCodeBuilderConfig ( )
30
-
30
+ lazy var handleDicts = NSMutableDictionary ( )
31
+ lazy var yymodelPropertyGenericClassDicts = NSMutableDictionary ( )
32
+ lazy var handlePropertyMapper = NSMutableDictionary ( )
33
+
34
+ // MARK: - Public
35
+
31
36
func build_OC_code( with jsonObj: Any , complete: BuildComplete ? ) {
32
37
let hString = NSMutableString ( )
33
38
let mString = NSMutableString ( )
@@ -41,34 +46,263 @@ class SKCodeBuilder: NSObject {
41
46
42
47
}
43
48
49
+ // MARK: - Private Handler
50
+
44
51
private func handleDictValue( dictValue: Any , key: String , hString: NSMutableString , mString: NSMutableString ) {
45
52
46
53
if key. isBlank { // Root model
47
- let modeName = modelName ( with: key)
54
+ hString. append ( " \n \n @interface \( self . config. rootModelName) : \( self . config. superClassName) \n \n " )
55
+ mString. append ( " \n \n @implementation \( self . config. rootModelName) \n \n " )
56
+
57
+ } else { // sub model
58
+ let modeName = modelClassName ( with: key)
48
59
hString. append ( " \n \n @interface \( modeName) : \( self . config. superClassName) \n \n " )
49
60
mString. append ( " \n \n @implementation \( modeName) \n \n " )
61
+ }
62
+
63
+ switch dictValue {
64
+
65
+ case let array as [ Any ] :
66
+
67
+ handleArrayValue ( arrayValue: array, key: " dataList " , hString: hString)
68
+
69
+ case let dict as [ String : Any ] :
70
+
71
+ dict. forEach { ( key, value) in
72
+
73
+ switch value {
74
+
75
+ case _ as NSNumber :
76
+
77
+ handleIdNumberValue ( numValue: value as! NSNumber , key: key, hString: hString, ignoreIdValue: config. jsonType == . none)
78
+
79
+ case _ as String :
80
+
81
+ handleIdStringValue ( idValue: value as! String , key: key, hString: hString, ignoreIdValue: config. jsonType == . none)
82
+
83
+ case _ as [ String : Any ] :
84
+
85
+ let modelName = modelClassName ( with: key)
86
+ hString. append ( " /** \(key) */\n @property (nonatomic, strong) \( modelName) * \( key) ; \n " )
87
+
88
+ self . yymodelPropertyGenericClassDicts. setValue ( modelName, forKey: key)
89
+ self . handleDicts. setValue ( value, forKey: key)
90
+
91
+ case let arr as [ Any ] :
92
+
93
+ handleArrayValue ( arrayValue: arr, key: key, hString: hString)
94
+
95
+ default :
96
+ // 识别不出类型
97
+ hString. append ( " /** <识别不出类型#> */\n @property (nonatomic, strong) id \( key) ; \n " )
98
+ }
99
+ }
100
+
101
+ default :
102
+ hString. append ( " \n @end \n \n " )
103
+ mString. append ( " \n @end \n \n " )
104
+ return
105
+ }
106
+
107
+ hString. append ( " \n @end \n \n " )
108
+
109
+ handleJsonType ( hString: hString, mString: mString)
110
+
111
+ if !key. isBlank {
112
+ self . handleDicts. removeObject ( forKey: key)
113
+ }
114
+ mString. append ( " \n @end \n \n " )
50
115
51
- } else { // sub model
52
- hString. append ( " \n \n @interface \( self . config. rootModelName) : \( self . config. superClassName) \n \n " )
53
- mString. append ( " \n \n @implementation \( self . config. rootModelName) \n \n " )
116
+ self . yymodelPropertyGenericClassDicts. removeAllObjects ( )
117
+ self . handlePropertyMapper. removeAllObjects ( )
118
+
119
+ if self . handleDicts. count > 0 {
120
+ let firstKey = self . handleDicts. allKeys. first as! String
121
+ if let firstObject = self . handleDicts. value ( forKey: firstKey) {
122
+ handleDictValue ( dictValue: firstObject, key: firstKey, hString: hString, mString: mString)
123
+ }
124
+ }
125
+ }
126
+
127
+ private func handleArrayValue( arrayValue: [ Any ] , key: String , hString: NSMutableString ) {
128
+
129
+ guard arrayValue. count > 0 else {
130
+ return
131
+ }
132
+ if let firstObject = arrayValue. first {
133
+
134
+ if firstObject is String {
135
+ // String 类型
136
+ hString. append ( " /** \(key) */\n @property (nonatomic, strong) NSArray <NSString *> * \( key) ; \n " )
137
+ }
138
+ else if ( firstObject is [ String : Any ] ) {
139
+ // Dictionary 类型
140
+ let modeName = modelClassName ( with: key)
141
+ self . handleDicts. setValue ( firstObject, forKey: key)
142
+ self . yymodelPropertyGenericClassDicts. setValue ( modeName, forKey: key)
143
+ hString. append ( " /** \(key) */\n @property (nonatomic, strong) NSArray < \( modeName) *> * \( key) ; \n " )
144
+ }
145
+ else if ( firstObject is [ Any ] ) {
146
+ // Array 类型
147
+ handleArrayValue ( arrayValue: firstObject as! [ Any ] , key: key, hString: hString)
148
+ }
149
+ else {
150
+ hString. append ( " /** \(key) */\n @property (nonatomic, strong) NSArray * \( key) ; \n " )
151
+ }
54
152
}
55
153
}
56
154
57
- private func modelName( with key: String ) -> String {
155
+ private func handleIdNumberValue( numValue: NSNumber , key: String , hString: NSMutableString , ignoreIdValue: Bool ) {
156
+
157
+ // let type = numValue.objCType
158
+
159
+ let numType = CFNumberGetType ( numValue as CFNumber )
160
+
161
+ switch numType {
162
+
163
+ case . doubleType, . floatType, . float32Type, . float64Type, . cgFloatType:
164
+ /// 浮点型
165
+ hString. append ( " /** eg. \(numValue) */\n @property (nonatomic, assign) CGFloat \( key) ; \n " )
166
+
167
+ case . charType:
168
+ if numValue. int32Value == 0 || numValue. int32Value == 1 {
169
+ /// Bool 类型
170
+ hString. append ( " /** eg. \(numValue) */\n @property (nonatomic, assign) BOOL \( key) ; \n " )
171
+
172
+ } else {
173
+ handleIdStringValue ( idValue: numValue. stringValue, key: key, hString: hString, ignoreIdValue: ignoreIdValue)
174
+ }
175
+
176
+ case . longType, . longLongType:
177
+ /// Int
178
+ hString. append ( " /** eg. \(numValue) */\n @property (nonatomic, assign) NSInteger \( key) ; \n " )
179
+
180
+ /// Int
181
+ case . shortType, . intType, . sInt32Type, . nsIntegerType:
182
+
183
+ hString. append ( " /** eg. \(numValue) */\n @property (nonatomic, assign) NSInteger itemId; \n " )
184
+
185
+ default :
186
+ /// Int
187
+ if key == " id " && !ignoreIdValue {
188
+ self . handlePropertyMapper. setValue ( " id " , forKey: " itemId " )
189
+ hString. append ( " /** eg. \(numValue) */\n @property (nonatomic, assign) NSInteger itemId; \n " )
190
+
191
+ } else {
192
+ hString. append ( " /** eg. \(numValue) */\n @property (nonatomic, assign) NSInteger \( key) ; \n " )
193
+ }
194
+ }
195
+ }
196
+
197
+ private func handleIdStringValue( idValue: String , key: String , hString: NSMutableString , ignoreIdValue: Bool ) {
198
+
199
+ if key == " id " && !ignoreIdValue {
200
+ self . handlePropertyMapper. setValue ( " id " , forKey: " itemId " )
201
+ hString. append ( " /** eg. \(idValue) */\n @property (nonatomic, copy) NSString itemId; \n " )
202
+ } else {
203
+ if hString. length > 12 {
204
+ hString. append ( " /** eg. \(key) */\n @property (nonatomic, assign) NSInteger \( key) ; \n " )
205
+ } else {
206
+ hString. append ( " /** eg. \(idValue) */\n @property (nonatomic, assign) NSInteger \( key) ; \n " )
207
+ }
208
+ }
209
+ }
210
+
211
+ /// 处理json解析
212
+
213
+ private func handleJsonType( hString: NSMutableString , mString: NSMutableString ) {
214
+
215
+ switch config. jsonType {
216
+ case . YYModel:
217
+ // 适配YYModel
218
+
219
+ /// 1.The generic class mapper for container properties.
220
+
221
+ var needLineBreak = false ;
222
+ if ( self . yymodelPropertyGenericClassDicts. count > 0 ) {
223
+ mString. append ( " + (NSDictionary<NSString *,id> *)modelContainerPropertyGenericClass \n " )
224
+ mString. append ( " { \n return @{ \n " )
225
+ for (key, obj) in self . yymodelPropertyGenericClassDicts {
226
+ mString. append ( " @ \" \( key) \" : \( obj) .class, \n " )
227
+ }
228
+ mString. append ( " }; " )
229
+ mString. append ( " \n } \n " )
230
+ needLineBreak = true ;
231
+ }
232
+
233
+ /// 2.Custom property mapper.
234
+
235
+ if ( self . handlePropertyMapper. count > 0 ) {
236
+ if ( needLineBreak) {
237
+ mString. append ( " \n " )
238
+ }
239
+
240
+ mString. append ( " + (nullable NSDictionary<NSString *, id> *)modelCustomPropertyMapper \n " )
241
+ mString. append ( " { \n return @{ \n " )
242
+ for (key, obj) in self . handlePropertyMapper {
243
+ mString. append ( " @ \" \( key) \" : @ \" \( obj) \" , \n " )
244
+ }
245
+ mString. append ( " }; " )
246
+ mString. append ( " \n } \n " )
247
+ }
248
+
249
+ case . MJExtension:
250
+ // 适配MJExtension
251
+
252
+ /// 1.The generic class mapper for container properties.
253
+
254
+ var needLineBreak = false ;
255
+ if ( self . yymodelPropertyGenericClassDicts. count > 0 ) {
256
+ mString. append ( " + (NSDictionary *)mj_objectClassInArray \n " )
257
+ mString. append ( " { \n return @{ \n " )
258
+ for (key, obj) in self . yymodelPropertyGenericClassDicts {
259
+ mString. append ( " @ \" \( key) \" : \( obj) .class, \n " )
260
+ }
261
+ mString. append ( " }; " )
262
+ mString. append ( " \n } \n " )
263
+ needLineBreak = true ;
264
+ }
265
+
266
+ /// 2.Custom property mapper.
267
+
268
+ if ( self . handlePropertyMapper. count > 0 ) {
269
+ if ( needLineBreak) {
270
+ mString. append ( " \n " )
271
+ }
272
+
273
+ mString. append ( " + (NSDictionary *)mj_replacedKeyFromPropertyName \n " )
274
+ mString. append ( " { \n return @{ \n " )
275
+ for (key, obj) in self . handlePropertyMapper {
276
+ mString. append ( " @ \" \( key) \" : @ \" \( obj) \" , \n " )
277
+ }
278
+ mString. append ( " }; " )
279
+ mString. append ( " \n } \n " )
280
+ }
281
+
282
+ default :
283
+ break
284
+ }
285
+ }
286
+
287
+ /// 生成类名
288
+
289
+ private func modelClassName( with key: String ) -> String {
58
290
if key. isBlank { return config. rootModelName }
59
291
let firstCharacterIndex = key. index ( key. startIndex, offsetBy: 1 )
60
- var firstCharacter = String ( key [ ... firstCharacterIndex] )
292
+ var firstCharacter = String ( key [ ..< firstCharacterIndex] )
61
293
firstCharacter = firstCharacter. uppercased ( )
62
294
let start = String . Index. init ( utf16Offset: 0 , in: key)
63
295
let end = String . Index. init ( utf16Offset: 1 , in: key)
64
296
var modelName = key. replacingCharacters ( in: start..< end, with: firstCharacter)
65
297
if !modelName. hasPrefix ( config. modelNamePrefix) {
66
- modelName = config. modelNamePrefix + key
298
+ modelName = config. modelNamePrefix + modelName
67
299
}
68
300
return modelName
69
301
}
70
302
}
71
303
304
+ // MARK: - Config
305
+
72
306
class SKCodeBuilderConfig : NSObject {
73
307
var superClassName = " NSObject "
74
308
var rootModelName = " NSRootModel "
@@ -108,3 +342,4 @@ extension String {
108
342
return nil
109
343
}
110
344
}
345
+
0 commit comments