@@ -68,12 +68,20 @@ extension ConfigKeys {
6868 static let text = ConfigKey< String > (" text" )
6969}
7070
71- // Get value.
71+ // Get value from config .
7272// If value didn't fetch from remote yet. returns default value (if exists).
7373let text: String = Lobster.shared [.text ]
74+
75+ // Get value from only config.
76+ // it is possible to crash if value didn't fetch from remote yet.
7477let text: String = Lobster.shared [config : .text ]
78+
79+ // Get value from only default.
80+ // It is possible to crash if the default value is not set yet.
7581let text: String = Lobster.shared [default : .text ]
7682
83+ // [safe:], [safeConfig:], [safeDefault:] subscripting syntax.
84+ // It is safe because they return nil if they have no value.(return type is `Optional<T>`.)
7785let text: String ? = Lobster.shared [safe : .text ]
7886let text: String ? = Lobster.shared [safeConfig : .text ]
7987let text: String ? = Lobster.shared [safeDefault : .text ]
@@ -111,6 +119,8 @@ Lobster.shared.fetchExpirationDuration = 0.0
111119```
112120
113121### isStaled
122+ If you set ` isStaled ` to true, Lobster will fetch remote value ignoring ` fetchExpirationDuration ` .
123+ ` isStaled ` will be set to ` false ` after fetched remote value.
114124
115125``` swift
116126Lobster.shared .fetchExpirationDuration = 60 * 12
@@ -123,17 +133,6 @@ Lobster.shared.isStaled = true
123133Lobster.shared .fetch ()
124134```
125135
126- ### Demo
127- Required: CocoaPods 1.5 or higher.
128-
129- ``` bash
130- $ cd path/to/Lobster
131- $ bundle install
132- $ cd ./Demo
133- $ bundle exec pod install
134- $ open Demo.xcworkspace
135- ```
136-
137136## Supported types
138137
139138Lobster supports more types as default followings:
@@ -159,55 +158,27 @@ Lobster supports more types as default followings:
159158 - enum(String/Int)
160159 - Decodable Object
161160 - Codable Object
162- - Dictionary
161+
162+ ### TODO
163+ - [ ] CGPoint
164+ - [ ] CGSize
165+ - [ ] CGRect
166+ - [ ] Dictionary
163167
164168#### URL
165- support text: e.g. ` "https://example.com" ` .
169+ Supports text: e.g. ` "https://example.com" ` .
166170
167171![ ] ( docs/img2.png )
168172
169173#### UIColor
170- support only HEX sttring like ` "#FF00FF" ` .
174+ Supports only HEX string like ` "#FF00FF" ` .
171175
172176![ ] ( docs/img3.png )
173177
174- #### CGPoint
175- support text: e.g. ` "[100, 100]" `
176- → Use ` DecodableConfigKey ` (or ` CodableConfigKey ` )
177-
178- ``` swift
179- extension ConfigKeys {
180- static let labelOrigin = ConfigKey< CGPoint> (" label_origin" )
181- }
182- ```
183-
184- #### CGSize
185- support text: e.g. ` "[100, 100]" `
186- → Use ` DecodableConfigKey ` (or ` CodableConfigKey ` )
187-
188- ``` swift
189- extension ConfigKeys {
190- static let boxSize = ConfigKey< CGSize> (" box_size" )
191- }
192- ```
193-
194- #### CGRect
195- support text: e.g. ` "[10, 10, 100, 100]" `
196- → Use ` DecodableConfigKey ` (or ` CodableConfigKey ` )
197-
198- ``` swift
199- extension ConfigKeys {
200- static let boxRect = ConfigKey< CGRect> (" box_rect" )
201- }
202- ```
203-
204- <br />
205-
206- ![ ] ( docs/img4.png )
207-
208178#### Enum
209179supports ` Int ` or ` String ` rawValue.
210- If you want to use other enum, see "Use custom value".
180+ It can be used only by adapting ` ConfigSerializable ` .
181+ If you want to use other enum, see *** Use custom value*** .
211182
212183#### Decodable compliant type
213184read only
@@ -222,73 +193,79 @@ You can easily define custom key in order to get remote value.
222193### Ex 1: enum
223194
224195``` swift
225- enum Status {
226- case invalid
227- case foo (String )
228- case bar (String )
196+ // Adapt protocol `ConfigSerializable`
197+ enum Status : ConfigSerializable {
198+ // Define `_config`, `_configArray`(If needed).
199+ // Custom ConfigBridge's definition see below.
200+ static var _config: ConfigBridge<Status> { return ConfigStatusBridge () }
201+ static var _configArray: ConfigBridge<[Status]> { fatalError (" Not implemented" ) }
202+
203+ case unknown
204+ case active
205+ case inactive
229206
230207 init (value : String ? ) {
231208 guard let value = value else {
232- self = .invalid
233- return
234- }
235- let separated = value.components (separatedBy : " :" )
236- guard let query: (String , String ) = separated.first .flatMap ({ f in separated.last .flatMap ({ l in (f, l) })}) else {
237- self = .invalid
209+ self = .unknown
238210 return
239211 }
240- switch query {
241- case (" foo" , let x):
242- self = .foo (x)
243- case (" bar" , let x):
244- self = .bar (x)
245- default :
246- self = .invalid
212+ switch value {
213+ case " active" : self = .active
214+ case " inactive" : self = .inactive
215+ default : self = .unknown
247216 }
248217 }
249218
250219 var value: String {
251220 switch self {
252- case .foo (let x):
253- return " foo:\( x ) "
254- case .bar (let x):
255- return " bar:\( x ) "
256- default :
257- return " "
221+ case .active : return " active"
222+ case .inactive : return " inactive"
223+ default : return " "
258224 }
259225 }
260226}
261227
262- // define subscript
263- extension Lobster {
264- subscript (_ key : ConfigKey<Status>) -> Status? {
265- get { return Status (value : configValue (forKey : key._key )) }
266- set { setDefaultValue (newValue? .value , forKey : key._key ) }
228+ // Define Bridge class
229+ final class ConfigStatusBridge : ConfigBridge<Status> {
230+ typealias T = Status
231+
232+ // Save value to default store
233+ override func save (key : String , value : T? , defaultsStore : DefaultsStore) {
234+ defaultsStore[key] = value? .value
235+ }
236+
237+ // Get value from RemoteConfig
238+ override func get (key : String , remoteConfig : RemoteConfig) -> T? {
239+ return remoteConfig[key].stringValue .flatMap (Status.init (value: ))
240+ }
241+
242+ // Get value from default store
243+ override func get (key : String , defaultsStore : DefaultsStore) -> T? {
244+ return (defaultsStore[key] as? String ).flatMap (Status.init (value: ))
267245 }
268246}
269247
270- // define ConfigKey
248+ // Define ConfigKey
271249extension ConfigKeys {
272- static let status = ConfigKey< Status> ( " status " )
250+ static let status = ConfigKey< Status>
273251}
274252
275- // Use
276- // set default value
277- Lobster.shared [.status ] = .foo (" bar" )
253+ // Set default
254+ Lobster.shared [default : .status ] = .inactive
278255
279- // get config value
280- if let status = Lobster.shared[. status ] {
281- // ...
256+ // Use value
257+ Lobster.shared . fetch { _ in
258+ let currentStatus = Lobster. shared [. status ]
282259}
283260```
284261
285262To define subscript makes it possible to access custom enum.
286263
287264### Ex 2: Decodable compliant type
288- Just adapt class or struct to Decodable or Codable
265+ Just adapt ` Decodable ` or ` Codable ` to class or struct and adapt ` ConfigSerializable `
289266
290267``` swift
291- struct Person : Codable {
268+ struct Person : Codable , ConfigSerializable {
292269 let name: String
293270 let age: Int
294271 let country: String
@@ -299,10 +276,21 @@ extension ConfigKeys {
299276}
300277```
301278
302- Define config value like below:
279+ Define config value like below in console :
303280
304281![ ] ( docs/img5.png )
305282
283+ ## Demo
284+ Required: CocoaPods 1.5 or higher.
285+
286+ ``` bash
287+ $ cd path/to/Lobster
288+ $ bundle install
289+ $ cd ./Demo
290+ $ bundle exec pod install
291+ $ open Demo.xcworkspace
292+ ```
293+
306294## Requirements
307295- iOS 11.0+
308296- Xcode 10+
0 commit comments