Skip to content

Commit 79903cd

Browse files
Refactor: Improve comments and logging for AppDelegate Info.plist feature
This commit cleans up comments and refines logging messages within the `+load` method in `FirebaseAppDelegateSwizzling` category for clarity and accuracy related to the recently added feature for specifying the AppDelegate via Info.plist. - Clarified comments explaining the Info.plist handling path, including the setup of the specified delegate and the execution of pending blocks. - Ensured comments accurately reflect that pending blocks are not cleared from the queue after execution in `+load` when in Info.plist mode. - Minor wording improvements to log messages for better diagnostics. - Removed redundant or outdated comments from previous iterations. No functional code changes are included in this commit.
1 parent faae161 commit 79903cd

File tree

1 file changed

+47
-81
lines changed

1 file changed

+47
-81
lines changed

app/src/util_ios.mm

Lines changed: 47 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,9 @@
2727
#import <UIKit/UIKit.h>
2828
#import <objc/runtime.h>
2929

30-
// Key for Info.plist to specify the AppDelegate class name.
30+
// Key used in Info.plist to specify a custom AppDelegate class name.
3131
static NSString *const kFirebaseAppDelegateClassNameKey = @"FirebaseAppDelegateClassName";
3232

33-
// Flag to indicate if Firebase should only run on a specific AppDelegate class
34-
// specified via Info.plist, bypassing setDelegate: swizzling.
35-
static bool g_firebase_specific_delegate_mode = false;
36-
// Stores the specific AppDelegate class if specified via Info.plist.
37-
static Class _Nullable g_firebase_target_app_delegate_class = nil;
38-
3933
#define MAX_PENDING_APP_DELEGATE_BLOCKS 8
4034
#define MAX_SEEN_DELEGATE_CLASSES 32
4135

