diff --git a/FirebaseRemoteConfig/Sources/FIRConfigValue.m b/FirebaseRemoteConfig/Sources/FIRConfigValue.m deleted file mode 100644 index 96e03aa7044..00000000000 --- a/FirebaseRemoteConfig/Sources/FIRConfigValue.m +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h" - -#import "FirebaseCore/Extension/FirebaseCoreInternal.h" -#import "FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h" - -@implementation FIRRemoteConfigValue { - /// Data backing the config value. - NSData *_data; - FIRRemoteConfigSource _source; -} - -/// Designated initializer -- (instancetype)initWithData:(nullable NSData *)data source:(FIRRemoteConfigSource)source { - self = [super init]; - if (self) { - _data = [data copy]; - _source = source; - } - return self; -} - -/// Superclass's designated initializer -- (instancetype)init { - return [self initWithData:nil source:FIRRemoteConfigSourceStatic]; -} - -/// The string is a UTF-8 representation of NSData. -- (nonnull NSString *)stringValue { - return [[NSString alloc] initWithData:_data encoding:NSUTF8StringEncoding] ?: @""; -} - -/// Number representation of a UTF-8 string. -- (NSNumber *)numberValue { - return [NSNumber numberWithDouble:self.stringValue.doubleValue]; -} - -/// Internal representation of the FIRRemoteConfigValue as a NSData object. -- (NSData *)dataValue { - return _data; -} - -/// Boolean representation of a UTF-8 string. -- (BOOL)boolValue { - return self.stringValue.boolValue; -} - -/// Returns a foundation object (NSDictionary / NSArray) representation for JSON data. -- (id)JSONValue { - NSError *error; - if (!_data) { - return nil; - } - id JSONObject = [NSJSONSerialization JSONObjectWithData:_data options:kNilOptions error:&error]; - if (error) { - FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000065", @"Error parsing data as JSON."); - return nil; - } - return JSONObject; -} - -/// Debug description showing the representations of all types. -- (NSString *)debugDescription { - NSString *content = [NSString - stringWithFormat:@"Boolean: %d, String: %@, Number: %@, JSON:%@, Data: %@, Source: %zd", - self.boolValue, self.stringValue, self.numberValue, self.JSONValue, _data, - (long)self.source]; - return [NSString stringWithFormat:@"<%@: %p, %@>", [self class], self, content]; -} - -/// Copy method. -- (id)copyWithZone:(NSZone *)zone { - FIRRemoteConfigValue *value = [[[self class] allocWithZone:zone] initWithData:_data]; - return value; -} -@end diff --git a/FirebaseRemoteConfig/Sources/FIRRemoteConfig.m b/FirebaseRemoteConfig/Sources/FIRRemoteConfig.m index ca38f0f8841..958fbb4f9f9 100644 --- a/FirebaseRemoteConfig/Sources/FIRRemoteConfig.m +++ b/FirebaseRemoteConfig/Sources/FIRRemoteConfig.m @@ -24,7 +24,6 @@ #import "FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h" #import "FirebaseRemoteConfig/Sources/RCNConfigConstants.h" #import "FirebaseRemoteConfig/Sources/RCNConfigRealtime.h" -#import "FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h" #import "FirebaseRemoteConfig/Sources/RCNPersonalization.h" #import "FirebaseRemoteConfig/FirebaseRemoteConfig-Swift.h" diff --git a/FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h b/FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h index c5df0dfd9fa..459b898b76f 100644 --- a/FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h +++ b/FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h @@ -22,6 +22,7 @@ @class RCNConfigContent; @class FIROptions; @class RCNConfigSettings; +@class FIRRemoteConfigValue; @protocol FIRAnalyticsInterop; /// The Firebase Remote Config service default namespace, to be used if the API method does not @@ -139,31 +140,6 @@ typedef void (^FIRRemoteConfigFetchAndActivateCompletion)( FIRRemoteConfigFetchAndActivateStatus status, NSError *_Nullable error) NS_SWIFT_UNAVAILABLE("Use Swift's closure syntax instead."); -#pragma mark - FIRRemoteConfigValue -/// This class provides a wrapper for Remote Config parameter values, with methods to get parameter -/// values as different data types. -NS_SWIFT_NAME(RemoteConfigValue) -@interface FIRRemoteConfigValue : NSObject -/// Gets the value as a string. -@property(nonatomic, readonly, nonnull) NSString *stringValue; -/// Gets the value as a number value. -@property(nonatomic, readonly, nonnull) NSNumber *numberValue; -/// Gets the value as a NSData object. -@property(nonatomic, readonly, nonnull) NSData *dataValue; -/// Gets the value as a boolean. -@property(nonatomic, readonly) BOOL boolValue; -/// Gets a foundation object (NSDictionary / NSArray) by parsing the value as JSON. This method uses -/// NSJSONSerialization's JSONObjectWithData method with an options value of 0. -@property(nonatomic, readonly, nullable) id JSONValue NS_SWIFT_NAME(jsonValue); -/// Identifies the source of the fetched value. -@property(nonatomic, readonly) FIRRemoteConfigSource source; - -/// TODO: internal API for temporary bridging -/// Designated initializer. -- (instancetype _Nonnull)initWithData:(nullable NSData *)data - source:(FIRRemoteConfigSource)source NS_DESIGNATED_INITIALIZER; -@end - #pragma mark - FIRRemoteConfigSettings /// Firebase Remote Config settings. NS_SWIFT_NAME(RemoteConfigSettings) diff --git a/FirebaseRemoteConfig/Sources/RCNConfigSettings.m b/FirebaseRemoteConfig/Sources/RCNConfigSettings.m index 3bc86977fdb..19d6e6ca9ea 100644 --- a/FirebaseRemoteConfig/Sources/RCNConfigSettings.m +++ b/FirebaseRemoteConfig/Sources/RCNConfigSettings.m @@ -19,7 +19,6 @@ #import "FirebaseRemoteConfig/FirebaseRemoteConfig-Swift.h" #import "FirebaseRemoteConfig/Sources/RCNConfigConstants.h" -#import "FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h" #import #import "FirebaseCore/Extension/FirebaseCoreInternal.h" diff --git a/FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h b/FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h deleted file mode 100644 index c5a7d21e002..00000000000 --- a/FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h" - -NS_ASSUME_NONNULL_BEGIN -@interface FIRRemoteConfigValue () -@property(nonatomic, readwrite, assign) FIRRemoteConfigSource source; - -/// Designated initializer. -- (instancetype)initWithData:(nullable NSData *)data - source:(FIRRemoteConfigSource)source NS_DESIGNATED_INITIALIZER; -@end -NS_ASSUME_NONNULL_END diff --git a/FirebaseRemoteConfig/Sources/RCNPersonalization.m b/FirebaseRemoteConfig/Sources/RCNPersonalization.m index 0bcb41193bf..2c41fc30f25 100644 --- a/FirebaseRemoteConfig/Sources/RCNPersonalization.m +++ b/FirebaseRemoteConfig/Sources/RCNPersonalization.m @@ -16,8 +16,8 @@ #import "FirebaseRemoteConfig/Sources/RCNPersonalization.h" +#import "FirebaseRemoteConfig/FirebaseRemoteConfig-Swift.h" #import "FirebaseRemoteConfig/Sources/RCNConfigConstants.h" -#import "FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h" @implementation RCNPersonalization diff --git a/FirebaseRemoteConfig/SwiftNew/RemoteConfigValue.swift b/FirebaseRemoteConfig/SwiftNew/RemoteConfigValue.swift new file mode 100644 index 00000000000..609635db26a --- /dev/null +++ b/FirebaseRemoteConfig/SwiftNew/RemoteConfigValue.swift @@ -0,0 +1,77 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import FirebaseCore +import Foundation + +@objc(FIRRemoteConfigValue) +public class RemoteConfigValue: NSObject, NSCopying { + /// Data backing the config value. + @objc public let dataValue: Data + + /// Identifies the source of the fetched value. + @objc public let source: RemoteConfigSource + + /// Designated initializer + @objc public init(data: Data, source: RemoteConfigSource) { + dataValue = data + self.source = source + } + + /// Gets the value as a string. + @objc public var stringValue: String { + if let string = String(data: dataValue, encoding: .utf8) { + return string + } + return "" // Return empty string if data is not valid UTF-8 + } + + /// Gets the value as a number value. + @objc public var numberValue: NSNumber { + return NSNumber(value: Double(stringValue) ?? 0) + } + + /// Gets the value as a boolean. + @objc public var boolValue: Bool { + return (stringValue as NSString).boolValue + } + + /// Gets a foundation object (NSDictionary / NSArray) by parsing the value as JSON. + @objc(JSONValue) public var jsonValue: Any? { + guard !dataValue.isEmpty else { + return nil + } + do { + let jsonObject = try JSONSerialization.jsonObject(with: dataValue, options: []) + return jsonObject + } catch { + RCLog.debug("I-RCN000065", "Error parsing data as JSON.") + return nil + } + } + + /// Debug description showing the representations of all types. + override public var debugDescription: String { + let content = """ + Boolean: \(boolValue), String: \(stringValue), Number: \(numberValue), \ + JSON:\(String(describing: jsonValue)), Data: \(dataValue), Source: \(source.rawValue) + """ + return "<\(type(of: self)): \(Unmanaged.passUnretained(self).toOpaque()), \(content)>" + } + + /// Copy method. + @objc public func copy(with zone: NSZone? = nil) -> Any { + return RemoteConfigValue(data: dataValue, source: source) + } +} diff --git a/FirebaseRemoteConfig/Tests/Unit/RCNConfigContentTest.m b/FirebaseRemoteConfig/Tests/Unit/RCNConfigContentTest.m index 01661b12a44..ed68786784d 100644 --- a/FirebaseRemoteConfig/Tests/Unit/RCNConfigContentTest.m +++ b/FirebaseRemoteConfig/Tests/Unit/RCNConfigContentTest.m @@ -22,7 +22,6 @@ #import "FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h" #import "FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h" #import "FirebaseRemoteConfig/Sources/RCNConfigConstants.h" -#import "FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h" #import "FirebaseRemoteConfig/Tests/Unit/RCNTestUtilities.h" #import "FirebaseRemoteConfig/FirebaseRemoteConfig-Swift.h" diff --git a/FirebaseRemoteConfig/Tests/Unit/RCNConfigExperimentTest.m b/FirebaseRemoteConfig/Tests/Unit/RCNConfigExperimentTest.m index 2de42eb01cd..0c5de6eb45c 100644 --- a/FirebaseRemoteConfig/Tests/Unit/RCNConfigExperimentTest.m +++ b/FirebaseRemoteConfig/Tests/Unit/RCNConfigExperimentTest.m @@ -22,7 +22,6 @@ #import "FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h" #import "FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h" #import "FirebaseRemoteConfig/Sources/RCNConfigDefines.h" -#import "FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h" #import "FirebaseRemoteConfig/Tests/Unit/RCNTestUtilities.h" #import "FirebaseABTesting/Sources/Private/FirebaseABTestingInternal.h" diff --git a/FirebaseRemoteConfig/Tests/Unit/RCNConfigValueTest.m b/FirebaseRemoteConfig/Tests/Unit/RCNConfigValueTest.m index a12af9c13ee..912abe2b698 100644 --- a/FirebaseRemoteConfig/Tests/Unit/RCNConfigValueTest.m +++ b/FirebaseRemoteConfig/Tests/Unit/RCNConfigValueTest.m @@ -16,7 +16,7 @@ #import -#import "FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h" +@import FirebaseRemoteConfig; @interface FIRRemoteConfigValueTest : XCTestCase @end diff --git a/FirebaseRemoteConfig/Tests/Unit/RCNPersonalizationTest.m b/FirebaseRemoteConfig/Tests/Unit/RCNPersonalizationTest.m index 282f3f9193d..5219da1c5c5 100644 --- a/FirebaseRemoteConfig/Tests/Unit/RCNPersonalizationTest.m +++ b/FirebaseRemoteConfig/Tests/Unit/RCNPersonalizationTest.m @@ -23,7 +23,6 @@ // #import "FirebaseRemoteConfig/Sources/Private/FIRRemoteConfig_Private.h" #import "FirebaseRemoteConfig/Sources/Private/RCNConfigFetch.h" #import "FirebaseRemoteConfig/Sources/RCNConfigConstants.h" -#import "FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h" #import "FirebaseRemoteConfig/Sources/RCNPersonalization.h" #import "FirebaseRemoteConfig/Tests/Unit/RCNTestUtilities.h" #import "Interop/Analytics/Public/FIRAnalyticsInterop.h"