@regulaforensics/face-sdk 8.2.804-nightly → 8.2.812-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,934 @@
1
+ import FaceSDK
2
+ import FaceSDK.Private
3
+ import UIKit
4
+
5
+ // MARK: - Init
6
+
7
+ // No decode and no tests for FaceSDKVersion because of the way its implemented.
8
+ public extension RFSFaceSDKVersion {
9
+ func encode() -> [String: Any?] {
10
+ return [
11
+ "api": self.api,
12
+ "core": self.core,
13
+ "coreMode": self.coreMode,
14
+ ]
15
+ }
16
+ }
17
+
18
+
19
+ public extension Error {
20
+ func encode() -> [String: Any?] {
21
+ guard let it = self as NSError? else { return [:] }
22
+ var result: [String: Any?] = [
23
+ "code": it.code,
24
+ "message": it.localizedDescription
25
+ ]
26
+ if let temp = it.userInfo[NSUnderlyingErrorKey] as? NSError {
27
+ if let underlying = temp.userInfo[NSUnderlyingErrorKey] as? BackendError {
28
+ result["underlyingError"] = [
29
+ "code": underlying.code,
30
+ "message": underlying.userInfo[BackendError.OriginalMessageKey]
31
+ ]
32
+ }
33
+ }
34
+ return result
35
+ }
36
+ }
37
+
38
+ func generateInitCompletion(_ success: Bool, _ error: Error?) -> [String: Any?] {
39
+ return [
40
+ "success": success,
41
+ "error": error?.encode()
42
+ ]
43
+ }
44
+
45
+ public extension InitializationConfiguration {
46
+ static func decode(_ it: Any?) -> Self? {
47
+ guard let it = it as? [String: Any] else { return nil }
48
+ return Self(builder: { builder in
49
+ builder.licenseData = Data.decode(it["license"])!
50
+ if let prop = it["licenseUpdate"] as? Bool { builder.licenseUpdate = prop }
51
+ })
52
+ }
53
+ func encode() -> [String: Any?] {
54
+ return [
55
+ "license": self.licenseData.encode(),
56
+ "licenseUpdate": self.licenseUpdate,
57
+ ]
58
+ }
59
+ }
60
+
61
+ func generateVideoEncoderCompletion(_ success: Bool, _ transactionId: String) -> [String: Any?] {
62
+ return [
63
+ "success": success,
64
+ "transactionId": transactionId
65
+ ]
66
+ }
67
+
68
+ // MARK: - FaceCapture
69
+
70
+ public extension Image {
71
+ static func decode(_ it: Any?) -> Self? {
72
+ guard let it = it as? [String: Any] else { return nil }
73
+ let result = Self(
74
+ image: UIImage.decode(it["image"])!,
75
+ type: ImageType(rawValue: it["imageType"] as! Int)!)
76
+ result.setValue(it["tag"] as! String, forKey: "identifier")
77
+ return result
78
+ }
79
+ func encode() -> [String: Any?] {
80
+ return [
81
+ "imageType": self.imageType.rawValue,
82
+ "image": self.image.encode(),
83
+ "tag": self.identifier,
84
+ ]
85
+ }
86
+ }
87
+
88
+ public extension FaceCaptureResponse {
89
+ static func decode(_ it: Any?) -> Self {
90
+ let it = it as! [String: Any]
91
+ let alloc = FaceCaptureResponse.allocate()
92
+ let sel = "initWithImage:error:".selector()
93
+ return privateInit(alloc, sel, (@convention(c)(
94
+ Any, Selector,
95
+ Any?, Any?) -> Unmanaged<AnyObject>?).self, { f in f(
96
+ alloc, sel,
97
+ Image.decode(it["image"]),
98
+ nil,
99
+ )})
100
+ }
101
+ func encode() -> [String: Any?] {
102
+ return [
103
+ "image": self.image?.encode(),
104
+ "error": self.error?.encode(),
105
+ ]
106
+ }
107
+ }
108
+
109
+ // MARK: - Liveness
110
+
111
+ public extension LivenessResponse {
112
+ static func decode(_ it: Any?) -> Self {
113
+ let it = it as! [String: Any]
114
+ let alloc = LivenessResponse.allocate()
115
+ let sel = "initWithTag:transactionId:estimatedAge:status:image:error:".selector()
116
+ return privateInit(alloc, sel, (@convention(c)(
117
+ AnyObject, Selector,
118
+ Any?, Any?, Any?, Int, Any?, Any?) -> Unmanaged<AnyObject>?).self, { f in f(
119
+ alloc, sel,
120
+ it["tag"],
121
+ it["transactionId"],
122
+ it["estimatedAge"],
123
+ it["liveness"] as! Int,
124
+ UIImage.decode(it["image"]),
125
+ nil,
126
+ )})
127
+ }
128
+ func encode() -> [String: Any?] {
129
+ return [
130
+ "image": self.image?.encode(),
131
+ "liveness": self.liveness.rawValue,
132
+ "error": self.error?.encode(),
133
+ "estimatedAge": self.estimatedAge,
134
+ "tag": self.tag,
135
+ "transactionId": self.transactionId,
136
+ ]
137
+ }
138
+ }
139
+
140
+ func generateLivenessNotification(_ status: LivenessProcessStatus, _ result: LivenessResponse?) -> [String: Any?] {
141
+ return [
142
+ "status": status.rawValue,
143
+ "result": result?.encode()
144
+ ]
145
+ }
146
+
147
+ // MARK: - MatchFacesRequest
148
+
149
+ public extension MatchFacesImage {
150
+ static func decode(_ it: Any?) -> Self? {
151
+ guard let it = it as? [String: Any] else { return nil }
152
+ let result = Self(image: UIImage.decode(it["image"])!,
153
+ imageType: ImageType(rawValue: it["imageType"] as! Int)!,
154
+ detectAll: it["detectAll"] as? Bool ?? false)
155
+ result.setValue(it["identifier"] as! String, forKey: "identifier")
156
+ return result
157
+ }
158
+ func encode() -> [String: Any?] {
159
+ return [
160
+ "image": self.image.encode(),
161
+ "imageType": self.imageType.rawValue,
162
+ "detectAll": self.detectAll,
163
+ "identifier": self.identifier,
164
+ ]
165
+ }
166
+ }
167
+
168
+ public extension CGSize {
169
+ static func decode(_ it: Any?) -> Self {
170
+ guard let it = it as? [String: Any] else { return .zero }
171
+ return Self(width: CGFloat(it["width"] as! Float),
172
+ height: CGFloat(it["height"] as! Float))
173
+ }
174
+ func encode() -> [String: Any?]? {
175
+ if self == .zero { return nil }
176
+ if self == CGSizeMake(60, 80) { return nil } // this is default size that is created in sdk if you pass null
177
+ return [
178
+ "width": self.width,
179
+ "height": self.height,
180
+ ]
181
+ }
182
+ }
183
+
184
+ public extension OutputImageCrop {
185
+ static func decode(_ it: Any?) -> Self? {
186
+ guard let it = it as? [String: Any] else { return nil }
187
+ return Self(type: AspectRatio(rawValue: it["type"] as! UInt)!,
188
+ size: CGSize.decode(it["size"]),
189
+ padColor: UIColor.decode(it["padColor"]),
190
+ returnOriginalRect: it["returnOriginalRect"] as? Bool ?? false)
191
+ }
192
+ func encode() -> [String: Any?] {
193
+ return [
194
+ "type": self.type.rawValue,
195
+ "size": self.size.encode(),
196
+ "padColor": self.padColor?.encode(),
197
+ "returnOriginalRect": self.returnOriginalRect,
198
+ ]
199
+ }
200
+ }
201
+
202
+ public extension OutputImageParams {
203
+ static func decode(_ it: Any?) -> Self? {
204
+ guard let it = it as? [String: Any] else { return nil }
205
+ let result = Self()
206
+ result.backgroundColor = UIColor.decode(it["backgroundColor"]);
207
+ result.crop = OutputImageCrop.decode(it["crop"]);
208
+ return result
209
+ }
210
+ func encode() -> [String: Any?] {
211
+ return [
212
+ "backgroundColor": self.backgroundColor?.encode(),
213
+ "crop": self.crop?.encode(),
214
+ ]
215
+ }
216
+ }
217
+
218
+ public extension MatchFacesRequest {
219
+ static func decode(_ it: Any?) -> Self {
220
+ let it = it as! [String: Any]
221
+ let result = Self(images: (it["images"] as! [[String: Any?]]).compactMap { MatchFacesImage.decode($0) })
222
+ result.metadata = it["metadata"] as? [String: Any]
223
+ result.tag = it["tag"] as? String
224
+ result.outputImageParams = OutputImageParams.decode(it["outputImageParams"])
225
+ return result
226
+ }
227
+ func encode() -> [String: Any?] {
228
+ return [
229
+ "images": self.images.map { $0.encode() },
230
+ "metadata": self.metadata,
231
+ "tag": self.tag,
232
+ "outputImageParams": self.outputImageParams?.encode(),
233
+ ]
234
+ }
235
+ }
236
+
237
+ // MARK: - MatchFacesResponse
238
+
239
+ public extension Point {
240
+ static func decode(_ it: Any?) -> Self {
241
+ let it = it as! [String: Any]
242
+ return Self(x: CGFloat(it["x"] as! Float),
243
+ y: CGFloat(it["y"] as! Float))
244
+ }
245
+ func encode() -> [String: Any?] {
246
+ return [
247
+ "x": self.x,
248
+ "y": self.y,
249
+ ]
250
+ }
251
+ }
252
+
253
+ public extension CGRect {
254
+ static func decode(_ it: Any?) -> Self {
255
+ guard let it = it as? [String: Any] else { return .null }
256
+ return Self(x: CGFloat(it["left"] as! Float),
257
+ y: CGFloat(it["top"] as! Float),
258
+ width: CGFloat(it["right"] as! Float) - CGFloat(it["left"] as! Float),
259
+ height: CGFloat(it["bottom"] as! Float) - CGFloat(it["top"] as! Float))
260
+ }
261
+ func encode() -> [String: Any?]? {
262
+ if self == .null { return nil }
263
+ return [
264
+ "top": self.origin.y,
265
+ "left": self.origin.x,
266
+ "bottom": self.origin.y + self.size.height,
267
+ "right": self.origin.x + self.size.width,
268
+ ]
269
+ }
270
+ }
271
+
272
+ public extension MatchFacesDetectionFace {
273
+ static func decode(_ it: Any?) -> Self? {
274
+ guard let it = it as? [String: Any] else { return nil }
275
+ return Self(faceIndex: it["faceIndex"] as! NSNumber,
276
+ landmarks: (it["landmarks"] as! [[String: Any?]]).compactMap { Point.decode($0) },
277
+ face: CGRect.decode(it["faceRect"]),
278
+ rotationAngle: it["rotationAngle"] as? NSNumber,
279
+ thumbnailImage: UIImage.decode(it["thumbnailImage"]),
280
+ crop: UIImage.decode(it["crop"]),
281
+ originalRect: CGRect.decode(it["originalRect"]))
282
+ }
283
+ func encode() -> [String: Any?] {
284
+ return [
285
+ "faceIndex": self.faceIndex,
286
+ "landmarks": self.landmarks.map { $0.encode() },
287
+ "faceRect": self.faceRect.encode(),
288
+ "rotationAngle": self.rotationAngle,
289
+ "crop": self.crop?.encode(),
290
+ "originalRect": self.originalRect.encode(),
291
+ ]
292
+ }
293
+ }
294
+
295
+ public extension MatchFacesDetection {
296
+ static func decode(_ it: Any?) -> Self {
297
+ let it = it as! [String: Any]
298
+ let alloc = MatchFacesDetection.allocate()
299
+ let sel = "initWithImageIndex:image:faces:error:".selector()
300
+ return privateInit(alloc, sel, (@convention(c)(
301
+ AnyObject, Selector,
302
+ Any?, Any?, Any?, Any?) -> Unmanaged<AnyObject>?).self, { f in f(
303
+ alloc, sel,
304
+ it["imageIndex"],
305
+ MatchFacesImage.decode(it["image"]),
306
+ (it["faces"] as? [Any])?.map { MatchFacesDetectionFace.decode($0) },
307
+ nil,
308
+ )})
309
+ }
310
+ func encode() -> [String: Any?] {
311
+ return [
312
+ "image": self.image.encode(),
313
+ "imageIndex": self.imageIndex,
314
+ "faces": self.faces.map { $0.encode() },
315
+ "error": self.error?.encode(),
316
+ ]
317
+ }
318
+ }
319
+
320
+ public extension MatchFacesComparedFace {
321
+ static func decode(_ it: Any?) -> Self {
322
+ let it = it as! [String: Any]
323
+ return Self(imageIndex: it["imageIndex"] as! NSNumber,
324
+ image: MatchFacesImage.decode(it["image"])!,
325
+ faceIndex: it["faceIndex"] as? NSNumber,
326
+ face: MatchFacesDetectionFace.decode(it["face"]))
327
+ }
328
+ func encode() -> [String: Any?] {
329
+ return [
330
+ "imageIndex": self.imageIndex,
331
+ "image": self.image.encode(),
332
+ "faceIndex": self.faceIndex,
333
+ "face": self.face?.encode(),
334
+ ]
335
+ }
336
+ }
337
+
338
+ public extension MatchFacesComparedFacesPair {
339
+ static func decode(_ it: Any?) -> Self {
340
+ let it = it as! [String: Any]
341
+ return Self(first: MatchFacesComparedFace.decode(it["first"]),
342
+ second: MatchFacesComparedFace.decode(it["second"]),
343
+ score: it["score"] as? NSNumber,
344
+ similarity: it["similarity"] as? NSNumber,
345
+ error: nil)
346
+ }
347
+ func encode() -> [String: Any?] {
348
+ return [
349
+ "first": self.first.encode(),
350
+ "second": self.second.encode(),
351
+ "score": self.score,
352
+ "similarity": self.similarity,
353
+ "error": self.error?.encode(),
354
+ ]
355
+ }
356
+ }
357
+
358
+ public extension MatchFacesResponse {
359
+ static func decode(_ it: Any?) -> MatchFacesResponse {
360
+ let it = it as! [String: Any]
361
+ let alloc = MatchFacesResponse.allocate()
362
+ let sel = "initWithResults:detections:error:".selector()
363
+ let result = privateInit(alloc, sel, (@convention(c)(
364
+ AnyObject, Selector,
365
+ Any?, Any?, Any?) -> Unmanaged<AnyObject>?).self, { f in f(
366
+ alloc, sel,
367
+ (it["results"] as? [Any])?.map { MatchFacesComparedFacesPair.decode($0) },
368
+ (it["detections"] as? [Any])?.map { MatchFacesDetection.decode($0) },
369
+ nil,
370
+ )}) as MatchFacesResponse
371
+ result.setValue(it["tag"] as? String, forKey: "tag")
372
+ return result
373
+ }
374
+ func encode() -> [String: Any?] {
375
+ return [
376
+ "results": self.results.map { $0.encode() },
377
+ "detections": self.detections.map { $0.encode() },
378
+ "error": self.error?.encode(),
379
+ "tag": self.tag,
380
+ ]
381
+ }
382
+ }
383
+
384
+ public extension MatchFacesSimilarityThresholdSplit {
385
+ func encode() -> [String: Any?] {
386
+ return [
387
+ "matchedFaces": self.matchedFaces.map { $0.encode() },
388
+ "unmatchedFaces": self.unmatchedFaces.map { $0.encode() },
389
+ ]
390
+ }
391
+ }
392
+
393
+ // MARK: - DetectFaces
394
+
395
+ public extension ImageQualityRange {
396
+ static func decode(_ it: Any?) -> Self? {
397
+ guard let it = it as? [String: Any] else { return nil }
398
+ let alloc = ImageQualityRange.allocate()
399
+ let sel = "initWithRange:".selector()
400
+ return privateInit(alloc, sel, (@convention(c)(
401
+ Any, Selector,
402
+ Any?) -> Unmanaged<AnyObject>?).self, { f in f(
403
+ alloc, sel,
404
+ [it["min"] as! NSNumber, it["max"] as! NSNumber]
405
+ ) })
406
+ }
407
+ func encode() -> [String: Any?] {
408
+ return [
409
+ "min": self.min,
410
+ "max": self.max,
411
+ ]
412
+ }
413
+ func asList() -> [NSNumber] {
414
+ return [self.min, self.max]
415
+ }
416
+ }
417
+
418
+ public extension ImageQualityCharacteristic {
419
+ static func decode(_ it: Any?) -> ImageQualityCharacteristic {
420
+ let it = it as! [String: Any]
421
+ let name = it["characteristicName"] as! String
422
+ let recommendedRange = ImageQualityRange.decode(it["recommendedRange"])?.asList()
423
+ let customRange = ImageQualityRange.decode(it["customRange"])?.asList()
424
+ let color = UIColor.decode(it["customRange"])
425
+ var result: ImageQualityCharacteristic?
426
+
427
+ switch name {
428
+ case("ImageWidth"): result = ImageQualityGroup.Image.imageWidth(withRange: recommendedRange!)
429
+ case("ImageHeight"): result = ImageQualityGroup.Image.imageHeight(withRange: recommendedRange!)
430
+ case("ImageWidthToHeight"): result = ImageQualityGroup.Image.imageWidthToHeight(withRange: recommendedRange!)
431
+ case("ImageChannelsNumber"): result = ImageQualityGroup.Image.imageChannelsNumber(withValue: recommendedRange![0])
432
+ case("PaddingRatio"): result = ImageQualityGroup.Image.paddingRatio(withMinValue: recommendedRange![0], maxValue: recommendedRange![1])
433
+ case("ArtFace"): result = ImageQualityGroup.Image.artFace()
434
+
435
+ case("FaceMidPointHorizontalPosition"): result = ImageQualityGroup.HeadSizeAndPosition.faceMidPointHorizontalPosition()
436
+ case("FaceMidPointVerticalPosition"): result = ImageQualityGroup.HeadSizeAndPosition.faceMidPointVerticalPosition()
437
+ case("HeadWidthRatio"): result = ImageQualityGroup.HeadSizeAndPosition.headWidthRatio()
438
+ case("HeadHeightRatio"): result = ImageQualityGroup.HeadSizeAndPosition.headHeightRatio()
439
+ case("EyesDistance"): result = ImageQualityGroup.HeadSizeAndPosition.eyesDistance()
440
+ case("Yaw"): result = ImageQualityGroup.HeadSizeAndPosition.yaw()
441
+ case("Pitch"): result = ImageQualityGroup.HeadSizeAndPosition.pitch()
442
+ case("Roll"): result = ImageQualityGroup.HeadSizeAndPosition.roll()
443
+
444
+ case("BlurLevel"): result = ImageQualityGroup.FaceImage.blurLevel()
445
+ case("NoiseLevel"): result = ImageQualityGroup.FaceImage.noiseLevel()
446
+ case("UnnaturalSkinTone"): result = ImageQualityGroup.FaceImage.unnaturalSkinTone()
447
+ case("FaceDynamicRange"): result = ImageQualityGroup.FaceImage.faceDynamicRange()
448
+
449
+ case("EyeRightClosed"): result = ImageQualityGroup.Eyes.eyeRightClosed()
450
+ case("EyeLeftClosed"): result = ImageQualityGroup.Eyes.eyeLeftClosed()
451
+ case("EyeRightOccluded"): result = ImageQualityGroup.Eyes.eyeRightOccluded()
452
+ case("EyeLeftOccluded"): result = ImageQualityGroup.Eyes.eyeLeftOccluded()
453
+ case("EyesRed"): result = ImageQualityGroup.Eyes.eyesRed()
454
+ case("EyeRightCoveredWithHair"): result = ImageQualityGroup.Eyes.eyeRightCoveredWithHair()
455
+ case("EyeLeftCoveredWithHair"): result = ImageQualityGroup.Eyes.eyeLeftCoveredWithHair()
456
+ case("OffGaze"): result = ImageQualityGroup.Eyes.offGaze()
457
+
458
+ case("TooDark"): result = ImageQualityGroup.ShadowsAndLightning.tooDark()
459
+ case("TooLight"): result = ImageQualityGroup.ShadowsAndLightning.tooLight()
460
+ case("FaceGlare"): result = ImageQualityGroup.ShadowsAndLightning.faceGlare()
461
+ case("ShadowsOnFace"): result = ImageQualityGroup.ShadowsAndLightning.shadowsOnFace()
462
+
463
+ case("ShouldersPose"): result = ImageQualityGroup.PoseAndExpression.shouldersPose()
464
+ case("ExpressionLevel"): result = ImageQualityGroup.PoseAndExpression.expressionLevel()
465
+ case("MouthOpen"): result = ImageQualityGroup.PoseAndExpression.mouthOpen()
466
+ case("Smile"): result = ImageQualityGroup.PoseAndExpression.smile()
467
+
468
+ case("DarkGlasses"): result = ImageQualityGroup.HeadOcclusion.darkGlasses()
469
+ case("ReflectionOnGlasses"): result = ImageQualityGroup.HeadOcclusion.reflectionOnGlasses()
470
+ case("FramesTooHeavy"): result = ImageQualityGroup.HeadOcclusion.framesTooHeavy()
471
+ case("FaceOccluded"): result = ImageQualityGroup.HeadOcclusion.faceOccluded()
472
+ case("HeadCovering"): result = ImageQualityGroup.HeadOcclusion.headCovering()
473
+ case("ForeheadCovering"): result = ImageQualityGroup.HeadOcclusion.foreheadCovering()
474
+ case("StrongMakeup"): result = ImageQualityGroup.HeadOcclusion.strongMakeup()
475
+ case("Headphones"): result = ImageQualityGroup.HeadOcclusion.headphones()
476
+ case("MedicalMask"): result = ImageQualityGroup.HeadOcclusion.medicalMask()
477
+
478
+ case("BackgroundUniformity"): result = ImageQualityGroup.Background.backgroundUniformity()
479
+ case("ShadowsOnBackground"): result = ImageQualityGroup.Background.shadowsOnBackground()
480
+ case("OtherFaces"): result = ImageQualityGroup.Background.otherFaces()
481
+ case("BackgroundColorMatch"):
482
+ if color != nil { result = ImageQualityGroup.Background.backgroundColorMatch(with: color!) }
483
+ else { result = ImageQualityGroup.Background.backgroundColorMatch() }
484
+ default: break
485
+ }
486
+
487
+ guard let customRange = customRange else { return result! }
488
+ return result!.withCustomRange(customRange)
489
+ }
490
+ func encode() -> [String: Any?] {
491
+ return [
492
+ "characteristicName": self.name.rawValue,
493
+ "recommendedRange": self.recommendedRange?.encode(),
494
+ "customRange": self.customRange?.encode(),
495
+ "color": (self as? ImageQualityColorCharacteristic)?.color.encode()
496
+ ]
497
+ }
498
+ }
499
+
500
+ public extension DetectFacesConfiguration {
501
+ static func decode(_ it: Any?) -> Self {
502
+ let it = it as! [String: Any]
503
+ let result = Self()
504
+ result.customQuality = (it["customQuality"] as? [[String: Any]])?.compactMap { ImageQualityCharacteristic.decode($0) }
505
+ result.outputImageParams = OutputImageParams.decode(it["outputImageParams"])
506
+ result.onlyCentralFace = it["onlyCentralFace"] as? Bool ?? false
507
+ result.attributes = (it["attributes"] as? [String])?.compactMap { DetectFacesAttribute(rawValue: $0) }
508
+ return result
509
+ }
510
+ func encode() -> [String: Any?] {
511
+ return [
512
+ "customQuality": self.customQuality?.map { $0.encode() },
513
+ "outputImageParams": self.outputImageParams?.encode(),
514
+ "onlyCentralFace": self.onlyCentralFace,
515
+ "attributes": self.attributes?.map { $0.rawValue },
516
+ ]
517
+ }
518
+ }
519
+
520
+ public extension DetectFacesRequest {
521
+ static func decode(_ it: Any?) -> DetectFacesRequest {
522
+ let it = it as! [String: Any]
523
+ var result: DetectFacesRequest!
524
+ let image = UIImage.decode(it["image"])!
525
+ if let scenario = it["scenario"] as? String {
526
+ let alloc = DetectFacesRequest.allocate()
527
+ let sel = "initImage:scenario:".selector()
528
+ result = privateInit(alloc, sel, (@convention(c)(
529
+ Any, Selector,
530
+ Any?, Any?) -> Unmanaged<AnyObject>?).self, { f in f(
531
+ alloc, sel,
532
+ image, scenario
533
+ ) })
534
+ } else {
535
+ result = DetectFacesRequest(
536
+ image: image,
537
+ configuration: DetectFacesConfiguration.decode(it["configuration"])
538
+ )
539
+ }
540
+
541
+ result.tag = it["tag"] as? String
542
+ return result
543
+ }
544
+ func encode() -> [String: Any?] {
545
+ return [
546
+ "image": self.image.encode(),
547
+ "tag": self.tag,
548
+ "scenario": self.scenario,
549
+ "configuration": self.configuration?.encode(),
550
+ ]
551
+ }
552
+ }
553
+
554
+ public extension ImageQualityResult {
555
+ static func decode(_ it: Any?) -> Self {
556
+ let it = it as! [String: Any]
557
+ let alloc = ImageQualityResult.allocate()
558
+ let sel = "initWithName:groupId:status:value:range:".selector()
559
+ return privateInit(alloc, sel, (@convention(c)(
560
+ Any, Selector,
561
+ Any?, Int, Int, Any?, Any?) -> Unmanaged<AnyObject>?).self, { f in f(
562
+ alloc, sel,
563
+ it["name"] as! NSString,
564
+ it["group"] as! Int,
565
+ it["status"] as! Int,
566
+ it["value"] as! NSNumber,
567
+ ImageQualityRange.decode(it["range"])!,
568
+ )})
569
+ }
570
+ func encode() -> [String: Any?] {
571
+ return [
572
+ "name": self.name.rawValue,
573
+ "group": self.group.rawValue,
574
+ "status": self.status.rawValue,
575
+ "range": self.range.encode(),
576
+ "value": self.value,
577
+ ]
578
+ }
579
+ }
580
+
581
+ public extension DetectFacesAttributeResult {
582
+ static func decode(_ it: Any?) -> Self {
583
+ let it = it as! [String: Any]
584
+ let alloc = DetectFacesAttributeResult.allocate()
585
+ let sel = "initWith:confidence:value:range:".selector()
586
+ return privateInit(alloc, sel, (@convention(c)(
587
+ Any, Selector,
588
+ Any?, Any?, Any?, Any?) -> Unmanaged<AnyObject>?).self, { f in f(
589
+ alloc, sel,
590
+ it["attribute"],
591
+ it["confidence"],
592
+ it["value"],
593
+ ImageQualityRange.decode(it["range"])?.asList(),
594
+ )})
595
+ }
596
+ func encode() -> [String: Any?] {
597
+ return [
598
+ "attribute": self.attribute.rawValue,
599
+ "range": self.range?.encode(),
600
+ "value": self.value,
601
+ "confidence": self.confidence,
602
+ ]
603
+ }
604
+ }
605
+
606
+ public extension DetectFaceResult {
607
+ static func decode(_ it: Any?) -> Self {
608
+ let it = it as! [String: Any]
609
+ let alloc = DetectFaceResult.allocate()
610
+ let sel = "initWithQuality:attributes:cropImageData:faceRect:landmarks:originalRect:".selector()
611
+ return privateInit(alloc, sel, (@convention(c)(
612
+ Any, Selector,
613
+ Any?, Any?, Any?, CGRect, Any?, CGRect) -> Unmanaged<AnyObject>?).self, { f in f(
614
+ alloc, sel,
615
+ (it["quality"] as? [Any])?.map { ImageQualityResult.decode($0) },
616
+ (it["attributes"] as? [Any])?.map{ DetectFacesAttributeResult.decode($0) },
617
+ it["crop"],
618
+ CGRect.decode(it["faceRect"]),
619
+ (it["landmarks"] as? [Any])?.map{ Point.decode($0) },
620
+ CGRect.decode(it["originalRect"]),
621
+ )})
622
+ }
623
+ func encode() -> [String: Any?] {
624
+ return [
625
+ "quality": self.quality?.map { $0.encode() },
626
+ "attributes": self.attributes?.map { $0.encode() },
627
+ "landmarks": self.landmarks?.map { $0.encode() },
628
+ "crop": self.crop?.encode(),
629
+ "faceRect": self.faceRect.encode(),
630
+ "originalRect": self.originalRect.encode(),
631
+ "isQualityCompliant": self.isQualityCompliant,
632
+ ]
633
+ }
634
+ }
635
+
636
+ public extension DetectFacesResponse {
637
+ static func decode(_ it: Any?) -> Self {
638
+ let it = it as! [String: Any]
639
+ let alloc = DetectFacesResponse.allocate()
640
+ let sel = "initWithDetections:scenario:error:".selector()
641
+ return privateInit(alloc, sel, (@convention(c)(
642
+ Any, Selector,
643
+ Any?, Any?, Any?) -> Unmanaged<AnyObject>?).self, { f in f(
644
+ alloc, sel,
645
+ (it["allDetections"] as? [Any])?.map { DetectFaceResult.decode($0) },
646
+ it["scenario"],
647
+ nil,
648
+ )})
649
+ }
650
+ func encode() -> [String: Any?] {
651
+ return [
652
+ "detection": self.detection?.encode(),
653
+ "error": self.error?.encode(),
654
+ "allDetections": self.allDetections?.map { $0.encode() },
655
+ "scenario": self.scenario,
656
+ ]
657
+ }
658
+ }
659
+
660
+ // MARK: - PersonDatabase
661
+
662
+ func encodeDBItemResponse(_ data: Any?, _ error: Error?) -> [String: Any?] {
663
+ return [
664
+ "data": data,
665
+ "error": error?.localizedDescription
666
+ ]
667
+ }
668
+
669
+ func encodeDBPageResponse<T>(_ response: DBPageResponse<T>, _ data: Any?) -> [String: Any?] {
670
+ return encodeDBItemResponse([
671
+ "items": data,
672
+ "page": response.page,
673
+ "totalPages": response.totalPages,
674
+ ], response.error)
675
+ }
676
+
677
+ public extension PersonDatabase.Response {
678
+ func encode() -> [String: Any?] { return encodeDBItemResponse(self.success, self.error) }
679
+ }
680
+ public extension BDItemResponse<PersonDatabase.Person> {
681
+ func encode() -> [String: Any?] { return encodeDBItemResponse(self.item?.encode(), self.error) }
682
+ }
683
+ public extension BDItemResponse<PersonDatabase.PersonImage> {
684
+ func encode() -> [String: Any?] { return encodeDBItemResponse(self.item?.encode(), self.error) }
685
+ }
686
+ public extension BDItemResponse<PersonDatabase.PersonGroup> {
687
+ func encode() -> [String: Any?] { return encodeDBItemResponse(self.item?.encode(), self.error) }
688
+ }
689
+ public extension DBPageResponse<PersonDatabase.Person> {
690
+ func encode() -> [String: Any?] { return encodeDBPageResponse(self, self.items?.compactMap{ $0.encode() }) }
691
+ }
692
+ public extension DBPageResponse<PersonDatabase.PersonImage> {
693
+ func encode() -> [String: Any?] { return encodeDBPageResponse(self, self.items?.compactMap{ $0.encode() }) }
694
+ }
695
+ public extension DBPageResponse<PersonDatabase.PersonGroup> {
696
+ func encode() -> [String: Any?] { return encodeDBPageResponse(self, self.items?.compactMap{ $0.encode() }) }
697
+ }
698
+
699
+ public extension Date {
700
+ private static func formatter() -> DateFormatter {
701
+ let df = DateFormatter()
702
+ df.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS"
703
+ return df
704
+ }
705
+ static func decode(_ it: Any?) -> Date {
706
+ let it = it as! String
707
+ return formatter().date(from: it)!
708
+ }
709
+ func encode() -> String { return Date.formatter().string(from: self) }
710
+ }
711
+
712
+ public extension URL {
713
+ static func decode(_ it: Any?) -> Self? {
714
+ guard let it = it as? String else { return nil }
715
+ return Self(string: it)
716
+ }
717
+ func encode() -> String {
718
+ return self.absoluteString
719
+ }
720
+ }
721
+
722
+ public extension PersonDatabase.Person {
723
+ static func decode(_ it: Any?) -> PersonDatabase.Person {
724
+ let it = it as! [String: Any]
725
+ let result = PersonDatabase.Person.emptyInit() as PersonDatabase.Person
726
+ result.setValue(Date.decode(it["updatedAt"]), forKey: "updatedAt")
727
+ result.setValue(Date.decode(it["createdAt"]), forKey: "createdAt")
728
+ result.setValue(it["name"] as Any?, forKey: "name")
729
+ result.setValue(it["groups"] as Any?, forKey: "groups")
730
+ result.setValue(it["id"] as Any?, forKey: "itemId")
731
+ result.setValue((it["metadata"] as Any?) ?? NSNull(), forKey: "mutableMetadata")
732
+ return result
733
+ }
734
+ func encode() -> [String: Any?] {
735
+ return [
736
+ "updatedAt": self.updatedAt.encode(),
737
+ "createdAt": self.createdAt.encode(),
738
+ "name": self.name,
739
+ "groups": self.groups,
740
+ "id": self.itemId,
741
+ "metadata": self.metadata,
742
+ ]
743
+ }
744
+ func update(_ it: [String: Any?]) -> Self {
745
+ if let name = it["name"] as? String { self.name = name }
746
+ if let metadata = it["metadata"] as? [String: Any] { self.metadata = NSMutableDictionary(dictionary: metadata) }
747
+ return self
748
+ }
749
+ }
750
+
751
+ public extension PersonDatabase.PersonImage {
752
+ static func decode(_ it: Any?) -> PersonDatabase.PersonImage {
753
+ let it = it as! [String: Any]
754
+ let result = PersonDatabase.PersonImage.emptyInit() as PersonDatabase.PersonImage
755
+ result.setValue(Date.decode(it["createdAt"]), forKey: "createdAt")
756
+ result.setValue(URL.decode(it["url"]), forKey: "url")
757
+ result.setValue(it["id"] as Any?, forKey: "itemId")
758
+ result.setValue(it["path"] as Any?, forKey: "path")
759
+ result.setValue(it["contentType"] as Any?, forKey: "contentType")
760
+ result.setValue(it["metadata"] as Any?, forKey: "metadata")
761
+ return result
762
+ }
763
+ func encode() -> [String: Any?] {
764
+ return [
765
+ "url": self.url.encode(),
766
+ "createdAt": self.createdAt.encode(),
767
+ "path": self.path,
768
+ "contentType": self.contentType,
769
+ "id": self.itemId,
770
+ "metadata": self.metadata,
771
+ ]
772
+ }
773
+ }
774
+
775
+ public extension PersonDatabase.ImageUpload {
776
+ static func decode(_ it: Any?) -> Self? {
777
+ guard let it = it as? [String: Any] else { return nil }
778
+ if let imageUrl = it["imageUrl"] as? String { return Self(imageURL: URL.decode(imageUrl)!) }
779
+ return Self(imageData: Data.decode(it["imageData"])!)
780
+ }
781
+ func encode() -> [String: Any?] {
782
+ return [
783
+ "imageUrl": self.imageURL?.encode(),
784
+ "imageData": self.imageData?.encode(),
785
+ ]
786
+ }
787
+ }
788
+
789
+ public extension PersonDatabase.PersonGroup {
790
+ static func decode(_ it: Any?) -> PersonDatabase.PersonGroup {
791
+ let it = it as! [String: Any]
792
+ let result = PersonDatabase.PersonGroup.emptyInit() as PersonDatabase.PersonGroup
793
+ result.setValue(Date.decode(it["createdAt"]), forKey: "createdAt")
794
+ result.setValue(it["name"] as Any?, forKey: "name")
795
+ result.setValue(it["id"] as Any?, forKey: "itemId")
796
+ result.setValue((it["metadata"] as Any?) ?? NSNull(), forKey: "mutableMetadata")
797
+ return result
798
+ }
799
+ func encode() -> [String: Any?] {
800
+ return [
801
+ "createdAt": self.createdAt.encode(),
802
+ "name": self.name,
803
+ "id": self.itemId,
804
+ "metadata": self.metadata,
805
+ ]
806
+ }
807
+ func update(_ it: Any?) -> Self {
808
+ let it = it as! [String: Any]
809
+ if let name = it["name"] as? String { self.name = name }
810
+ if let metadata = it["metadata"] as? [String: Any] { self.metadata = NSMutableDictionary(dictionary: metadata) }
811
+ return self
812
+ }
813
+ }
814
+
815
+ public extension PersonDatabase.EditGroupPersonsRequest {
816
+ static func decode(_ it: Any?) -> Self {
817
+ let it = it as! [String: Any]
818
+ return Self(personIdsToAdd: it["personIdsToAdd"] as? [String],
819
+ personIdsToRemove: it["personIdsToRemove"] as? [String])
820
+ }
821
+ func encode() -> [String: Any?] {
822
+ return [
823
+ "personIdsToAdd": self.personIdsToAdd,
824
+ "personIdsToRemove": self.personIdsToRemove,
825
+ ]
826
+ }
827
+ }
828
+
829
+ public extension PersonDatabase.SearchPersonRequest {
830
+ static func decode(_ it: Any?) -> Self {
831
+ let it = it as! [String: Any]
832
+ let result = Self(
833
+ groupIds: it["groupIdsForSearch"] as? [String],
834
+ imageUpload: PersonDatabase.ImageUpload.decode(it["imageUpload"])!)
835
+ result.threshold = it["threshold"] as? NSNumber
836
+ result.limit = it["limit"] as? NSNumber
837
+ result.tag = it["tag"] as? String
838
+ result.detectAll = it["detectAll"] as? Bool ?? false
839
+ result.outputImageParams = OutputImageParams.decode(it["outputImageParams"])
840
+ return result
841
+ }
842
+ func encode() -> [String: Any?] {
843
+ return [
844
+ "imageUpload": self.imageUpload.encode(),
845
+ "detectAll": self.detectAll,
846
+ "threshold": self.threshold,
847
+ "limit": self.limit,
848
+ "tag": self.tag,
849
+ "groupIdsForSearch": self.groupIdsForSearch,
850
+ "outputImageParams": self.outputImageParams?.encode(),
851
+ ]
852
+ }
853
+ }
854
+
855
+ public extension PersonDatabase.SearchPersonDetection {
856
+ static func decode(_ it: Any?) -> Self {
857
+ let it = it as! [String: Any]
858
+ let alloc = PersonDatabase.SearchPersonDetection.allocate()
859
+ let sel = "initWithRoi:landmarks:crop:rotationAngle:".selector()
860
+ return privateInit(alloc, sel, (@convention(c)(
861
+ Any, Selector,
862
+ CGRect, Any?, Any?, Any?) -> Unmanaged<AnyObject>?).self, { f in f(
863
+ alloc, sel,
864
+ CGRect.decode(it["rect"]),
865
+ (it["landmarks"] as? [Any])?.map { Point.decode($0) },
866
+ UIImage.decode(it["crop"]),
867
+ it["rotationAngle"],
868
+ )})
869
+ }
870
+ func encode() -> [String: Any?] {
871
+ return [
872
+ "landmarks": self.landmarks.compactMap({ $0.encode() }),
873
+ "rect": self.rect.encode(),
874
+ "crop": self.crop?.encode(),
875
+ "rotationAngle": self.rotationAngle,
876
+ ]
877
+ }
878
+ }
879
+
880
+ public extension PersonDatabase.SearchPersonImage {
881
+ static func decode2(_ it: Any?) -> PersonDatabase.SearchPersonImage {
882
+ let it = it as! [String: Any]
883
+ let result = PersonDatabase.SearchPersonImage.emptyInit() as PersonDatabase.SearchPersonImage
884
+ result.setValue(Date.decode(it["createdAt"]), forKey: "createdAt")
885
+ result.setValue(URL.decode(it["url"]), forKey: "url")
886
+ result.setValue(it["id"] as Any?, forKey: "itemId")
887
+ result.setValue(it["path"] as Any?, forKey: "path")
888
+ result.setValue(it["contentType"] as Any?, forKey: "contentType")
889
+ result.setValue(it["metadata"] as Any?, forKey: "metadata")
890
+ result.setValue(it["similarity"] as Any?, forKey: "similarity")
891
+ result.setValue(it["distance"] as Any?, forKey: "distance")
892
+ return result
893
+ }
894
+ func encode2() -> [String: Any?] {
895
+ return [
896
+ "url": self.url.encode(),
897
+ "createdAt": self.createdAt.encode(),
898
+ "similarity": self.similarity,
899
+ "distance": self.distance,
900
+ "path": self.path,
901
+ "contentType": self.contentType,
902
+ "id": self.itemId,
903
+ "metadata": self.metadata,
904
+ ]
905
+ }
906
+ }
907
+
908
+ public extension PersonDatabase.SearchPerson {
909
+ static func decode2(_ it: Any?) -> PersonDatabase.SearchPerson {
910
+ let it = it as! [String: Any]
911
+ let result = PersonDatabase.SearchPerson.emptyInit() as PersonDatabase.SearchPerson
912
+ result.setValue(Date.decode(it["updatedAt"]), forKey: "updatedAt")
913
+ result.setValue(Date.decode(it["createdAt"]), forKey: "createdAt")
914
+ result.setValue(it["name"] as Any?, forKey: "name")
915
+ result.setValue(it["groups"] as Any?, forKey: "groups")
916
+ result.setValue(it["id"] as Any?, forKey: "itemId")
917
+ result.setValue((it["metadata"] as Any?) ?? NSNull(), forKey: "mutableMetadata")
918
+ result.setValue((it["images"] as? [Any])?.map { PersonDatabase.SearchPersonImage.decode2($0) }, forKey: "images")
919
+ result.setValue(PersonDatabase.SearchPersonDetection.decode(it["detection"]), forKey: "detection")
920
+ return result
921
+ }
922
+ func encode2() -> [String: Any?] {
923
+ return [
924
+ "detection": self.detection.encode(),
925
+ "images": self.images.compactMap({ $0.encode2() }),
926
+ "createdAt": self.createdAt.encode(),
927
+ "updatedAt": self.updatedAt.encode(),
928
+ "name": self.name,
929
+ "groups": self.groups,
930
+ "id": self.itemId,
931
+ "metadata": self.metadata,
932
+ ]
933
+ }
934
+ }