@@ -430,7 +430,7 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
430430 }
431431
432432 /// 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.
434434 @objc public func addListener( _ listener: @escaping RemoteConfigListener ) {
435435 queue. async {
436436 self . listeners. append ( listener)
@@ -478,7 +478,7 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
478478 /// To stop the periodic sync, call `Installations.delete(completion:)`
479479 /// and avoid calling this method again.
480480 ///
481- /// - Parameter completionHandler Fetch operation callback with status and error parameters.
481+ /// - Parameter completionHandler: Fetch operation callback with status and error parameters.
482482 @objc public func fetch( completionHandler: (
483483 @Sendable ( RemoteConfigFetchStatus , Error ? ) -> Void
484484 ) ? =
@@ -492,7 +492,7 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
492492 /// Fetches Remote Config data and sets a duration that specifies how long config data lasts.
493493 /// Call `activateWithCompletion:` to make fetched data available to your app.
494494 ///
495- /// - Parameter expirationDuration Override the (default or optionally set `minimumFetchInterval`
495+ /// - Parameter expirationDuration: Override the (default or optionally set `minimumFetchInterval`
496496 /// property in RemoteConfigSettings) `minimumFetchInterval` for only the current request, in
497497 /// seconds. Setting a value of 0 seconds will force a fetch to the backend.
498498 ///
@@ -518,10 +518,10 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
518518 /// Fetches Remote Config data and sets a duration that specifies how long config data lasts.
519519 /// Call `activateWithCompletion:` to make fetched data available to your app.
520520 ///
521- /// - Parameter expirationDuration Override the (default or optionally set `minimumFetchInterval`
521+ /// - Parameter expirationDuration: Override the (default or optionally set `minimumFetchInterval`
522522 /// property in RemoteConfigSettings) `minimumFetchInterval` for only the current request, in
523523 /// 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.
525525 ///
526526 /// Note: This method uses a Firebase Installations token to identify the app instance, and once
527527 /// it's called, it periodically sends data to the Firebase backend. (see
@@ -550,12 +550,14 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
550550 /// and avoid calling this method again.
551551 @available ( iOS 13 , tvOS 13 , macOS 10 . 15 , macCatalyst 13 , watchOS 7 , * )
552552 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+ }
559561 }
560562 }
561563
@@ -569,7 +571,7 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
569571 /// To stop the periodic sync, call `Installations.delete(completion:)`
570572 /// and avoid calling this method again.
571573 ///
572- /// - Parameter completionHandler Fetch operation callback with status and error parameters.
574+ /// - Parameter completionHandler: Fetch operation callback with status and error parameters.
573575 @objc public func fetchAndActivate( completionHandler:
574576 ( @Sendable ( RemoteConfigFetchAndActivateStatus , Error ? ) -> Void ) ? = nil ) {
575577 fetch { [ weak self] fetchStatus, error in
@@ -617,7 +619,7 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
617619
618620 /// Applies Fetched Config data to the Active Config, causing updates to the behavior and
619621 /// 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.
621623 @objc public func activate( completion: ( @Sendable ( Bool , Error ? ) -> Void ) ? = nil ) {
622624 queue. async { [ weak self] in
623625 guard let self else {
@@ -626,12 +628,12 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
626628 code: RemoteConfigError . internalError. rawValue,
627629 userInfo: [ " ActivationFailureReason " : " Internal Error. " ]
628630 )
629- RCLog . error ( " I-RCN000068 " , " Internal error activating config. " )
630631 if let completion {
631632 DispatchQueue . main. async {
632633 completion ( false , error)
633634 }
634635 }
636+ RCLog . error ( " I-RCN000068 " , " Internal error activating config. " )
635637 return
636638 }
637639 // Check if the last fetched config has already been activated. Fetches with no data change
@@ -695,7 +697,7 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
695697 )
696698 }
697699
698- // MARK: helpers
700+ // MARK: - Helpers
699701
700702 private func fullyQualifiedNamespace( _ namespace: String ) -> String {
701703 if namespace. contains ( " : " ) { return namespace } // Already fully qualified
@@ -713,114 +715,106 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
713715 // MARK: Get Config Result
714716
715717 /// Gets the config value.
716- /// - Parameter key Config key.
718+ /// - Parameter key: Config key.
717719 @objc public func configValue( forKey key: String ) -> RemoteConfigValue {
718720 guard !key. isEmpty else {
719721 return RemoteConfigValue ( data: Data ( ) , source: . static)
720722 }
721723
722724 let fullyQualifiedNamespace = fullyQualifiedNamespace ( FIRNamespace)
723- var value : RemoteConfigValue !
724725
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)
738729 }
739730
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
741741 }
742- return value
743742 }
744743
745744 /// 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.
748747 @objc public func configValue( forKey key: String , source: RemoteConfigSource ) ->
749748 RemoteConfigValue {
750749 guard !key. isEmpty else {
751750 return RemoteConfigValue ( data: Data ( ) , source: . static)
752751 }
753752 let fullyQualifiedNamespace = self . fullyQualifiedNamespace ( FIRNamespace)
754- var value : RemoteConfigValue !
755753
756- queue. sync {
757- switch source {
754+ return queue. sync {
755+ let remoteConfigValue = switch source {
758756 case . remote:
759- value = configContent. activeConfig ( ) [ fullyQualifiedNamespace] ? [ key]
757+ configContent. activeConfig ( ) [ fullyQualifiedNamespace] ? [ key]
760758 case . default:
761- value = configContent. defaultConfig ( ) [ fullyQualifiedNamespace] ? [ key]
759+ configContent. defaultConfig ( ) [ fullyQualifiedNamespace] ? [ key]
762760 case . static:
763- value = RemoteConfigValue ( data: Data ( ) , source: . static)
761+ RemoteConfigValue ( data: Data ( ) , source: . static)
764762 }
763+ return remoteConfigValue ?? RemoteConfigValue ( data: Data ( ) , source: source)
765764 }
766- return value
767765 }
768766
769767 @objc ( allKeysFromSource: )
770768 public func allKeys( from source: RemoteConfigSource ) -> [ String ] {
771- var keys : [ String ] = [ ]
772769 queue. sync {
773770 let fullyQualifiedNamespace = self . fullyQualifiedNamespace ( FIRNamespace)
774771 switch source {
775772 case . default:
776773 if let values = configContent. defaultConfig ( ) [ fullyQualifiedNamespace] {
777- keys = Array ( values. keys)
774+ return Array ( values. keys)
778775 }
779776 case . remote:
780777 if let values = configContent. activeConfig ( ) [ fullyQualifiedNamespace] {
781- keys = Array ( values. keys)
778+ return Array ( values. keys)
782779 }
783- case . static:
784- break
780+ case . static: break
785781 }
782+ return [ ]
786783 }
787- return keys
788784 }
789785
790786 @objc public func keys( withPrefix prefix: String ? ) -> Set < String > {
791- var keys = Set < String > ( )
792787 queue. sync {
793788 let fullyQualifiedNamespace = self . fullyQualifiedNamespace ( FIRNamespace)
794789
795790 if let config = configContent. activeConfig ( ) [ fullyQualifiedNamespace] {
796791 if let prefix = prefix, !prefix. isEmpty {
797- keys = Set ( config. keys. filter { $0. hasPrefix ( prefix) } )
792+ return Set ( config. keys. filter { $0. hasPrefix ( prefix) } )
798793 } else {
799- keys = Set ( config. keys)
794+ return Set ( config. keys)
800795 }
801796 }
797+ return Set < String > ( )
802798 }
803- return keys
804799 }
805800
806801 public func countByEnumerating( with state: UnsafeMutablePointer < NSFastEnumerationState > ,
807802 objects buffer: AutoreleasingUnsafeMutablePointer < AnyObject ? > ,
808803 count len: Int ) -> Int {
809- var count = 0
810804 queue. sync {
811805 let fullyQualifiedNamespace = self . fullyQualifiedNamespace ( FIRNamespace)
812806
813807 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)
815809 }
810+ return 0
816811 }
817- return count
818812 }
819813
820814 // MARK: - Defaults
821815
822816 /// 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.
824818 @objc public func setDefaults( _ defaults: [ String : Any ] ? ) {
825819 let defaults = defaults ?? [ String: Any] ( )
826820 let fullyQualifiedNamespace = self . fullyQualifiedNamespace ( FIRNamespace)
@@ -836,12 +830,12 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
836830
837831 /// Sets default configs from plist for default namespace.
838832 ///
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
840834 /// plist file is named `defaultSamples.plist`:
841835 /// `RemoteConfig.remoteConfig().setDefaults(fromPlist: "defaultSamples")`
842836 @objc ( setDefaultsFromPlistFileName: )
843837 public func setDefaults( fromPlist fileName: String ? ) {
844- guard let fileName = fileName , !fileName. isEmpty else {
838+ guard let fileName, !fileName. isEmpty else {
845839 RCLog . warning ( " I-RCN000037 " ,
846840 " The plist file name cannot be nil or empty. " )
847841 return
@@ -860,12 +854,12 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
860854
861855 /// Returns the default value of a given key from the default config.
862856 ///
863- /// - Parameter key The parameter key of default config.
857+ /// - Parameter key: The parameter key of default config.
864858 /// - Returns The default value of the specified key if the key exists; otherwise, nil.
865859 @objc public func defaultValue( forKey key: String ) -> RemoteConfigValue ? {
866- let fullyQualifiedNamespace = self . fullyQualifiedNamespace ( FIRNamespace)
867- var value : RemoteConfigValue ?
868860 queue. sync {
861+ let fullyQualifiedNamespace = self . fullyQualifiedNamespace ( FIRNamespace)
862+ var value : RemoteConfigValue ?
869863 if let config = configContent. defaultConfig ( ) [ fullyQualifiedNamespace] {
870864 value = config [ key]
871865 if let value, value. source != . default {
@@ -874,8 +868,8 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
874868 " instead coming from source: \( value. source. rawValue) " )
875869 }
876870 }
871+ return value
877872 }
878- return value
879873 }
880874
881875 // MARK: Realtime
@@ -892,9 +886,9 @@ open class RemoteConfig: NSObject, NSFastEnumeration {
892886 /// https://firebase.google.com/docs/remote-config/get-started
893887 /// for more information.
894888 ///
895- /// - Parameter listener The configured listener that is called for every config
889+ /// - Parameter listener: The configured listener that is called for every config
896890 /// update.
897- /// - Returns Returns a registration representing the listener. The registration
891+ /// - Returns A registration representing the listener. The registration
898892 /// contains a remove method, which can be used to stop receiving updates for the provided
899893 /// listener.
900894 @discardableResult
0 commit comments