mkloubert / nativescript-social-login

NativeScript plugin for social (token based) log-ins.
MIT License
42 stars 44 forks source link

Add warning about overriding the complete app delegate #69

Open jerbob92 opened 5 years ago

jerbob92 commented 5 years ago

Some plugins (like the Firebase plugin) set some app delegate methods. In the readme of this plugin, the suggestion is to override the complete delegate, this is dangerous as it breaks those other plugins completely.

We made our SocalLogin integration like this:

if (application.ios) {
    let oldapplicationDidFinishLaunchingWithOptions;
    let oldapplicationOpenURLSourceApplicationAnnotation;

    // Play nice with other plugins by not completely ignoring anything already added to the appdelegate.
    if (application.ios.delegate === undefined) {
        // Create empty app delegate.
        @ObjCClass(UIApplicationDelegate)
        class CustomUIApplicationDelegateImpl extends UIResponder implements UIApplicationDelegate {
        }

        application.ios.delegate = CustomUIApplicationDelegateImpl;
    } else {
        // Save the old delegates that we override.
        if (application.ios.delegate.prototype.applicationDidFinishLaunchingWithOptions) {
            oldapplicationDidFinishLaunchingWithOptions = application.ios.delegate.prototype.applicationDidFinishLaunchingWithOptions;
        }
        if (application.ios.delegate.prototype.applicationOpenURLSourceApplicationAnnotation) {
            oldapplicationOpenURLSourceApplicationAnnotation = application.ios.delegate.prototype.applicationOpenURLSourceApplicationAnnotation;
        }
    }

    // Override the delegates.
    application.ios.delegate.prototype.applicationDidFinishLaunchingWithOptions = (application, launchOptions) => {
        let gglDelegate = false;

        try {
            const errorRef = new interop.Reference();
            GGLContext.sharedInstance().configureWithError(errorRef);

            const signIn = GIDSignIn.sharedInstance();
            gglDelegate = true;
        } catch (error) {
            console.log(error);
        }

        const fcbDelegate = FBSDKApplicationDelegate.sharedInstance().applicationDidFinishLaunchingWithOptions(application, launchOptions); // facebook login delegate
        // Execute the old delegate.
        let oldDelegate = true;
        if (oldapplicationDidFinishLaunchingWithOptions) {
            oldDelegate = oldapplicationDidFinishLaunchingWithOptions(application, launchOptions);
        }
        return gglDelegate || fcbDelegate || oldDelegate;
    };

    application.ios.delegate.prototype.applicationOpenURLSourceApplicationAnnotation = (application, url, sourceApplication, annotation) => {
        const fcbDelegate = FBSDKApplicationDelegate.sharedInstance().applicationOpenURLSourceApplicationAnnotation(application, url, sourceApplication, annotation); // facebook login delegate
        const gglDelegate = GIDSignIn.sharedInstance().handleURLSourceApplicationAnnotation(url, sourceApplication, annotation); // google login delegate
        // Execute the old delegate.
        let oldDelegate = true;
        if (oldapplicationOpenURLSourceApplicationAnnotation) {
            oldDelegate = oldapplicationOpenURLSourceApplicationAnnotation(url, sourceApplication, annotation);
        }
        return fcbDelegate || gglDelegate || oldDelegate;
    };
}

By this, we do not override when the delegate when it already exists, we just override the delegate methods we need to override for SocialLogin to work, and we copy the old delegate methods so they are still executed.