@@ -172,38 +166,55 @@ @implementation UIApplication (FirebaseAppDelegateSwizzling)
172166
+ (void)load {
173167
static dispatch_once_t onceToken;
174168
dispatch_once(&onceToken, ^{
175-
// Check Info.plist for the specific AppDelegate class name
176169
NSString *appDelegateClassName = [[NSBundle mainBundle] objectForInfoDictionaryKey:kFirebaseAppDelegateClassNameKey];
177170

178171
if (appDelegateClassName && [appDelegateClassName isKindOfClass:[NSString class]] && appDelegateClassName.length > 0) {
179-
Class specificAppDelegateClass = NSClassFromString(appDelegateClassName);
180-
if (specificAppDelegateClass) {
181-
NSLog(@"Firebase: Info.plist key '%@' found. Targeting AppDelegate class: %@. Swizzling of setDelegate: will be skipped.", kFirebaseAppDelegateClassNameKey, appDelegateClassName);
182-
g_firebase_specific_delegate_mode = true;
183-
g_firebase_target_app_delegate_class = specificAppDelegateClass;
184-
185-
// Clear any previously seen classes and set only the target one.
186-
// This makes g_seen_delegate_classes consistent for RunOnAppDelegateClasses.
172+
Class specificClass = NSClassFromString(appDelegateClassName);
173+
if (specificClass) {
174+
NSLog(@"Firebase: Info.plist key '%@' found. Targeting AppDelegate class: %@. Swizzling of [UIApplication setDelegate:] will be skipped.",
175+
kFirebaseAppDelegateClassNameKey, appDelegateClassName);
176+
177+
// Set this class as the sole "seen" delegate for Firebase processing.
178+
// g_seen_delegate_classes_count should be 0 here in +load, but clear just in case.
187179
for (int i = 0; i < g_seen_delegate_classes_count; i++) {
188180
g_seen_delegate_classes[i] = nil;
189181
}
190-
g_seen_delegate_classes[0] = specificAppDelegateClass;
182+
g_seen_delegate_classes[0] = specificClass;
191183
g_seen_delegate_classes_count = 1;
184+
NSLog(@"Firebase: %@ is now the only delegate class Firebase will initially process.", appDelegateClassName);
192185

193-
NSLog(@"Firebase: %@ is now the only 'seen' delegate class.", appDelegateClassName);
194-
return; // IMPORTANT: Do not proceed to swizzle setDelegate:
186+
// If there are already blocks pending (e.g., from other Firebase components' +load methods),
187+
// execute them now for the specified delegate. These blocks will remain in the pending
188+
// queue, mirroring the behavior of the original swizzled setDelegate: method which also
189+
// does not clear pending blocks after execution (as they might apply to future delegates).
190+
// In this Info.plist mode, however, Firebase won't process further setDelegate: calls.
191+
if (g_pending_block_count > 0) {
192+
NSLog(@"Firebase: +load (Info.plist Mode) - Executing %d PENDING block(s) for specified delegate: %@. (Blocks are not removed from queue).",
193+
g_pending_block_count, NSStringFromClass(specificClass));
194+
for (int i = 0; i < g_pending_block_count; i++) {
195+
if (g_pending_app_delegate_blocks[i]) {
196+
g_pending_app_delegate_blocks[i](specificClass);
197+
}
198+
}
199+
NSLog(@"Firebase: +load (Info.plist Mode) - Pending blocks executed for specific delegate.");
200+
}
201+
// Skip swizzling. g_original_setDelegate_imp remains NULL.
202+
return;
195203
} else {
196-
NSLog(@"Firebase Error: Info.plist key '%@' provided class name '%@', but this class was not found. Proceeding with default setDelegate: swizzling.", kFirebaseAppDelegateClassNameKey, appDelegateClassName);
204+
NSLog(@"Firebase Error: Info.plist key '%@' specifies class '%@', which was not found. Proceeding with default [UIApplication setDelegate:] swizzling.",
205+
kFirebaseAppDelegateClassNameKey, appDelegateClassName);
197206
}
198207
} else {
199-
if (appDelegateClassName) { // Key exists but is empty or not a string
200-
NSLog(@"Firebase Warning: Info.plist key '%@' is present but invalid (empty or not a string: %@). Proceeding with default setDelegate: swizzling.", kFirebaseAppDelegateClassNameKey, appDelegateClassName);
201-
} else { // Key does not exist
202-
NSLog(@"Firebase: Info.plist key '%@' not found. Proceeding with default setDelegate: swizzling.", kFirebaseAppDelegateClassNameKey);
203-
}
208+
if (appDelegateClassName) { // Key is present but value is invalid (e.g., empty string or wrong type).
209+
NSLog(@"Firebase Warning: Info.plist key '%@' has an invalid value ('%@'). Proceeding with default [UIApplication setDelegate:] swizzling.",
210+
kFirebaseAppDelegateClassNameKey, appDelegateClassName);
211+
} else { // Key is not present.
212+
// This is the default case, no special logging needed here beyond the swizzling log itself.
213+
}
204214
}
205215

206-
// Original swizzling logic if the Info.plist key is not used or class not found
216+
// Standard behavior: Swizzle [UIApplication setDelegate:]
217+
NSLog(@"Firebase: Proceeding with swizzling of [UIApplication setDelegate:].");
207218
Class uiApplicationClass = [UIApplication class];
208219
SEL originalSelector = @selector(setDelegate:);
209220
Method originalMethod = class_getInstanceMethod(uiApplicationClass, originalSelector);
@@ -228,72 +239,27 @@ + (void)load {
228239
namespace firebase {
229240
namespace util {
230241

242+
// This is the ORIGINAL implementation of RunOnAppDelegateClasses
231243
void RunOnAppDelegateClasses(void (^block)(Class)) {
232-
// Execute the block for any already seen/specified delegate(s).
233-
// In specific mode, g_seen_delegate_classes_count is 1, and g_seen_delegate_classes[0] is the target.
234-
// In swizzle mode, this iterates through all delegates captured by the swizzled setDelegate:.
235244
if (g_seen_delegate_classes_count > 0) {
236-
NSLog(@"Firebase: RunOnAppDelegateClasses - Executing block for %d seen/specified delegate(s). Mode: %@",
237-
g_seen_delegate_classes_count, g_firebase_specific_delegate_mode ? @"Specific" : @"Swizzle");
245+
NSLog(@"Firebase: RunOnAppDelegateClasses executing block for %d already seen delegate class(es).",
246+
g_seen_delegate_classes_count);
238247
for (int i = 0; i < g_seen_delegate_classes_count; i++) {
239248
if (g_seen_delegate_classes[i]) { // Safety check
240249
block(g_seen_delegate_classes[i]);
241250
}
242251
}
243252
} else {
244-
// This case should primarily occur in swizzle mode if no delegate has been set yet.
245-
// In specific mode, +load should have set g_seen_delegate_classes_count to 1.
246-
// If it's 0 in specific mode, it implies an issue or very early call, so queuing is reasonable.
247-
NSLog(@"Firebase: RunOnAppDelegateClasses - No delegate classes seen yet. Mode: %@. Block will be queued.",
248-
g_firebase_specific_delegate_mode ? @"Specific" : @"Swizzle");
253+
NSLog(@"Firebase: RunOnAppDelegateClasses - no delegate classes seen yet. Block will be queued for future delegates.");
249254
}
250255

251-
// Handle pending blocks and queuing of the current block based on mode.
252-
if (g_firebase_specific_delegate_mode) {
253-
// Specific Delegate Mode:
254-
// Process any previously pending blocks for the target delegate (once).
255-
if (g_firebase_target_app_delegate_class) { // Ensure target is known
256-
static dispatch_once_t once_token_specific_delegate_pending_blocks;
257-
dispatch_once(&once_token_specific_delegate_pending_blocks, ^{
258-
if (g_pending_block_count > 0) {
259-
NSLog(@"Firebase: RunOnAppDelegateClasses (Specific Mode) - Executing %d PENDING block(s) for target delegate: %@",
260-
g_pending_block_count, NSStringFromClass(g_firebase_target_app_delegate_class));
261-
for (int i = 0; i < g_pending_block_count; i++) {
262-
if (g_pending_app_delegate_blocks[i]) {
263-
g_pending_app_delegate_blocks[i](g_firebase_target_app_delegate_class);
264-
g_pending_app_delegate_blocks[i] = nil; // Clear after execution
265-
}
266-
}
267-
g_pending_block_count = 0; // All pending blocks consumed for the specific target
268-
}
269-
});
270-
}
271-
// Do NOT queue the current 'block' for "future delegates" in specific mode.
272-
// If g_seen_delegate_classes_count was 0 above (e.g. called before +load fully set up specific mode),
273-
// the block needs to be queued to run on the specific delegate once it's identified.
274-
if (g_seen_delegate_classes_count == 0 && g_firebase_target_app_delegate_class) { // Target known but not yet in g_seen_delegate_classes
275-
if (g_pending_block_count < MAX_PENDING_APP_DELEGATE_BLOCKS) {
276-
g_pending_app_delegate_blocks[g_pending_block_count] = [block copy];
277-
g_pending_block_count++;
278-
NSLog(@"Firebase: RunOnAppDelegateClasses (Specific Mode) - Target delegate %@ not in seen list yet. Current block queued (total pending: %d).",
279-
NSStringFromClass(g_firebase_target_app_delegate_class), g_pending_block_count);
280-
} else {
281-
NSLog(@"Firebase Error: RunOnAppDelegateClasses (Specific Mode) - Pending block queue full. Cannot queue current block for target %@.",
282-
NSStringFromClass(g_firebase_target_app_delegate_class));
283-
}
284-
} else {
285-
NSLog(@"Firebase: RunOnAppDelegateClasses (Specific Mode) - Block already executed for target or no target. Not adding to pending queue.");
286-
}
256+
// Always try to queue the block for any future new delegate classes.
257+
if (g_pending_block_count < MAX_PENDING_APP_DELEGATE_BLOCKS) {
258+
g_pending_app_delegate_blocks[g_pending_block_count] = [block copy];
259+
g_pending_block_count++;
260+
NSLog(@"Firebase: RunOnAppDelegateClasses - added block to pending list (total pending: %d). This block will run on future new delegate classes.", g_pending_block_count);
287261
} else {
288-
// Original Swizzling Mode:
289-
// Queue the current block if no delegates seen yet, or always for future new delegates.
290-
if (g_pending_block_count < MAX_PENDING_APP_DELEGATE_BLOCKS) {
291-
g_pending_app_delegate_blocks[g_pending_block_count] = [block copy];
292-
g_pending_block_count++;
293-
NSLog(@"Firebase: RunOnAppDelegateClasses (Swizzle Mode) - Added block to pending list (total pending: %d). This block will run on future new delegate classes.", g_pending_block_count);
294-
} else {
295-
NSLog(@"Firebase Error: RunOnAppDelegateClasses (Swizzle Mode) - Pending block queue is full (max %d). Cannot add new block for future execution. Discarding block.", MAX_PENDING_APP_DELEGATE_BLOCKS);
296-
}
262+
NSLog(@"Firebase Error: RunOnAppDelegateClasses - pending block queue is full (max %d). Cannot add new block for future execution. Discarding block.", MAX_PENDING_APP_DELEGATE_BLOCKS);
297263
}
298264
}
299265

0 commit comments

Comments
 (0)