@@ -26,6 +26,8 @@ import Foundation
26
26
///
27
27
/// This may become the basis of a generated-from-manifest solution.
28
28
public protocol Variables {
29
+ var resourceBundles : [ Bundle ] { get }
30
+
29
31
/// Finds a string typed value for this key. If none exists, `nil` is returned.
30
32
///
31
33
/// N.B. the `key` and type `String` should be listed in the experiment manifest.
@@ -241,9 +243,7 @@ private func asEnum<T: RawRepresentable>(_ string: String) -> T? where T.RawValu
241
243
return T ( rawValue: string)
242
244
}
243
245
244
- protocol VariablesWithBundle : Variables {
245
- var resourceBundles : [ Bundle ] { get }
246
- }
246
+ protocol VariablesWithBundle : Variables { }
247
247
248
248
extension VariablesWithBundle {
249
249
func getImage( _ key: String ) -> UIImage ? {
@@ -289,65 +289,21 @@ extension VariablesWithBundle {
289
289
///
290
290
/// If no image is found in any of the `resourceBundles`, then the `nil` is returned.
291
291
func asImage( name: String ) -> UIImage ? {
292
- for bundle in resourceBundles {
293
- if let image = UIImage ( named: name, in: bundle, compatibleWith: nil ) {
294
- return image
295
- }
296
- }
297
- return nil
292
+ return resourceBundles. getImage ( named: name)
298
293
}
299
294
300
295
/// Search through the resource bundles looking for localized strings with the given name.
301
296
/// If the `name` contains exactly one slash, it is split up and the first part of the string is used
302
297
/// as the `tableName` and the second the `key` in localized string lookup.
303
298
/// If no string is found in any of the `resourceBundles`, then the `name` is passed back unmodified.
304
299
func asLocalizedString( name: String ) -> String ? {
305
- let parts = name. split ( separator: " / " , maxSplits: 1 , omittingEmptySubsequences: true ) . map { String ( $0) }
306
- let key : String
307
- let tableName : String ?
308
- switch parts. count {
309
- case 2 :
310
- tableName = parts [ 0 ]
311
- key = parts [ 1 ]
312
- default :
313
- tableName = nil
314
- key = name
315
- }
316
-
317
- for bundle in resourceBundles {
318
- let value = bundle. localizedString ( forKey: key, value: nil , table: tableName)
319
- if value != key {
320
- return value
321
- }
322
- }
323
- return name
300
+ return resourceBundles. getString ( named: name) ?? name
324
301
}
325
302
}
326
303
327
304
/// A thin wrapper around the JSON produced by the `get_feature_variables_json(feature_id)` call, useful
328
305
/// for configuring a feature, but without needing the developer to know about experiment specifics.
329
306
internal class JSONVariables : VariablesWithBundle {
330
- func asStringMap( ) -> [ String : String ] ? {
331
- return nil
332
- }
333
-
334
- func asIntMap( ) -> [ String : Int ] ? {
335
- return nil
336
- }
337
-
338
- func asBoolMap( ) -> [ String : Bool ] ? {
339
- return nil
340
- }
341
-
342
- func asVariablesMap( ) -> [ String : Variables ] ? {
343
- return json. compactMapValues { value in
344
- if let jsonMap = value as? [ String : Any ] {
345
- return JSONVariables ( with: jsonMap)
346
- }
347
- return nil
348
- }
349
- }
350
-
351
307
private let json : [ String : Any ]
352
308
internal let resourceBundles : [ Bundle ]
353
309
@@ -370,6 +326,10 @@ internal class JSONVariables: VariablesWithBundle {
370
326
return valueMap ( key)
371
327
}
372
328
329
+ func asStringMap( ) -> [ String : String ] ? {
330
+ return nil
331
+ }
332
+
373
333
func getInt( _ key: String ) -> Int ? {
374
334
return value ( key)
375
335
}
@@ -382,6 +342,10 @@ internal class JSONVariables: VariablesWithBundle {
382
342
return valueMap ( key)
383
343
}
384
344
345
+ func asIntMap( ) -> [ String : Int ] ? {
346
+ return nil
347
+ }
348
+
385
349
func getBool( _ key: String ) -> Bool ? {
386
350
return value ( key)
387
351
}
@@ -394,6 +358,10 @@ internal class JSONVariables: VariablesWithBundle {
394
358
return valueMap ( key)
395
359
}
396
360
361
+ func asBoolMap( ) -> [ String : Bool ] ? {
362
+ return nil
363
+ }
364
+
397
365
// Methods used to get sub-objects. We immediately re-wrap an JSON object if it exists.
398
366
func getVariables( _ key: String ) -> Variables ? {
399
367
if let dictionary: [ String : Any ] = value ( key) {
@@ -415,6 +383,15 @@ internal class JSONVariables: VariablesWithBundle {
415
383
}
416
384
}
417
385
386
+ func asVariablesMap( ) -> [ String : Variables ] ? {
387
+ return json. compactMapValues { value in
388
+ if let jsonMap = value as? [ String : Any ] {
389
+ return JSONVariables ( with: jsonMap)
390
+ }
391
+ return nil
392
+ }
393
+ }
394
+
418
395
private func value< T> ( _ key: String ) -> T ? {
419
396
return json [ key] as? T
420
397
}
@@ -438,24 +415,14 @@ internal class JSONVariables: VariablesWithBundle {
438
415
439
416
// Another implementation of `Variables` may just return nil for everything.
440
417
public class NilVariables : Variables {
441
- public func asStringMap( ) -> [ String : String ] ? {
442
- return nil
443
- }
444
-
445
- public func asIntMap( ) -> [ String : Int ] ? {
446
- return nil
447
- }
418
+ public static let instance = NilVariables ( )
448
419
449
- public func asBoolMap( ) -> [ String : Bool ] ? {
450
- return nil
451
- }
420
+ public private( set) var resourceBundles : [ Bundle ] = [ Bundle . main]
452
421
453
- public func asVariablesMap ( ) -> [ String : Variables ] ? {
454
- return nil
422
+ public func set ( bundles : [ Bundle ] ) {
423
+ resourceBundles = bundles
455
424
}
456
425
457
- public static let instance : Variables = NilVariables ( )
458
-
459
426
public func getString( _: String ) -> String ? {
460
427
return nil
461
428
}
@@ -468,6 +435,10 @@ public class NilVariables: Variables {
468
435
return nil
469
436
}
470
437
438
+ public func asStringMap( ) -> [ String : String ] ? {
439
+ return nil
440
+ }
441
+
471
442
public func getInt( _: String ) -> Int ? {
472
443
return nil
473
444
}
@@ -480,6 +451,10 @@ public class NilVariables: Variables {
480
451
return nil
481
452
}
482
453
454
+ public func asIntMap( ) -> [ String : Int ] ? {
455
+ return nil
456
+ }
457
+
483
458
public func getBool( _: String ) -> Bool ? {
484
459
return nil
485
460
}
@@ -492,6 +467,10 @@ public class NilVariables: Variables {
492
467
return nil
493
468
}
494
469
470
+ public func asBoolMap( ) -> [ String : Bool ] ? {
471
+ return nil
472
+ }
473
+
495
474
public func getImage( _: String ) -> UIImage ? {
496
475
return nil
497
476
}
@@ -527,4 +506,8 @@ public class NilVariables: Variables {
527
506
public func getVariablesMap( _: String ) -> [ String : Variables ] ? {
528
507
return nil
529
508
}
509
+
510
+ public func asVariablesMap( ) -> [ String : Variables ] ? {
511
+ return nil
512
+ }
530
513
}
0 commit comments