diff --git a/.github/workflows/google-utilities-components.yml b/.github/workflows/google-utilities-components.yml deleted file mode 100644 index 36b703b7b4d..00000000000 --- a/.github/workflows/google-utilities-components.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: google-utilities-components - -on: - pull_request: - paths: - - 'GoogleUtilitiesComponents**' - - '.github/workflows/google-utilities-components.yml' - - 'Gemfile*' - schedule: - # Run every day at 10pm (PST) - cron uses UTC times - - cron: '0 6 * * *' - - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} - cancel-in-progress: true - -jobs: - pod-lib-lint: - # Don't run on private repo unless it is a PR. - if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' - - runs-on: macos-14 - strategy: - matrix: - flags: [ - '', - '--use-static-frameworks' - ] - steps: - - uses: actions/checkout@v4 - - uses: ruby/setup-ruby@v1 - - name: Setup Bundler - run: scripts/setup_bundler.sh - - name: Build and test - run: | - scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb GoogleUtilitiesComponents.podspec ${{ matrix.flags }} diff --git a/GoogleUtilitiesComponents.podspec b/GoogleUtilitiesComponents.podspec deleted file mode 100644 index 227bbe5a86d..00000000000 --- a/GoogleUtilitiesComponents.podspec +++ /dev/null @@ -1,39 +0,0 @@ -Pod::Spec.new do |s| - s.name = 'GoogleUtilitiesComponents' - s.version = '2.0.0' - s.summary = 'Google Utilities Component Container for Apple platforms.' - - s.description = <<-DESC -An internal Google utility that is a dependency injection system for libraries to depend on other -libraries in a type safe and potentially weak manner. -Not intended for direct public usage. - DESC - - s.homepage = 'https://developers.google.com/' - s.license = { :type => 'Apache-2.0', :file => 'LICENSE' } - s.authors = 'Google, Inc.' - - s.source = { - :git => 'https://github.com/firebase/firebase-ios-sdk.git', - :tag => 'UtilitiesComponents-' + s.version.to_s - } - - s.ios.deployment_target = '12.0' - - s.cocoapods_version = '>= 1.12.0' - s.prefix_header_file = false - s.static_framework = true - - s.source_files = 'GoogleUtilitiesComponents/Sources/**/*.[mh]' - s.public_header_files = 'GoogleUtilitiesComponents/Sources/Public/*.h', 'GoogleUtilitiesComponents/Sources/Private/*.h' - s.private_header_files = 'GoogleUtilitiesComponents/Sources/Private/*.h' - s.dependency 'GoogleUtilities/Logger', "~> 8.0" - - s.test_spec 'unit' do |unit_tests| - unit_tests.scheme = { :code_coverage => true } - unit_tests.source_files = 'GoogleUtilitiesComponents/Tests/**/*.[mh]' - unit_tests.requires_arc = 'GoogleUtilitiesComponents/Tests/*/*.[mh]' - unit_tests.requires_app_host = true - unit_tests.dependency 'OCMock' - end -end diff --git a/GoogleUtilitiesComponents/Sources/GULCCComponent.m b/GoogleUtilitiesComponents/Sources/GULCCComponent.m deleted file mode 100644 index 34508ce9323..00000000000 --- a/GoogleUtilitiesComponents/Sources/GULCCComponent.m +++ /dev/null @@ -1,65 +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 "Public/GULCCComponent.h" - -#import "Public/GULCCComponentContainer.h" -#import "Public/GULCCDependency.h" - -@interface GULCCComponent () - -- (instancetype)initWithProtocol:(Protocol *)protocol - instantiationTiming:(GULCCInstantiationTiming)instantiationTiming - dependencies:(NSArray *)dependencies - creationBlock:(GULCCComponentCreationBlock)creationBlock; - -@end - -@implementation GULCCComponent - -+ (instancetype)componentWithProtocol:(Protocol *)protocol - creationBlock:(GULCCComponentCreationBlock)creationBlock { - return [[GULCCComponent alloc] initWithProtocol:protocol - instantiationTiming:GULCCInstantiationTimingLazy - dependencies:@[] - creationBlock:creationBlock]; -} - -+ (instancetype)componentWithProtocol:(Protocol *)protocol - instantiationTiming:(GULCCInstantiationTiming)instantiationTiming - dependencies:(NSArray *)dependencies - creationBlock:(GULCCComponentCreationBlock)creationBlock { - return [[GULCCComponent alloc] initWithProtocol:protocol - instantiationTiming:instantiationTiming - dependencies:dependencies - creationBlock:creationBlock]; -} - -- (instancetype)initWithProtocol:(Protocol *)protocol - instantiationTiming:(GULCCInstantiationTiming)instantiationTiming - dependencies:(NSArray *)dependencies - creationBlock:(GULCCComponentCreationBlock)creationBlock { - self = [super init]; - if (self) { - _protocol = protocol; - _instantiationTiming = instantiationTiming; - _dependencies = [dependencies copy]; - _creationBlock = creationBlock; - } - return self; -} - -@end diff --git a/GoogleUtilitiesComponents/Sources/GULCCComponentContainer.m b/GoogleUtilitiesComponents/Sources/GULCCComponentContainer.m deleted file mode 100644 index 61d571d7f0a..00000000000 --- a/GoogleUtilitiesComponents/Sources/GULCCComponentContainer.m +++ /dev/null @@ -1,208 +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 "Public/GULCCComponentContainer.h" - -#import "Public/GULCCComponent.h" -#import "Public/GULCCLibrary.h" - -#import - -static NSString *kGULComponentSubsystem = @"com.google.googleutilitiescomponents"; -static NSString *kGULComponentContainer = @"[GoogleUtilitiesComponents]"; - -NS_ASSUME_NONNULL_BEGIN - -@interface GULCCComponentContainer () - -/// The dictionary of components that are registered for a particular app. The key is an `NSString` -/// of the protocol. -@property(nonatomic, strong) - NSMutableDictionary *components; - -/// Cached instances of components that requested to be cached. -@property(nonatomic, strong) NSMutableDictionary *cachedInstances; - -/// Protocols of components that have requested to be eagerly instantiated. -@property(nonatomic, strong, nullable) NSMutableArray *eagerProtocolsToInstantiate; - -@end - -@implementation GULCCComponentContainer - -// Collection of all classes that register to provide components. -static NSMutableSet *sGULComponentRegistrants; - -#pragma mark - Public Registration - -+ (void)registerAsComponentRegistrant:(Class)klass { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sGULComponentRegistrants = [[NSMutableSet alloc] init]; - }); - - [self registerAsComponentRegistrant:klass inSet:sGULComponentRegistrants]; -} - -+ (void)registerAsComponentRegistrant:(Class)klass - inSet:(NSMutableSet *)allRegistrants { - [allRegistrants addObject:klass]; -} - -#pragma mark - Internal Initialization - -- (instancetype)initWithContext:(nullable id)context { - return [self initWithContext:context registrants:sGULComponentRegistrants]; -} - -- (instancetype)initWithContext:(nullable id)context - registrants:(NSMutableSet *)allRegistrants { - self = [super init]; - if (self) { - _context = context; - _cachedInstances = [NSMutableDictionary dictionary]; - _components = [NSMutableDictionary dictionary]; - - [self populateComponentsFromRegisteredClasses:allRegistrants withContext:context]; - } - return self; -} - -- (void)populateComponentsFromRegisteredClasses:(NSSet *)classes withContext:(id)context { - // Keep track of any components that need to eagerly instantiate after all components are added. - self.eagerProtocolsToInstantiate = [[NSMutableArray alloc] init]; - - // Loop through the verified component registrants and populate the components array. - for (Class klass in classes) { - // Loop through all the components being registered and store them as appropriate. - // Classes which do not provide functionality should use a dummy GULCCComponentRegistrant - // protocol. - for (GULCCComponent *component in [klass componentsToRegister]) { - // Check if the component has been registered before, and error out if so. - NSString *protocolName = NSStringFromProtocol(component.protocol); - if (self.components[protocolName]) { - GULOSLogError(kGULComponentSubsystem, kGULComponentContainer, NO, @"I-COM000001", - @"Attempted to register protocol %@, but it already has an implementation.", - protocolName); - continue; - } - - // Store the creation block for later usage. - self.components[protocolName] = component.creationBlock; - - // Queue any protocols that should be eagerly instantiated. Don't instantiate them yet - // because they could depend on other components that haven't been added to the components - // array yet. - if (component.instantiationTiming == GULCCInstantiationTimingAlwaysEager) { - [self.eagerProtocolsToInstantiate addObject:component.protocol]; - } - } - } -} - -#pragma mark - Instance Creation - -- (void)instantiateEagerComponents { - // After all components are registered, instantiate the ones that are requesting eager - // instantiation. - @synchronized(self) { - for (Protocol *protocol in self.eagerProtocolsToInstantiate) { - // Get an instance for the protocol, which will instantiate it since it couldn't have been - // cached yet. Ignore the instance coming back since we don't need it. - __unused id unusedInstance = [self instanceForProtocol:protocol]; - } - - // All eager instantiation is complete, clear the stored property now. - self.eagerProtocolsToInstantiate = nil; - } -} - -/// Instantiate an instance of a class that conforms to the specified protocol. -/// This will: -/// - Call the block to create an instance if possible, -/// - Validate that the instance returned conforms to the protocol it claims to, -/// - Cache the instance if the block requests it -/// -/// Note that this method assumes the caller already has @synchronized on self. -- (nullable id)instantiateInstanceForProtocol:(Protocol *)protocol - withBlock:(GULCCComponentCreationBlock)creationBlock { - if (!creationBlock) { - return nil; - } - - // Create an instance using the creation block. - BOOL shouldCache = NO; - id instance = creationBlock(self, &shouldCache); - if (!instance) { - return nil; - } - - // An instance was created, validate that it conforms to the protocol it claims to. - NSString *protocolName = NSStringFromProtocol(protocol); - if (![instance conformsToProtocol:protocol]) { - GULOSLogError(kGULComponentSubsystem, kGULComponentContainer, NO, @"I-COM000002", - @"An instance conforming to %@ was requested, but the instance provided does not " - @"conform to the protocol", - protocolName); - } - - // The instance is ready to be returned, but check if it should be cached first before returning. - if (shouldCache) { - self.cachedInstances[protocolName] = instance; - } - - return instance; -} - -#pragma mark - Internal Retrieval - -- (nullable id)instanceForProtocol:(Protocol *)protocol { - // Check if there is a cached instance, and return it if so. - NSString *protocolName = NSStringFromProtocol(protocol); - - id cachedInstance; - @synchronized(self) { - cachedInstance = self.cachedInstances[protocolName]; - if (!cachedInstance) { - // Use the creation block to instantiate an instance and return it. - GULCCComponentCreationBlock creationBlock = self.components[protocolName]; - cachedInstance = [self instantiateInstanceForProtocol:protocol withBlock:creationBlock]; - } - } - return cachedInstance; -} - -#pragma mark - Lifecycle - -- (void)removeAllCachedInstances { - @synchronized(self) { - // Loop through the cache and notify each instance that is a maintainer to clean up after - // itself. - for (id instance in self.cachedInstances.allValues) { - if ([instance conformsToProtocol:@protocol(GULCCComponentLifecycleMaintainer)] && - [instance respondsToSelector:@selector(containerWillBeEmptied:)]) { - [instance containerWillBeEmptied:self]; - } - } - - // Empty the cache. - [self.cachedInstances removeAllObjects]; - } -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/GoogleUtilitiesComponents/Sources/GULCCComponentType.m b/GoogleUtilitiesComponents/Sources/GULCCComponentType.m deleted file mode 100644 index b1f36052671..00000000000 --- a/GoogleUtilitiesComponents/Sources/GULCCComponentType.m +++ /dev/null @@ -1,28 +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 "Public/GULCCComponentType.h" - -#import "Private/GULCCComponentContainerInternal.h" - -@implementation GULCCComponentType - -+ (id)instanceForProtocol:(Protocol *)protocol inContainer:(GULCCComponentContainer *)container { - // Forward the call to the container. - return [container instanceForProtocol:protocol]; -} - -@end diff --git a/GoogleUtilitiesComponents/Sources/GULCCDependency.m b/GoogleUtilitiesComponents/Sources/GULCCDependency.m deleted file mode 100644 index 9d0415153ed..00000000000 --- a/GoogleUtilitiesComponents/Sources/GULCCDependency.m +++ /dev/null @@ -1,44 +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 "Public/GULCCDependency.h" - -@interface GULCCDependency () - -- (instancetype)initWithProtocol:(Protocol *)protocol isRequired:(BOOL)required; - -@end - -@implementation GULCCDependency - -+ (instancetype)dependencyWithProtocol:(Protocol *)protocol { - return [[self alloc] initWithProtocol:protocol isRequired:YES]; -} - -+ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required { - return [[self alloc] initWithProtocol:protocol isRequired:required]; -} - -- (instancetype)initWithProtocol:(Protocol *)protocol isRequired:(BOOL)required { - self = [super init]; - if (self) { - _protocol = protocol; - _isRequired = required; - } - return self; -} - -@end diff --git a/GoogleUtilitiesComponents/Sources/Private/GULCCComponentContainerInternal.h b/GoogleUtilitiesComponents/Sources/Private/GULCCComponentContainerInternal.h deleted file mode 100644 index fdc39d562a2..00000000000 --- a/GoogleUtilitiesComponents/Sources/Private/GULCCComponentContainerInternal.h +++ /dev/null @@ -1,48 +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 - -#import "GULCCComponent.h" -#import "GULCCComponentContainer.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface GULCCComponentContainer (Private) - -/// Initializes a container with a context. -- (instancetype)initWithContext:(nullable id)context; - -/// Initializes a container with a context and a given set of registered `GULLibraries`. -- (instancetype)initWithContext:(nullable id)context - registrants:(NSMutableSet *)allRegistrants; - -/// Retrieves an instance that conforms to the specified protocol. This will return `nil` if the -/// protocol wasn't registered, or if the instance couldn't be instantiated for the provided app. -- (nullable id)instanceForProtocol:(Protocol *)protocol NS_SWIFT_NAME(instance(for:)); - -/// Instantiates all the components that have registered as "eager" after initialization. -- (void)instantiateEagerComponents; - -/// Remove all of the cached instances stored and allow them to clean up after themselves. -- (void)removeAllCachedInstances; - -/// Register a class to provide components for the interoperability system. The class should conform -/// to `GULCCComponentRegistrant` and provide an array of `GULCCComponent` objects. -+ (void)registerAsComponentRegistrant:(Class)klass; - -@end - -NS_ASSUME_NONNULL_END diff --git a/GoogleUtilitiesComponents/Sources/Public/GULCCComponent.h b/GoogleUtilitiesComponents/Sources/Public/GULCCComponent.h deleted file mode 100644 index 386a8f9ce5f..00000000000 --- a/GoogleUtilitiesComponents/Sources/Public/GULCCComponent.h +++ /dev/null @@ -1,90 +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 - -@class GULCCComponentContainer; - -NS_ASSUME_NONNULL_BEGIN - -/// Provides a system to clean up cached instances returned from the component system. -NS_SWIFT_NAME(ComponentLifecycleMaintainer) -@protocol GULCCComponentLifecycleMaintainer -/// Clean up any resources as they are about to be deallocated. -- (void)containerWillBeEmptied:(GULCCComponentContainer *)container; -@end - -typedef _Nullable id (^GULCCComponentCreationBlock)(GULCCComponentContainer *container, - BOOL *isCacheable) - NS_SWIFT_NAME(ComponentCreationBlock); - -@class GULCCDependency; - -/// Describes the timing of instantiation. Note: new components should default to lazy unless there -/// is a strong reason to be eager. -typedef NS_ENUM(NSInteger, GULCCInstantiationTiming) { - GULCCInstantiationTimingLazy, - GULCCInstantiationTimingAlwaysEager -} NS_SWIFT_NAME(InstantiationTiming); - -/// A component that can be used from other components. -NS_SWIFT_NAME(Component) -@interface GULCCComponent : NSObject - -/// The protocol describing functionality provided from the Component. -@property(nonatomic, strong, readonly) Protocol *protocol; - -/// The timing of instantiation. -@property(nonatomic, readonly) GULCCInstantiationTiming instantiationTiming; - -/// An array of dependencies for the component. -@property(nonatomic, copy, readonly) NSArray *dependencies; - -/// A block to instantiate an instance of the component with the appropriate dependencies. -@property(nonatomic, copy, readonly) GULCCComponentCreationBlock creationBlock; - -// There's an issue with long NS_SWIFT_NAMES that causes compilation to fail, disable clang-format -// for the next two methods. -// clang-format off - -/// Creates a component with no dependencies that will be lazily initialized. -+ (instancetype)componentWithProtocol:(Protocol *)protocol - creationBlock:(GULCCComponentCreationBlock)creationBlock -NS_SWIFT_NAME(init(_:creationBlock:)); - -/// Creates a component to be registered with the component container. -/// -/// @param protocol - The protocol describing functionality provided by the component. -/// @param instantiationTiming - When the component should be initialized. Use .lazy unless there's -/// a good reason to be instantiated earlier. -/// @param dependencies - Any dependencies the `implementingClass` has, optional or required. -/// @param creationBlock - A block to instantiate the component with a container and a flag to cache -/// the instance created or not. -/// @return A component that can be registered with the component container. -+ (instancetype)componentWithProtocol:(Protocol *)protocol - instantiationTiming:(GULCCInstantiationTiming)instantiationTiming - dependencies:(NSArray *)dependencies - creationBlock:(GULCCComponentCreationBlock)creationBlock -NS_SWIFT_NAME(init(_:instantiationTiming:dependencies:creationBlock:)); - -// clang-format on - -/// Unavailable. -- (instancetype)init NS_UNAVAILABLE; - -@end - -NS_ASSUME_NONNULL_END diff --git a/GoogleUtilitiesComponents/Sources/Public/GULCCComponentContainer.h b/GoogleUtilitiesComponents/Sources/Public/GULCCComponentContainer.h deleted file mode 100644 index 179032b805a..00000000000 --- a/GoogleUtilitiesComponents/Sources/Public/GULCCComponentContainer.h +++ /dev/null @@ -1,41 +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 - -#import "GULCCComponentType.h" -#import "GULCCLibrary.h" - -NS_ASSUME_NONNULL_BEGIN - -/// A type-safe macro to retrieve a component from a container. This should be used to retrieve -/// components instead of using the container directly. -#define GUL_COMPONENT(type, container) \ - [GULCCComponentType> instanceForProtocol:@protocol(type) inContainer:container] - -/// A container that holds different components that are registered via the -/// `registerAsComponentRegistrant:` call. These classes should conform to -/// `GULCCComponentRegistrant` in order to properly register components for the container. -NS_SWIFT_NAME(GoogleComponentContainer) -@interface GULCCComponentContainer : NSObject - -/// A weak reference to an object that may provide context for the container. -@property(nonatomic, nullable, weak, readonly) id context; - -- (instancetype)init NS_UNAVAILABLE; - -@end - -NS_ASSUME_NONNULL_END diff --git a/GoogleUtilitiesComponents/Sources/Public/GULCCComponentType.h b/GoogleUtilitiesComponents/Sources/Public/GULCCComponentType.h deleted file mode 100644 index 8fa90894087..00000000000 --- a/GoogleUtilitiesComponents/Sources/Public/GULCCComponentType.h +++ /dev/null @@ -1,34 +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 - -@class GULCCComponentContainer; - -NS_ASSUME_NONNULL_BEGIN - -/// Do not use directly. A placeholder type in order to provide a macro that will warn users of -/// mis-matched protocols. -NS_SWIFT_NAME(ComponentType) -@interface GULCCComponentType<__covariant T> : NSObject - -/// Do not use directly. A factory method to retrieve an instance that provides a specific -/// functionality. -+ (T)instanceForProtocol:(Protocol *)protocol inContainer:(GULCCComponentContainer *)container; - -@end - -NS_ASSUME_NONNULL_END diff --git a/GoogleUtilitiesComponents/Sources/Public/GULCCDependency.h b/GoogleUtilitiesComponents/Sources/Public/GULCCDependency.h deleted file mode 100644 index e2d7d64dd8f..00000000000 --- a/GoogleUtilitiesComponents/Sources/Public/GULCCDependency.h +++ /dev/null @@ -1,45 +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 - -NS_ASSUME_NONNULL_BEGIN - -/// A dependency on a specific protocol's functionality. -NS_SWIFT_NAME(Dependency) -@interface GULCCDependency : NSObject - -/// The protocol describing functionality being depended on. -@property(nonatomic, strong, readonly) Protocol *protocol; - -/// A flag to specify if the dependency is required or not. -@property(nonatomic, readonly) BOOL isRequired; - -/// Initializes a dependency that is required. Calls `initWithProtocol:isRequired` with `YES` for -/// the required parameter. -/// Creates a required dependency on the specified protocol's functionality. -+ (instancetype)dependencyWithProtocol:(Protocol *)protocol; - -/// Creates a dependency on the specified protocol's functionality and specify if it's required for -/// the class's functionality. -+ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required; - -/// Use `dependencyWithProtocol:isRequired:` instead. -- (instancetype)init NS_UNAVAILABLE; - -@end - -NS_ASSUME_NONNULL_END diff --git a/GoogleUtilitiesComponents/Sources/Public/GULCCLibrary.h b/GoogleUtilitiesComponents/Sources/Public/GULCCLibrary.h deleted file mode 100644 index bf8d4e72d60..00000000000 --- a/GoogleUtilitiesComponents/Sources/Public/GULCCLibrary.h +++ /dev/null @@ -1,37 +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. - */ - -#ifndef GULLibrary_h -#define GULLibrary_h - -#import -#import "GULCCComponent.h" - -NS_ASSUME_NONNULL_BEGIN - -/// Provide an interface to register a library for userAgent logging and availability to others. -NS_SWIFT_NAME(Library) -@protocol GULCCLibrary - -/// Returns one or more GULComponents that will be registered in the container and participate in -/// dependency resolution and injection. -+ (NSArray *)componentsToRegister; - -@end - -NS_ASSUME_NONNULL_END - -#endif /* GULLibrary_h */ diff --git a/GoogleUtilitiesComponents/Tests/GULCCComponentContainerTest.m b/GoogleUtilitiesComponents/Tests/GULCCComponentContainerTest.m deleted file mode 100644 index 7282bf50455..00000000000 --- a/GoogleUtilitiesComponents/Tests/GULCCComponentContainerTest.m +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright 2018 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 - -#import -#import - -#import "GULCCTestComponents.h" - -/// Internally exposed methods and properties for testing. -@interface GULCCComponentContainer (TestInternal) - -@property(nonatomic, strong) - NSMutableDictionary *components; -@property(nonatomic, strong) NSMutableDictionary *cachedInstances; - -+ (void)registerAsComponentRegistrant:(Class)klass - inSet:(NSMutableSet *)allRegistrants; - -@end - -@interface GULCCComponentContainer (TestInternalImplementations) -- (instancetype)initWithContext:(id)context - components:(NSDictionary *)components; -@end - -@implementation GULCCComponentContainer (TestInternalImplementations) - -- (instancetype)initWithContext:(id)context - components: - (NSDictionary *)components { - self = [self initWithContext:context registrants:[[NSMutableSet alloc] init]]; - if (self) { - self.components = [components mutableCopy]; - } - return self; -} - -@end - -@interface GULCCComponentContainerTest : XCTestCase { - /// Stored context, since the container has a `weak` reference to it. - id _context; -} - -@end - -@implementation GULCCComponentContainerTest - -- (void)tearDown { - _context = nil; - [super tearDown]; -} - -#pragma mark - Registration Tests - -- (void)testRegisteringConformingClass { - NSMutableSet *allRegistrants = [NSMutableSet set]; - Class testClass = [GULCCTestClass class]; - [GULCCComponentContainer registerAsComponentRegistrant:testClass inSet:allRegistrants]; - XCTAssertTrue([allRegistrants containsObject:testClass]); -} - -- (void)testComponentsPopulatedOnInit { - GULCCComponentContainer *container = [self containerWithRegistrants:@[ [GULCCTestClass class] ]]; - - // Verify that the block is stored. - NSString *protocolName = NSStringFromProtocol(@protocol(GULCCTestProtocol)); - GULCCComponentCreationBlock creationBlock = container.components[protocolName]; - XCTAssertNotNil(creationBlock); -} - -#pragma mark - Caching Tests - -- (void)testInstanceCached { - GULCCComponentContainer *container = - [self containerWithRegistrants:@[ [GULCCTestClassCached class] ]]; - - // Fetch an instance for `GULCCTestProtocolCached`, then fetch it again to assert it's cached. - id instance1 = GUL_COMPONENT(GULCCTestProtocolCached, container); - XCTAssertNotNil(instance1); - id instance2 = GUL_COMPONENT(GULCCTestProtocolCached, container); - XCTAssertNotNil(instance2); - XCTAssertEqual(instance1, instance2); -} - -- (void)testInstanceNotCached { - GULCCComponentContainer *container = [self containerWithRegistrants:@[ [GULCCTestClass class] ]]; - - // Retrieve an instance from the container, then fetch it again and ensure it's not the same - // instance. - id instance1 = GUL_COMPONENT(GULCCTestProtocol, container); - XCTAssertNotNil(instance1); - id instance2 = GUL_COMPONENT(GULCCTestProtocol, container); - XCTAssertNotNil(instance2); - XCTAssertNotEqual(instance1, instance2); -} - -- (void)testRemoveAllCachedInstances { - GULCCComponentContainer *container = [self containerWithRegistrants:@[ - [GULCCTestClass class], [GULCCTestClassCached class], [GULCCTestClassEagerCached class], - [GULCCTestClassCachedWithDep class] - ]]; - - // Retrieve an instance of GULCCTestClassCached to ensure it's cached. - id cachedInstance1 = GUL_COMPONENT(GULCCTestProtocolCached, container); - id eagerInstance1 = - GUL_COMPONENT(GULCCTestProtocolEagerCached, container); - - // GULCCTestClassEagerCached and GULCCTestClassCached instances should be cached at this point. - XCTAssertTrue(container.cachedInstances.count == 2); - - // Remove the instances and verify cachedInstances is empty, and that new instances returned from - // the container don't match the old ones. - [container removeAllCachedInstances]; - XCTAssertTrue(container.cachedInstances.count == 0); - - id cachedInstance2 = GUL_COMPONENT(GULCCTestProtocolCached, container); - XCTAssertNotEqual(cachedInstance1, cachedInstance2); - id eagerInstance2 = - GUL_COMPONENT(GULCCTestProtocolEagerCached, container); - XCTAssertNotEqual(eagerInstance1, eagerInstance2); -} - -#pragma mark - Instantiation Tests - -- (void)testEagerInstantiation { - // Create a container with `GULCCTestClassEagerCached` as a registrant, which provides the - // implementation for `GULCCTestProtocolEagerCached` and requires eager instantiation as well as - // caching so the test can verify it was eagerly instantiated. - GULCCComponentContainer *container = - [self containerWithRegistrants:@[ [GULCCTestClassEagerCached class] ]]; - NSString *protocolName = NSStringFromProtocol(@protocol(GULCCTestProtocolEagerCached)); - XCTAssertNotNil(container.cachedInstances[protocolName]); -} - -#pragma mark - Input Validation Tests - -- (void)testProtocolAlreadyRegistered { - // Register two classes that provide the same protocol. Only one should be stored, and there - // should be a log stating that the protocol has already been registered. Right now there's no - // guarantee which one will be registered first since it's an NSSet under the hood, but that could - // change in the future. - // TODO(wilsonryan): Assert that the log gets called warning that it's already been registered. - GULCCComponentContainer *container = - [self containerWithRegistrants:@[ [GULCCTestClass class], [GULCCTestClassDuplicate class] ]]; - XCTAssert(container.components.count == 1); -} - -#pragma mark - Dependency Tests - -- (void)testDependencyDoesntBlock { - /// Test a class that has a dependency, and fetching doesn't block the internal queue. - GULCCComponentContainer *container = [self containerWithRegistrants:@[ - [GULCCTestClassCached class], [GULCCTestClassCachedWithDep class] - ]]; - XCTAssert(container.components.count == 2); - - id instanceWithDep = - GUL_COMPONENT(GULCCTestProtocolCachedWithDep, container); - XCTAssertNotNil(instanceWithDep); -} - -- (void)testDependencyRemoveAllCachedInstancesDoesntBlock { - /// Test a class that has a dependency, and fetching doesn't block the internal queue. - GULCCComponentContainer *container = [self containerWithRegistrants:@[ - [GULCCTestClassCached class], [GULCCTestClassCachedWithDep class] - ]]; - XCTAssert(container.components.count == 2); - - id instanceWithDep = - GUL_COMPONENT(GULCCTestProtocolCachedWithDep, container); - XCTAssertNotNil(instanceWithDep); - XCTAssertNotNil(instanceWithDep.testProperty); - - // Both `instanceWithDep` and `testProperty` should be cached now. - XCTAssertTrue(container.cachedInstances.count == 2); - - // Remove the instances and verify cachedInstances is empty, and doesn't block the queue. - [container removeAllCachedInstances]; - XCTAssertTrue(container.cachedInstances.count == 0); -} - -#pragma mark - Convenience Methods - -/// Create a container that has registered the test class. -- (GULCCComponentContainer *)containerWithRegistrants:(NSArray *)registrants { - NSMutableSet *allRegistrants = [NSMutableSet set]; - - // Initialize the container with the test classes. - for (Class c in registrants) { - [GULCCComponentContainer registerAsComponentRegistrant:c inSet:allRegistrants]; - } - - GULCCComponentContainer *container = - [[GULCCComponentContainer alloc] initWithContext:nil registrants:allRegistrants]; - - // Instantiate all the components that were eagerly registered now that all other properties are - // configured. - [container instantiateEagerComponents]; - - return container; -} - -@end diff --git a/GoogleUtilitiesComponents/Tests/GULCCComponentTypeTest.m b/GoogleUtilitiesComponents/Tests/GULCCComponentTypeTest.m deleted file mode 100644 index 8d11887c0a6..00000000000 --- a/GoogleUtilitiesComponents/Tests/GULCCComponentTypeTest.m +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2018 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 - -#import -#import -#import - -#import "GULCCTestComponents.h" - -@interface GULComponentTypeTest : XCTestCase - -@property(nonatomic, strong) id componentContainerMock; -@end - -@implementation GULComponentTypeTest - -- (void)setUp { - [super setUp]; - _componentContainerMock = OCMClassMock([GULCCComponentContainer class]); -} - -- (void)tearDown { - [super tearDown]; - [_componentContainerMock stopMocking]; -} - -- (void)testForwardsCallToContainer { - Protocol *testProtocol = @protocol(GULCCTestProtocol); - OCMExpect([self.componentContainerMock instanceForProtocol:testProtocol]); - - // Grab an instance from the container, through ComponentType. - __unused id instance = - [GULCCComponentType> instanceForProtocol:@protocol(GULCCTestProtocol) - inContainer:self.componentContainerMock]; - OCMVerifyAll(self.componentContainerMock); -} - -- (void)testMacroForwardsCallToContainer { - Protocol *testProtocol = @protocol(GULCCTestProtocol); - OCMExpect([self.componentContainerMock instanceForProtocol:testProtocol]); - - // Grab an instance from the container, through the macro that uses GULCCComponentType. - __unused id instance = - GUL_COMPONENT(GULCCTestProtocol, self.componentContainerMock); - - OCMVerifyAll(self.componentContainerMock); -} -@end diff --git a/GoogleUtilitiesComponents/Tests/GULCCTestComponents.h b/GoogleUtilitiesComponents/Tests/GULCCTestComponents.h deleted file mode 100644 index 7ab19233a6a..00000000000 --- a/GoogleUtilitiesComponents/Tests/GULCCTestComponents.h +++ /dev/null @@ -1,77 +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 - -#import -#import -#import - -#pragma mark - Standard Component - -/// A test protocol to be used for container testing. -@protocol GULCCTestProtocol -- (void)doSomething; -@end - -/// A test class that is a component registrant. -@interface GULCCTestClass - : NSObject -@end - -/// A test class that is a component registrant, a duplicate of GULCCTestClass. -@interface GULCCTestClassDuplicate - : NSObject -@end - -#pragma mark - Eager Component - -/// A test protocol to be used for container testing. -@protocol GULCCTestProtocolEagerCached -- (void)doSomethingFaster; -@end - -/// A test class that is a component registrant that provides a component requiring eager -/// instantiation, and is cached for easier validation that it was instantiated. -@interface GULCCTestClassEagerCached - : NSObject -@end - -#pragma mark - Cached Component - -/// A test protocol to be used for container testing. -@protocol GULCCTestProtocolCached -- (void)cacheCow; -@end - -/// A test class that is a component registrant that provides a component that requests to be -/// cached. -@interface GULCCTestClassCached - : NSObject -@end - -#pragma mark - Dependency on Standard - -/// A test protocol to be used for container testing. -@protocol GULCCTestProtocolCachedWithDep -@property(nonatomic, strong) id testProperty; -@end - -/// A test class that is a component registrant that provides a component with a dependency on -// `GULCCTestProtocolCached`. -@interface GULCCTestClassCachedWithDep - : NSObject -@property(nonatomic, strong) id testProperty; -- (instancetype)initWithTest:(id)testInstance; -@end diff --git a/GoogleUtilitiesComponents/Tests/GULCCTestComponents.m b/GoogleUtilitiesComponents/Tests/GULCCTestComponents.m deleted file mode 100644 index 7a4945fb405..00000000000 --- a/GoogleUtilitiesComponents/Tests/GULCCTestComponents.m +++ /dev/null @@ -1,167 +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 "GULCCTestComponents.h" - -#import -#import - -#pragma mark - Standard Component - -@implementation GULCCTestClass - -/// GULCCTestProtocol conformance. -- (void)doSomething { -} - -/// GULCCLibrary conformance. -+ (nonnull NSArray *)componentsToRegister { - GULCCComponent *testComponent = [GULCCComponent - componentWithProtocol:@protocol(GULCCTestProtocol) - creationBlock:^id _Nullable(GULCCComponentContainer *_Nonnull container, - BOOL *_Nonnull isCacheable) { - return [[GULCCTestClass alloc] init]; - }]; - return @[ testComponent ]; -} - -/// GULCCComponentLifecycleMaintainer conformance. -- (void)containerWillBeEmptied:(GULCCComponentContainer *)container { -} - -@end - -/// A test class that is a component registrant, a duplicate of GULCCTestClass. -@implementation GULCCTestClassDuplicate - -- (void)doSomething { -} - -/// GULCCLibrary conformance. -+ (nonnull NSArray *)componentsToRegister { - GULCCComponent *testComponent = [GULCCComponent - componentWithProtocol:@protocol(GULCCTestProtocol) - creationBlock:^id _Nullable(GULCCComponentContainer *_Nonnull container, - BOOL *_Nonnull isCacheable) { - return [[GULCCTestClassDuplicate alloc] init]; - }]; - return @[ testComponent ]; -} - -/// GULCCComponentLifecycleMaintainer conformance. -- (void)containerWillBeEmptied:(GULCCComponentContainer *)container { -} - -@end - -#pragma mark - Eager Component - -@implementation GULCCTestClassEagerCached - -/// GULCCTestProtocolEager conformance. -- (void)doSomethingFaster { -} - -/// GULCCLibrary conformance. -+ (nonnull NSArray *)componentsToRegister { - GULCCComponent *testComponent = [GULCCComponent - componentWithProtocol:@protocol(GULCCTestProtocolEagerCached) - instantiationTiming:GULCCInstantiationTimingAlwaysEager - dependencies:@[] - creationBlock:^id _Nullable(GULCCComponentContainer *_Nonnull container, - BOOL *_Nonnull isCacheable) { - GULCCTestClassEagerCached *instance = [[GULCCTestClassEagerCached alloc] init]; - *isCacheable = YES; - [instance doSomethingFaster]; - return instance; - }]; - return @[ testComponent ]; -} - -/// GULCCComponentLifecycleMaintainer conformance. -- (void)containerWillBeEmptied:(GULCCComponentContainer *)container { -} - -@end - -#pragma mark - Cached Component - -@implementation GULCCTestClassCached - -/// GULCCLibrary conformance. -+ (nonnull NSArray *)componentsToRegister { - GULCCComponent *testComponent = [GULCCComponent - componentWithProtocol:@protocol(GULCCTestProtocolCached) - creationBlock:^id _Nullable(GULCCComponentContainer *_Nonnull container, - BOOL *_Nonnull isCacheable) { - GULCCTestClassCached *instanceToCache = [[GULCCTestClassCached alloc] init]; - *isCacheable = YES; - return instanceToCache; - }]; - return @[ testComponent ]; -} - -/// GULCCComponentLifecycleMaintainer conformance. -- (void)containerWillBeEmptied:(GULCCComponentContainer *)container { -} - -/// GULCCTestProtocolCached conformance. -- (void)cacheCow { -} - -@end - -#pragma mark - Test Component with Dependency - -@implementation GULCCTestClassCachedWithDep - -- (instancetype)initWithTest:(id)testInstance { - self = [super init]; - if (self != nil) { - self.testProperty = testInstance; - } - return self; -} - -- (void)containerWillBeEmptied:(GULCCComponentContainer *)container { - // Do something that depends on the instance from our dependency. - [self.testProperty cacheCow]; - - // Fetch from the container in the deletion function. - id anotherInstance = GUL_COMPONENT(GULCCTestProtocolCached, container); - [anotherInstance cacheCow]; -} - -+ (nonnull NSArray *)componentsToRegister { - GULCCDependency *dep = - [GULCCDependency dependencyWithProtocol:@protocol(GULCCTestProtocolCached)]; - GULCCComponent *testComponent = [GULCCComponent - componentWithProtocol:@protocol(GULCCTestProtocolCachedWithDep) - instantiationTiming:GULCCInstantiationTimingLazy - dependencies:@[ dep ] - creationBlock:^id _Nullable(GULCCComponentContainer *_Nonnull container, - BOOL *_Nonnull isCacheable) { - // Fetch from the container in the instantiation block. - *isCacheable = YES; - - id test = - GUL_COMPONENT(GULCCTestProtocolCached, container); - GULCCTestClassCachedWithDep *instance = - [[GULCCTestClassCachedWithDep alloc] initWithTest:test]; - return instance; - }]; - return @[ testComponent ]; -} - -@end diff --git a/SymbolCollisionTest/Podfile b/SymbolCollisionTest/Podfile index 2d92ae6638e..95dfd255f4c 100644 --- a/SymbolCollisionTest/Podfile +++ b/SymbolCollisionTest/Podfile @@ -27,7 +27,6 @@ target 'SymbolCollisionTest' do pod 'FirebasePerformance', :path => '../' pod 'FirebaseRemoteConfig', :path => '../' pod 'FirebaseStorage', :path => '../' - pod 'GoogleUtilitiesComponents', :path => '../' # pod 'FirebaseUI'. - requires use_frameworks! diff --git a/scripts/check_imports.swift b/scripts/check_imports.swift index 6ddd3afc29d..89011f61b7f 100755 --- a/scripts/check_imports.swift +++ b/scripts/check_imports.swift @@ -47,7 +47,6 @@ let skipDirPatterns = ["/Sample/", "/Pods/", "FirebaseDatabase/Sources/third_party/Wrap-leveldb", // Pending SwiftPM for leveldb. "Example", "Firestore", - "GoogleUtilitiesComponents", "FirebasePerformance/ProtoSupport/", ] diff --git a/scripts/health_metrics/file_patterns.json b/scripts/health_metrics/file_patterns.json index cfda46156e5..4b488a28df3 100644 --- a/scripts/health_metrics/file_patterns.json +++ b/scripts/health_metrics/file_patterns.json @@ -108,13 +108,6 @@ "FirebaseMessaging/Interop/[^/]+\\.h" ] }, - { - "sdk": "google-utilities-components", - "podspecs": ["GoogleUtilitiesComponents.podspec"], - "filePatterns": [ - "^GoogleUtilitiesComponents.*" - ] - }, { "sdk": "inappmessaging", "podspecs": ["FirebaseInAppMessaging.podspec"],