Quantcast
Channel: Active questions tagged react-native+ios - Stack Overflow
Viewing all articles
Browse latest Browse all 16552

How to make Google sign in with Swift and use it in React Native

$
0
0

I am trying to create a google login for a react native app I intend to release to the app store. I am aware there are npm libraries for this, however I don't want to run into the issue of creators not updating their libraries. Also in the future I will probably make a custom native login UI for both ios and android. For that reason I followed this google guide to make a google sign-in button in Swift. I am proficient with React and know enough to work with React Native comfortably. However I am not familiar with Swift or branching code from Swift to React Native. Also since that google guide gives the example in swift I decided to convert the native files from Objective C to Swift (deleted AppDelegate.h, AppDelegate.m, main.m. Created AppDelegate.swift).

Problem: Can't get swift google sign in button to be visible in React Native

Steps:

  1. build google sign in button in swift
  2. export it to react native
  3. make a button to call sign in code from swift

I prefer to just make the button in swift then import it in react, but just making a button in react native to call swift functions is fine too. Also if I need to I can revert back to original Objective C code.

By following this guide I assume the solution would look something like this:

GoogleSignInManager.swift

import UIKit
import GoogleSignIn

@objc(GoogleSignInManager)
class GoogleSignInManager : NSObject {
  override func viewDidLoad() {
    super.viewDidLoad()

    GIDSignIn.sharedInstance()?.presentingViewController = self

    // Automatically sign in the user.
    GIDSignIn.sharedInstance()?.restorePreviousSignIn()
  }
}

GoogleSignInManger.m

#import "React/RCTViewManager.h"

@interface RCT_EXTERN_MODULE(GoogleSignInManager, RCTViewManager)
@end

MyApp-Bridging-Header.h

#import "React/RCTBridgeModule.h"
#import "React/RCTViewManager.h"

#import <React/RCTBridgeModule.h>
#import <React/RCTBridge.h>
#import <React/RCTEventDispatcher.h>
#import <React/RCTRootView.h>
#import <React/RCTUtils.h>
#import <React/RCTConvert.h>
#import <React/RCTBundleURLProvider.h>

AppDelegate.swift

import GoogleSignIn

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
  var window: UIWindow?
  var bridge: RCTBridge!

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    let jsCodeLocation: URL

    jsCodeLocation = RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index", fallbackResource:nil)
    let rootView = RCTRootView(bundleURL: jsCodeLocation, moduleName: "BbookMobile", initialProperties: nil, launchOptions: launchOptions)
    let rootViewController = UIViewController()
    rootViewController.view = rootView

    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = rootViewController
    self.window?.makeKeyAndVisible()

    /* Google API stuff I got from the guide */
    Initialize sign-in
    GIDSignIn.sharedInstance().clientID = "123fakeClientID456.apps.googleusercontent.com"
    GIDSignIn.sharedInstance().delegate = self

    @available(iOS 9.0, *)
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
      return GIDSignIn.sharedInstance().handle(url)
    }

    func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!,
              withError error: Error!) {
      if let error = error {
        if (error as NSError).code == GIDSignInErrorCode.hasNoAuthInKeychain.rawValue {
          print("The user has not signed in before or they have since signed out.")
        } else {
          print("\(error.localizedDescription)")
        }
        return
      }
      // Perform any operations on signed in user here.
      let userId = user.userID                  // For client-side use only!
      let idToken = user.authentication.idToken // Safe to send to the server
      let fullName = user.profile.name
      let givenName = user.profile.givenName
      let familyName = user.profile.familyName
      let email = user.profile.email

      print(fullName)
    }

    func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!,
              withError error: Error!) {
      // Perform any operations when the user disconnects from app here.
      print("User has disconnected")
    }
    /* End of google stuff */
    return true
  }
}

App.tsx

import React from 'react'
import { View, requireNativeComponent } from 'react-native'
import { ActionBtn } from './component-lib/Button'
import TextField from './component-lib/TextField'

const GoogleSignIn = requireNativeComponent("GoogleSignInManager")

const App = () => {
  return (
    <>
      <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
        <TextField label={"Username"} placeholder={"johndoe_"} contentType={"username"} />
        <TextField label={"Password"} contentType={"password"} secure={true} />
        <ActionBtn text={"hello"} />
        <GoogleSignIn />
      </View>
    </>
  )
}

I have been reading and looking for examples for about three hours to close the gap on this one and plan to write my own guide if I figure it out but hopefully someone can fill in the holes for me.


Viewing all articles
Browse latest Browse all 16552

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>