Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ firebase-ios-sdk/

#scripts link
scripts

GoogleMulticastAppDelegate/Apps/SwiftUISample/SwiftUISample/GoogleService-Info.plist
74 changes: 74 additions & 0 deletions GoogleMulticastAppDelegate.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
Pod::Spec.new do |s|
# TODO: Is `GoogleMulticastAppDelegate` name fine?
Comment thread
charlotteliang marked this conversation as resolved.
Outdated
s.name = 'GoogleMulticastAppDelegate'
s.version = '7.7.0'
s.summary = 'GoogleMulticastAppDelegate'

s.description = <<-DESC
GoogleMulticastAppDelegate
DESC

s.homepage = 'https://github.com/google/GoogleUtilities'
s.license = { :type => 'Apache', :file => 'LICENSE' }
s.authors = 'Google, Inc.'

s.source = {
:git => 'https://github.com/google/GoogleUtilities.git',
:tag => 'MulticastAppDelegate-' + s.version.to_s
}

ios_deployment_target = '9.0'
osx_deployment_target = '10.12'
tvos_deployment_target = '10.0'
watchos_deployment_target = '6.0'

s.ios.deployment_target = ios_deployment_target
# s.osx.deployment_target = osx_deployment_target
# s.tvos.deployment_target = tvos_deployment_target
# s.watchos.deployment_target = watchos_deployment_target

s.swift_versions = ['5.0', '5.2']
Comment thread
charlotteliang marked this conversation as resolved.
Outdated

s.cocoapods_version = '>= 1.4.0'
s.prefix_header_file = false

s.pod_target_xcconfig = {
'GCC_C_LANGUAGE_STANDARD' => 'c99',
'HEADER_SEARCH_PATHS' => '"${PODS_TARGET_SRCROOT}"',
}

base_dir = "GoogleMulticastAppDelegate/"
s.source_files = [
base_dir + 'Sources/**/*.[hm]',
]

s.dependency 'GoogleUtilities/AppDelegateSwizzler', '~> 7.7'

# s.test_spec 'unit' do |unit_tests|
# unit_tests.scheme = { :code_coverage => true }
# unit_tests.platforms = {
# :ios => ios_deployment_target,
# :osx => osx_deployment_target,
# :tvos => tvos_deployment_target
# }
# unit_tests.source_files = [
# base_dir + 'Tests/Unit/**/*.[mh]',
# ]
# unit_tests.requires_app_host = true
# unit_tests.dependency 'OCMock'
# end

# s.test_spec 'unit-swift' do |unit_tests_swift|
# unit_tests_swift.scheme = { :code_coverage => true }
# unit_tests_swift.platforms = {
# :ios => ios_deployment_target,
# :osx => osx_deployment_target,
# :tvos => tvos_deployment_target
# }
# unit_tests_swift.source_files = [
# base_dir + 'Tests/Unit/**/*.swift',
# ]

# unit_tests_swift.requires_app_host = true
# end
end
155 changes: 155 additions & 0 deletions GoogleMulticastAppDelegate/Sources/GULMulticastAppDelegate.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// Copyright 2022 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 "GoogleMulticastAppDelegate/Sources/Public/GoogleUtilities/GULMulticastAppDelegate.h"

@interface GULMulticastAppDelegate () <GULMulticastAppDelegateProtocol> {
NSMutableArray<id> *_interceptors;
id<GULApplicationDelegate> _defaultAppDelegate;
}
Comment thread
ncooke3 marked this conversation as resolved.
@end

@implementation GULMulticastAppDelegate

- (instancetype)init {
self = [super init];
if (self) {
_interceptors = [[NSMutableArray alloc] init];
Comment thread
ncooke3 marked this conversation as resolved.
}
return self;
}

- (instancetype)initWithAppDelegate:(id<GULApplicationDelegate>)delegate {
self = [super init];
if (self) {
_interceptors = [[NSMutableArray alloc] init];
[_interceptors addObject:delegate];
Comment thread
charlotteliang marked this conversation as resolved.
Outdated
_defaultAppDelegate = delegate;
}
return self;
}

