@@ -19,7 +19,7 @@ import Foundation
19
19
public class OptimizelyJSON : NSObject {
20
20
21
21
private lazy var logger = OPTLoggerFactory . getLogger ( )
22
- private typealias SchemaHandler = ( Any ) -> Bool
22
+ private typealias ValueHandler < T > = ( Any ) -> T ?
23
23
var payload : String ?
24
24
var map = [ String: Any] ( )
25
25
@@ -67,58 +67,63 @@ public class OptimizelyJSON: NSObject {
67
67
return map
68
68
}
69
69
70
- /// Populates the decodable schema passed by the user
70
+ /// Returns decoded value for jsonPath
71
+ ///
72
+ /// If JSON Data is {"k1":true, "k2":{"k3":"v3"}}
73
+ ///
74
+ /// Set jsonPath to "k2" to access {"k3":"v3"} or set it to "k2.k3" to access "v3"
75
+ /// Set it to nil or empty to access the entire JSON data.
71
76
///
72
77
/// - Parameters:
73
78
/// - jsonPath: Key path for the value.
74
- /// - schema: Decodable schema to populate.
75
- /// - Returns: true if value decoded successfully
76
- public func getValue< T: Decodable > ( jsonPath: String ? , schema: inout T ) -> Bool {
77
- func populateDecodableSchema( value: Any ) -> Bool {
79
+ /// - Returns: Value if decoded successfully
80
+ public func getValue< T: Decodable > ( jsonPath: String ? = nil ) -> T ? {
81
+ func handler( value: Any ) -> T ? {
78
82
guard JSONSerialization . isValidJSONObject ( value) else {
79
- // Try and assign value directly to schema
83
+ // Try and typecast value to required return type
80
84
if let v = value as? T {
81
- schema = v
82
- return true
85
+ return v
83
86
}
84
- logger. e ( . failedToAssignValueToSchema )
85
- return false
87
+ logger. e ( . failedToAssignValue )
88
+ return nil
86
89
}
87
- // Try to decode value into schema
90
+ // Try to decode value into return type
88
91
guard let jsonData = try ? JSONSerialization . data ( withJSONObject: value, options: [ ] ) ,
89
92
let decodedValue = try ? JSONDecoder ( ) . decode ( T . self, from: jsonData) else {
90
- logger. e ( . failedToAssignValueToSchema )
91
- return false
93
+ logger. e ( . failedToAssignValue )
94
+ return nil
92
95
}
93
- schema = decodedValue
94
- return true
96
+ return decodedValue
95
97
}
96
- return getValue ( jsonPath: jsonPath, schemaHandler : populateDecodableSchema ( value: ) )
98
+ return getValue ( jsonPath: jsonPath, valueHandler : handler ( value: ) )
97
99
}
98
100
99
- /// Populates the schema passed by the user
101
+ /// Returns parsed value for jsonPath
102
+ ///
103
+ /// If JSON Data is {"k1":true, "k2":{"k3":"v3"}}
104
+ ///
105
+ /// Set jsonPath to "k2" to access {"k3":"v3"} or set it to "k2.k3" to access "v3"
106
+ /// Set it to nil or empty to access the entire JSON data.
100
107
///
101
108
/// - Parameters:
102
109
/// - jsonPath: Key path for the value.
103
- /// - schema: Schema to populate.
104
- /// - Returns: true if value decoded successfully
105
- public func getValue< T> ( jsonPath: String ? , schema: inout T ) -> Bool {
106
- func populateSchema( value: Any ) -> Bool {
110
+ /// - Returns: Value if parsed successfully
111
+ public func getValue< T> ( jsonPath: String ? ) -> T ? {
112
+ func handler( value: Any ) -> T ? {
107
113
guard let v = value as? T else {
108
- self . logger. e ( . failedToAssignValueToSchema )
109
- return false
114
+ self . logger. e ( . failedToAssignValue )
115
+ return nil
110
116
}
111
- schema = v
112
- return true
117
+ return v
113
118
}
114
- return getValue ( jsonPath: jsonPath, schemaHandler : populateSchema ( value: ) )
119
+ return getValue ( jsonPath: jsonPath, valueHandler : handler ( value: ) )
115
120
}
116
121
117
- private func getValue( jsonPath: String ? , schemaHandler : SchemaHandler ) -> Bool {
122
+ private func getValue< T > ( jsonPath: String ? , valueHandler : ValueHandler < T > ) -> T ? {
118
123
119
124
guard let path = jsonPath, !path. isEmpty else {
120
- // Populate the whole schema
121
- return schemaHandler ( map)
125
+ // Retrieve value for path
126
+ return valueHandler ( map)
122
127
}
123
128
124
129
let pathArray = path. components ( separatedBy: " . " )
@@ -128,15 +133,15 @@ public class OptimizelyJSON: NSObject {
128
133
for (index, key) in pathArray. enumerated ( ) {
129
134
guard let value = internalMap [ key] else {
130
135
self . logger. e ( . valueForKeyNotFound( key) )
131
- return false
136
+ return nil
132
137
}
133
138
if let dict = value as? [ String : Any ] {
134
139
internalMap = dict
135
140
}
136
141
if index == lastIndex {
137
- return schemaHandler ( value)
142
+ return valueHandler ( value)
138
143
}
139
144
}
140
- return false
145
+ return nil
141
146
}
142
147
}
0 commit comments