-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Handle UISceneDelegate changes in Auth #3925
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Firestore still needs GoogleUtilities to build on Xcode 8, so @available checks need to be wrapped in #if __has_builtin(__builtin_available) like https://github.com/firebase/firebase-ios-sdk/blob/master/GoogleUtilities/SecureCoding/GULSecureCoding.m#L55
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@renkelvin Thanks a lot for working on it!
There are couple comments from my side to improve the implementation. Also, I feel like this code really needs unit tests (at least basic ones).
| [sceneDelegateIMPDict copy], OBJC_ASSOCIATION_RETAIN); | ||
|
|
||
| BOOL didAddMethod = | ||
| class_addMethod(sceneDelegateClass, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I can see, the method swizzling has been implemented here. ISA swizzling is used to proxy App Delegate which is a preferable way (method swizzling will affect any object of the class in contrast to ISA swizzling which will affect only a particular instance, so the impact on the host app will be smaller as well as risks of issues).
I think, GULObjectSwizzler can be used here to create a subclass for the object. Then proxyDestinationSelector... method may be used to update the method implementation.
Feel free to reach out to me to clarify the details.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see the updated pr. Seems works well. I'll add unit tests later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can unit tests be added before this lands? It seems like a pretty significant change that we should be testing before publishing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I also would feel more comfortable with the changes having tests in place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean this pr is more of a draft. The solution is not finalized yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, sure, no problem
| [GULAppDelegateSwizzler sharedApplication].delegate; | ||
| [GULAppDelegateSwizzler proxyAppDelegate:originalDelegate]; | ||
|
|
||
| #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've determined that this won't work in our zip file. @paulb777 do we have a better approach, or do we need to start packaging with Xcode 11 (either in addition to Xcode 10.1, or as a replacement)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the current status of this?
| @"Cannot create subclass of App Delegate, because the created subclass is not the " | ||
| @"same size. %@", | ||
| NSStringFromClass(realClass)); | ||
| NSAssert(NO, @"Classes must be the same size to swizzle isa"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we avoid asserting here? Although functionality will be broken, we shouldn't be asserting and crashing developers' apps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maksymmalyhin Asserting seems used a lot for AppDelegate, what do you think?
| [GULAppDelegateSwizzler correctAppDelegateProxyKey]); | ||
| } | ||
|
|
||
| // TODO: reassign delegate as app delegate above? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there something that needs to be done here still? If so, please file an issue an update the comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's required for AppDelegate, while we need discuss more to see if it's needed for SceneDelegate.
See:
| /// We have to do this to invalidate the cache that caches the original respondsToSelector of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed it for now. I didn't see any issue without reassigning.
| [sceneDelegateIMPDict copy], OBJC_ASSOCIATION_RETAIN); | ||
|
|
||
| BOOL didAddMethod = | ||
| class_addMethod(sceneDelegateClass, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can unit tests be added before this lands? It seems like a pretty significant change that we should be testing before publishing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please run style.sh as well.
|
|
||
| // Register the new class as subclass of the real one. Do not allocate more than the real class | ||
| // size. | ||
| Class sceneDelegateSubClass = objc_allocateClassPair(realClass, newClassName.UTF8String, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we don't have a protection from multiple swizzling of the same object (not sure though how often it may happen, but it looks like a possible case). I think, we do our best guess based on the current object class name prefix - if it is equal to classNameWithPrefix then skip proxying.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's a good point. If developer's app uses a prefix of "GUL_" like us, then there would be collision issue any way.
1. Reuse `kGULRealIMPBySelectorKey` dict to retrieve the original IMP. Remove the `kGULSceneDelegateIMPDictKey` and associated dict. 2. Check the prefix of scene delegate class name. If it’s “GUL_”, then skip proxying to avoid proxying for more than once.
No description provided.