+ (id<GULMulticastAppDelegateProtocol>)multicastDelegate {
Comment thread
ncooke3 marked this conversation as resolved.
id<UIApplicationDelegate> appDelegate = [UIApplication sharedApplication].delegate;
if (!appDelegate) {
return nil;
}
if ([appDelegate conformsToProtocol:@protocol(GULMulticastAppDelegateProtocol)]) {
id<GULMulticastAppDelegateProtocol> multicastAppDelegate =
(id<GULMulticastAppDelegateProtocol>)appDelegate;
return multicastAppDelegate;
}
if (appDelegate && [appDelegate respondsToSelector:@selector(getMulticastDelegate)]) {
Comment thread
charlotteliang marked this conversation as resolved.
Outdated
id<GULMulticastAppDelegateProtocol> multicastDelegate =
[appDelegate performSelector:@selector(getMulticastDelegate)];
CFRetain((__bridge CFTypeRef)(multicastDelegate));
Comment thread
ncooke3 marked this conversation as resolved.
return multicastDelegate;
}
return nil;
}

- (id<GULMulticastAppDelegateProtocol>)getMulticastDelegate {
return self;
}

- (void)addInterceptorWithDelegate:(id<GULApplicationDelegate>)interceptor {
[_interceptors addObject:interceptor];
}

- (void)removeInterceptorWithDelegate:(id<GULApplicationDelegate>)interceptor {
[_interceptors removeObject:interceptor];
}

- (BOOL)respondsToSelector:(SEL)aSelector {
if ([[self class] instancesRespondToSelector:aSelector]) {
return YES;
}
for (id<GULApplicationDelegate> interceptor in _interceptors) {
if (interceptor && [interceptor respondsToSelector:aSelector]) {
return YES;
}
}
Comment thread
ncooke3 marked this conversation as resolved.
return NO;
}

- (void)setDefaultAppDelegate:(id<UIApplicationDelegate>)defaultAppDelegate {
[_interceptors addObject:defaultAppDelegate];
_defaultAppDelegate = defaultAppDelegate;
}

- (id)forwardingTargetForSelector:(SEL)aSelector {
return _defaultAppDelegate;
}

#if !TARGET_OS_WATCH
#pragma mark - Open URL
- (BOOL)application:(GULApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
BOOL result = NO;
for (id<UIApplicationDelegate> interceptor in _interceptors) {
result = result || [interceptor application:app openURL:url options:options];
}
return result;
}

#pragma mark - APNS methods
- (void)application:(GULApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
for (id<GULApplicationDelegate> interceptor in _interceptors) {
if ([interceptor respondsToSelector:@selector(application:
didRegisterForRemoteNotificationsWithDeviceToken:)]) {
[interceptor application:application
didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
}
}

#else // !TARGET_OS_WATCH
- (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
for (id<GULApplicationDelegate> interceptor in _interceptors) {
if ([interceptor
respondsToSelector:@selector(didRegisterForRemoteNotificationsWithDeviceToken)]) {
[interceptor didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
}
}
#endif // !TARGET_OS_WATCH

#if TARGET_OS_IOS || TARGET_OS_TV
Comment thread
charlotteliang marked this conversation as resolved.
Outdated
- (void)application:(GULApplication *)application
didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
for (id<GULApplicationDelegate> interceptor in _interceptors) {
if ([interceptor respondsToSelector:@selector(application:
didFailToRegisterForRemoteNotificationsWithError:)]) {
[interceptor application:application didFailToRegisterForRemoteNotificationsWithError:error];
}
}
}

- (void)application:(GULApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
for (id<GULApplicationDelegate> interceptor in _interceptors) {
if ([interceptor respondsToSelector:@selector
(application:didReceiveRemoteNotification:fetchCompletionHandler:)]) {
[interceptor application:application
didReceiveRemoteNotification:userInfo
fetchCompletionHandler:completionHandler];
}
}
}
#endif

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2022 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 <Foundation/Foundation.h>

#import <GoogleUtilities/GULApplication.h>

NS_ASSUME_NONNULL_BEGIN

@protocol GULMulticastAppDelegateProtocol <NSObject>

- (void)addInterceptorWithDelegate:(id<GULApplicationDelegate>)interceptor;

- (void)removeInterceptorWithDelegate:(id<GULApplicationDelegate>)interceptor;
Comment thread
ncooke3 marked this conversation as resolved.
Outdated

@end

@interface GULMulticastAppDelegate : NSObject <GULApplicationDelegate>

@property(nonatomic, copy) id<GULApplicationDelegate> defaultAppDelegate;
Comment thread
charlotteliang marked this conversation as resolved.

- (instancetype)initWithAppDelegate:(id<GULApplicationDelegate>)delegate;

- (void)addInterceptorWithDelegate:(id<GULApplicationDelegate>)delegate;

+ (id<GULMulticastAppDelegateProtocol>)multicastDelegate;
@end

NS_ASSUME_NONNULL_END
Loading