@@ -430,7 +430,7 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
430
430
}
431
431
432
432
/// Adds a listener that will be called whenever one of the get methods is called.
433
- /// - Parameter listener Function that takes in the parameter key and the config.
433
+ /// - Parameter listener: Function that takes in the parameter key and the config.
434
434
@objc public func addListener( _ listener: @escaping RemoteConfigListener ) {
435
435
queue. async {
436
436
self . listeners. append ( listener)
@@ -478,7 +478,7 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
478
478
/// To stop the periodic sync, call `Installations.delete(completion:)`
479
479
/// and avoid calling this method again.
480
480
///
481
- /// - Parameter completionHandler Fetch operation callback with status and error parameters.
481
+ /// - Parameter completionHandler: Fetch operation callback with status and error parameters.
482
482
@objc public func fetch( completionHandler: (
483
483
@Sendable ( RemoteConfigFetchStatus , Error ? ) -> Void
484
484
) ? =
@@ -492,7 +492,7 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
492
492
/// Fetches Remote Config data and sets a duration that specifies how long config data lasts.
493
493
/// Call `activateWithCompletion:` to make fetched data available to your app.
494
494
///
495
- /// - Parameter expirationDuration Override the (default or optionally set `minimumFetchInterval`
495
+ /// - Parameter expirationDuration: Override the (default or optionally set `minimumFetchInterval`
496
496
/// property in RemoteConfigSettings) `minimumFetchInterval` for only the current request, in
497
497
/// seconds. Setting a value of 0 seconds will force a fetch to the backend.
498
498
///
@@ -518,10 +518,10 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
518
518
/// Fetches Remote Config data and sets a duration that specifies how long config data lasts.
519
519
/// Call `activateWithCompletion:` to make fetched data available to your app.
520
520
///
521
- /// - Parameter expirationDuration Override the (default or optionally set `minimumFetchInterval`
521
+ /// - Parameter expirationDuration: Override the (default or optionally set `minimumFetchInterval`
522
522
/// property in RemoteConfigSettings) `minimumFetchInterval` for only the current request, in
523
523
/// seconds. Setting a value of 0 seconds will force a fetch to the backend.
524
- /// - Parameter completionHandler Fetch operation callback with status and error parameters.
524
+ /// - Parameter completionHandler: Fetch operation callback with status and error parameters.
525
525
///
526
526
/// Note: This method uses a Firebase Installations token to identify the app instance, and once
527
527
/// it's called, it periodically sends data to the Firebase backend. (see
@@ -550,12 +550,14 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
550
550
/// and avoid calling this method again.
551
551
@available ( iOS 13 , tvOS 13 , macOS 10 . 15 , macCatalyst 13 , watchOS 7 , * )
552
552
public func fetchAndActivate( ) async throws -> RemoteConfigFetchAndActivateStatus {
553
- _ = try await fetch ( )
554
- do {
555
- try await activate ( )
556
- return . successFetchedFromRemote
557
- } catch {
558
- return . successUsingPreFetchedData
553
+ return try await withUnsafeThrowingContinuation { continuation in
554
+ fetchAndActivate { status, error in
555
+ if let error {
556
+ continuation. resume ( throwing: error)
557
+ } else {
558
+ continuation. resume ( returning: status)
559
+ }
560
+ }
559
561
}
560
562
}
561
563
@@ -569,7 +571,7 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
569
571
/// To stop the periodic sync, call `Installations.delete(completion:)`
570
572
/// and avoid calling this method again.
571
573
///
572
- /// - Parameter completionHandler Fetch operation callback with status and error parameters.
574
+ /// - Parameter completionHandler: Fetch operation callback with status and error parameters.
573
575
@objc public func fetchAndActivate( completionHandler:
574
576
( @Sendable ( RemoteConfigFetchAndActivateStatus , Error ? ) -> Void ) ? = nil ) {
575
577
fetch { [ weak self] fetchStatus, error in
@@ -617,7 +619,7 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
617
619
618
620
/// Applies Fetched Config data to the Active Config, causing updates to the behavior and
619
621
/// appearance of the app to take effect (depending on how config data is used in the app).
620
- /// - Parameter completion Activate operation callback with changed and error parameters.
622
+ /// - Parameter completion: Activate operation callback with changed and error parameters.
621
623
@objc public func activate( completion: ( @Sendable ( Bool , Error ? ) -> Void ) ? = nil ) {
622
624
queue. async { [ weak self] in
623
625
guard let self else {
@@ -626,12 +628,12 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
626
628
code: RemoteConfigError . internalError. rawValue,
627
629
userInfo: [ " ActivationFailureReason " : " Internal Error. " ]
628
630
)
629
- RCLog . error ( " I-RCN000068 " , " Internal error activating config. " )
630
631
if let completion {
631
632
DispatchQueue . main. async {
632
633
completion ( false , error)
633
634
}
634
635
}
636
+ RCLog . error ( " I-RCN000068 " , " Internal error activating config. " )
635
637
return
636
638
}
637
639
// Check if the last fetched config has already been activated. Fetches with no data change
@@ -695,7 +697,7 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
695
697
)
696
698
}
697
699
698
- // MARK: helpers
700
+ // MARK: - Helpers
699
701
700
702
private func fullyQualifiedNamespace( _ namespace: String ) -> String {
701
703
if namespace. contains ( " : " ) { return namespace } // Already fully qualified
@@ -713,114 +715,106 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
713
715
// MARK: Get Config Result
714
716
715
717
/// Gets the config value.
716
- /// - Parameter key Config key.
718
+ /// - Parameter key: Config key.
717
719
@objc public func configValue( forKey key: String ) -> RemoteConfigValue {
718
720
guard !key. isEmpty else {
719
721
return RemoteConfigValue ( data: Data ( ) , source: . static)
720
722
}
721
723
722
724
let fullyQualifiedNamespace = fullyQualifiedNamespace ( FIRNamespace)
723
- var value : RemoteConfigValue !
724
725
725
- queue. sync {
726
- value = configContent. activeConfig ( ) [ fullyQualifiedNamespace] ? [ key]
727
- if let value = value {
728
- if value. source != . remote {
729
- RCLog . error ( " I-RCN000001 " ,
730
- " Key \( key) should come from source: \( RemoteConfigSource . remote. rawValue) " +
731
- " instead coming from source: \( value. source. rawValue) " )
732
- }
733
- if let config = configContent. getConfigAndMetadata ( forNamespace: fullyQualifiedNamespace)
734
- as? [ String : RemoteConfigValue ] {
735
- callListeners ( key: key, config: config)
736
- }
737
- return
726
+ return queue. sync {
727
+ guard let value = configContent. activeConfig ( ) [ fullyQualifiedNamespace] ? [ key] else {
728
+ return defaultValue ( forFullyQualifiedNamespace: fullyQualifiedNamespace, key: key)
738
729
}
739
730
740
- value = defaultValue ( forFullyQualifiedNamespace: fullyQualifiedNamespace, key: key)
731
+ if value. source != . remote {
732
+ RCLog . error ( " I-RCN000001 " ,
733
+ " Key \( key) should come from source: \( RemoteConfigSource . remote. rawValue) " +
734
+ " instead coming from source: \( value. source. rawValue) " )
735
+ }
736
+ if let config = configContent. getConfigAndMetadata ( forNamespace: fullyQualifiedNamespace)
737
+ as? [ String : RemoteConfigValue ] {
738
+ callListeners ( key: key, config: config)
739
+ }
740
+ return value
741
741
}
742
- return value
743
742
}
744
743
745
744
/// Gets the config value of a given source from the default namespace.
746
- /// - Parameter key Config key.
747
- /// - Parameter source Config value source.
745
+ /// - Parameter key: Config key.
746
+ /// - Parameter source: Config value source.
748
747
@objc public func configValue( forKey key: String , source: RemoteConfigSource ) ->
749
748
RemoteConfigValue {
750
749
guard !key. isEmpty else {
751
750
return RemoteConfigValue ( data: Data ( ) , source: . static)
752
751
}
753
752
let fullyQualifiedNamespace = self . fullyQualifiedNamespace ( FIRNamespace)
754
- var value : RemoteConfigValue !
755
753
756
- queue. sync {
757
- switch source {
754
+ return queue. sync {
755
+ let remoteConfigValue = switch source {
758
756
case . remote:
759
- value = configContent. activeConfig ( ) [ fullyQualifiedNamespace] ? [ key]
757
+ configContent. activeConfig ( ) [ fullyQualifiedNamespace] ? [ key]
760
758
case . default:
761
- value = configContent. defaultConfig ( ) [ fullyQualifiedNamespace] ? [ key]
759
+ configContent. defaultConfig ( ) [ fullyQualifiedNamespace] ? [ key]
762
760
case . static:
763
- value = RemoteConfigValue ( data: Data ( ) , source: . static)
761
+ RemoteConfigValue ( data: Data ( ) , source: . static)
764
762
}
763
+ return remoteConfigValue ?? RemoteConfigValue ( data: Data ( ) , source: source)
765
764
}
766
- return value
767
765
}
768
766
769
767
@objc ( allKeysFromSource: )
770
768
public func allKeys( from source: RemoteConfigSource ) -> [ String ] {
771
- var keys : [ String ] = [ ]
772
769
queue. sync {
773
770
let fullyQualifiedNamespace = self . fullyQualifiedNamespace ( FIRNamespace)
774
771
switch source {
775
772
case . default:
776
773
if let values = configContent. defaultConfig ( ) [ fullyQualifiedNamespace] {
777
- keys = Array ( values. keys)
774
+ return Array ( values. keys)
778
775
}
779
776
case . remote:
780
777
if let values = configContent. activeConfig ( ) [ fullyQualifiedNamespace] {
781
- keys = Array ( values. keys)
778
+ return Array ( values. keys)
782
779
}
783
- case . static:
784
- break
780
+ case . static: break
785
781
}
782
+ return [ ]
786
783
}
787
- return keys
788
784
}
789
785
790
786
@objc public func keys( withPrefix prefix: String ? ) -> Set < String > {
791
- var keys = Set < String > ( )
792
787
queue. sync {
793
788
let fullyQualifiedNamespace = self . fullyQualifiedNamespace ( FIRNamespace)
794
789
795
790
if let config = configContent. activeConfig ( ) [ fullyQualifiedNamespace] {
796
791
if let prefix = prefix, !prefix. isEmpty {
797
- keys = Set ( config. keys. filter { $0. hasPrefix ( prefix) } )
792
+ return Set ( config. keys. filter { $0. hasPrefix ( prefix) } )
798
793
} else {
799
- keys = Set ( config. keys)
794
+ return Set ( config. keys)
800
795
}
801
796
}
797
+ return Set < String > ( )
802
798
}
803
- return keys
804
799
}
805
800
806
801
public func countByEnumerating( with state: UnsafeMutablePointer < NSFastEnumerationState > ,
807
802
objects buffer: AutoreleasingUnsafeMutablePointer < AnyObject ? > ,
808
803
count len: Int ) -> Int {
809
- var count = 0
810
804
queue. sync {
811
805
let fullyQualifiedNamespace = self . fullyQualifiedNamespace ( FIRNamespace)
812
806
813
807
if let config = configContent. activeConfig ( ) [ fullyQualifiedNamespace] as? NSDictionary {
814
- count = config. countByEnumerating ( with: state, objects: buffer, count: len)
808
+ return config. countByEnumerating ( with: state, objects: buffer, count: len)
815
809
}
810
+ return 0
816
811
}
817
- return count
818
812
}
819
813
820
814
// MARK: - Defaults
821
815
822
816
/// Sets config defaults for parameter keys and values in the default namespace config.
823
- /// - Parameter defaults A dictionary mapping a NSString * key to a NSObject * value.
817
+ /// - Parameter defaults: A dictionary mapping a NSString * key to a NSObject * value.
824
818
@objc public func setDefaults( _ defaults: [ String : Any ] ? ) {
825
819
let defaults = defaults ?? [ String: Any] ( )
826
820
let fullyQualifiedNamespace = self . fullyQualifiedNamespace ( FIRNamespace)
@@ -836,12 +830,12 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
836
830
837
831
/// Sets default configs from plist for default namespace.
838
832
///
839
- /// - Parameter fileName The plist file name, with no file name extension. For example, if the
833
+ /// - Parameter fileName: The plist file name, with no file name extension. For example, if the
840
834
/// plist file is named `defaultSamples.plist`:
841
835
/// `RemoteConfig.remoteConfig().setDefaults(fromPlist: "defaultSamples")`
842
836
@objc ( setDefaultsFromPlistFileName: )
843
837
public func setDefaults( fromPlist fileName: String ? ) {
844
- guard let fileName = fileName , !fileName. isEmpty else {
838
+ guard let fileName, !fileName. isEmpty else {
845
839
RCLog . warning ( " I-RCN000037 " ,
846
840
" The plist file name cannot be nil or empty. " )
847
841
return
@@ -860,12 +854,12 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
860
854
861
855
/// Returns the default value of a given key from the default config.
862
856
///
863
- /// - Parameter key The parameter key of default config.
857
+ /// - Parameter key: The parameter key of default config.
864
858
/// - Returns The default value of the specified key if the key exists; otherwise, nil.
865
859
@objc public func defaultValue( forKey key: String ) -> RemoteConfigValue ? {
866
- let fullyQualifiedNamespace = self . fullyQualifiedNamespace ( FIRNamespace)
867
- var value : RemoteConfigValue ?
868
860
queue. sync {
861
+ let fullyQualifiedNamespace = self . fullyQualifiedNamespace ( FIRNamespace)
862
+ var value : RemoteConfigValue ?
869
863
if let config = configContent. defaultConfig ( ) [ fullyQualifiedNamespace] {
870
864
value = config [ key]
871
865
if let value, value. source != . default {
@@ -874,8 +868,8 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
874
868
" instead coming from source: \( value. source. rawValue) " )
875
869
}
876
870
}
871
+ return value
877
872
}
878
- return value
879
873
}
880
874
881
875
// MARK: Realtime
@@ -892,9 +886,9 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
892
886
/// https://firebase.google.com/docs/remote-config/get-started
893
887
/// for more information.
894
888
///
895
- /// - Parameter listener The configured listener that is called for every config
889
+ /// - Parameter listener: The configured listener that is called for every config
896
890
/// update.
897
- /// - Returns Returns a registration representing the listener. The registration
891
+ /// - Returns A registration representing the listener. The registration
898
892
/// contains a remove method, which can be used to stop receiving updates for the provided
899
893
/// listener.
900
894
@discardableResult
0 commit comments