@@ -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