Google Sign-in crash & error: uiDelegate must either be a |UIViewController| - ios

I'm trying to implement Google Sign-in to an iOS app but the app crashes on clicking on the Sign-in button with the following error:
reason: 'uiDelegate must either be a |UIViewController| or implement the |signIn:presentViewController:| and |signIn:dismissViewController:| methods from |GIDSignInUIDelegate|.'
I'm not sure where I'm going wrong. I've followed the sample code from Google's iOS github exactly. I also can't get Google's sample to compile. If anyone could point me in the right direction, that would be great. Most of the SO questions are based on dated code.
Viewcontroller
import UIKit
import GoogleSignIn
#objc(ViewController)
class ViewController: UIViewController, GIDSignInUIDelegate {
// Viewcontroller buttons
#IBOutlet weak var signInButton: GIDSignInButton!
#IBOutlet weak var signOutButton: UIButton!
#IBOutlet weak var disconnectButton: UIButton!
#IBOutlet weak var statusText: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
GIDSignIn.sharedInstance().uiDelegate = self
// Sign in automatically
GIDSignIn.sharedInstance().signInSilently()
// Something to do with notifications
NotificationCenter.default.addObserver(self,
selector: #selector(ViewController.receiveToggleAuthUINotification(_:)),
name: NSNotification.Name(rawValue: "ToggleAuthUINotification"),
object: nil)
statusText.text = "Initialized Swift App..."
toggleAuthUi()
}
// Sign out tapped
#IBAction func didTapDisconnect(_ sender: AnyObject) {
GIDSignIn.sharedInstance().disconnect()
statusText.text = "Disconnecting"
}
// Toggle auth
func toggleAuthUi() {
if GIDSignIn.sharedInstance().hasAuthInKeychain() {
signInButton.isHidden = true
signOutButton.isHidden = false
disconnectButton.isHidden = false
} else {
signInButton.isHidden = false
signOutButton.isHidden = true
disconnectButton.isHidden = true
}
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return UIStatusBarStyle.lightContent
}
deinit {
NotificationCenter.default.removeObserver(self,
name: NSNotification.Name(rawValue: "ToggleAuthUINotification"),
object: nil)
}
#objc func receiveToggleAuthUINotification(_ notification: NSNotification) {
if notification.name.rawValue == "ToggleAuthUINotification" {
self.toggleAuthUi()
if notification.userInfo != nil {
guard let userInfo = notification.userInfo as? [String:String] else {return}
self.statusText.text = userInfo["statusText"]!
}
}
}
}
AppDelegate:
import UIKit
import GoogleSignIn
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
var window: UIWindow?
// Did Finished Launching
func application (_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Init Sign in
GIDSignIn.sharedInstance().clientID = "XXXXXXXXX"
GIDSignIn.sharedInstance().delegate = self
return true
}
// Open URL
func application (_app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any]) -> Bool {
return GIDSignIn.sharedInstance().handle(url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String, annotation: options[UIApplicationOpenURLOptionsKey.annotation])
}
public func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
if let error = error {
print("\(error.localizedDescription)")
NotificationCenter.default.post(
name: Notification.Name(rawValue: "ToggleAuthUINotificiation"), object: nil, userInfo: nil)
} else {
// User Stuff
let userID = user.userID
let idToken = user.authentication.idToken
let fullName = user.profile.name
let givenName = user.profile.givenName
let familyName = user.profile.familyName
let email = user.profile.email
NotificationCenter.default.post(
name: Notification.Name(rawValue: "ToggleAuthUINotification"),
object: nil,
userInfo: ["statusText": "Signed in user:\n\(fullName)"])
}
}
public func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
// Disconnect the user
NotificationCenter.default.post(
name: Notification.Name(rawValue: "ToggleAuthUINotification"),
object: nil,
userInfo: ["statusText": "User has disconnect."])
}
}

tl;dr: If using a non-UIViewController as a uiDelegate - check if Xcode is warning you that "Instance method [...] nearly matches optional requirement [...]" and use the Fix-Its. Make sure your functions match the required signature exactly.
I had the same error after following the sample code.
In my case the setup was a bit different, so I am not sure if my solution is applicable to your question - but because this StackOverflow answer shows up in Google Search, I thought I'd provide my resolution here for any people stumbling upon it:
I needed a non-UIVIewController subclass to be the Google Sign In uiDelegate. As the documentation and the error state, this means you need to implement some methods. I had implemented them, so it was strange that things were crashing.
In my case, the issue was that the copy-pasted code from Google's documentation was not exactly matching the Swift function signatures. In fact, I had warnings in Xcode, saying "Instance method [...] nearly matches optional requirement [...]". I used the auto Fix-Its by Xcode (it was stuff such as Error instead of NSError, or _ before a function's argument.)
Then it all worked.

Related

How to convert Google iOS Sign-In single page sample AppDelegate.h protocol -> to a segue to LoginPage ViewController AppDelegate.swift protocol?

Google's Sign-In sample on GitHub SignInSampleForPod.xcworkspace creates a single page sign-in using the AppDelegate.h SignInViewController.m etc protocol.
However many apps, such as mine, prefer to segue to a Login Page only when a user makes a choice requiring verification. I just want the basic Google Profile info and authentication token.
I have the Google iOS ClientID configured enough so a segue to my LoginPage.swift shows the Google Sign-In button via AppDelegate.swift:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(
_ app: UIApplication,
open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]
) -> Bool {
var handled: Bool
handled = GIDSignIn.sharedInstance.handle(url)
if handled {
return true
}
// Handle other custom URL types.
// If not handled by this app, return false.
return false
}
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
if error != nil || user == nil {
// Show the app's signed-out state.
} else {
// Show the app's signed-in state.
}
}
return true
}
And LoginPage.swift:
class LoginViewController: UIViewController {
let signInConfig = GIDConfiguration.init(clientID: "foo-bar85.apps.googleusercontent.com")
override func viewDidLoad() {
super.viewDidLoad()
GIDSignIn.sharedInstance.signIn(with: signInConfig, presenting: self) { user, error in
guard error == nil else { return }
guard let user = user else { return }
let emailAddress = user.profile?.email
let fullName = user.profile?.name
let givenName = user.profile?.givenName
let familyName = user.profile?.familyName
let profilePicUrl = user.profile?.imageURL(withDimension: 320)
}
So my question is what is the AppDelegate.swift Google Sign-In code for the fields shown below to display the basic profile info:
// Show the app's signed-out state.
} else {
// Show the app's signed-in state.
I may not able to understand your problem clearly.
But I am trying to answer based on my understanding.
You can create a class (GoogleLoginManager) for all google login related stuff and create a button in UI then call this method (signIn) from button action.
#IBAction func googleButtonAction(_ sender: Any) {
GoogleLoginManager.shared.signIn(controller: self) { (profile) in
print("GoogleLogin profile : \(String(describing: profile.name)), \(String(describing: profile.email))")
} onFailure: { (error) in
print("GoogleLogin error : \(String(describing: error.localizedDescription))")
}
}
import Foundation
import GoogleSignIn
class GoogleLoginManager: SocialLogin {
fileprivate var onSuccess : success?
fileprivate var onFailure : failure?
static let shared = GoogleLoginManager()
private override init() { }
func signIn(controller: UIViewController, onSuccess : #escaping success, onFailure : #escaping failure) {
self.onSuccess = onSuccess
self.onFailure = onFailure
GIDSignIn.sharedInstance().clientID = GOOGLE_CLIENT_ID
GIDSignIn.sharedInstance().delegate = self
GIDSignIn.sharedInstance().presentingViewController = controller
GIDSignIn.sharedInstance().signIn()
// Automatically sign in the user.
// GIDSignIn.sharedInstance()?.restorePreviousSignIn()
}
func signOut() {
GIDSignIn.sharedInstance().signOut()
}
}
extension GoogleLoginManager : GIDSignInDelegate {
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 if (error as NSError).code == GIDSignInErrorCode.canceled.rawValue {
print("user canceled the sign in request")
}
else {
print("\(error.localizedDescription)")
}
self.onFailure?(error)
return
}
var profile = SocialProfileModel.init(user: user)
profile.loginSuccess = true
self.onSuccess?(profile)
}
func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!,
withError error: Error!) {
// Perform any operations when the user disconnects from app here.
print("GIDSignIn : didDisconnectWith")
}
}
I just had to modify my above AppDelegate.swift slightly - adding a standard UIbutton linked to the following action - gets the profile info:
#IBAction func LogInButtonTouched(_ sender: UIButton) {
GIDSignIn.sharedInstance.signIn(with: signInConfig, presenting: self) { user, error in
guard error == nil else { return }
guard let user = user else { return }
let emailAddress = user.profile?.email
let fullName = user.profile?.name
let givenName = user.profile?.givenName
let familyName = user.profile?.familyName
let profilePicUrl = user.profile?.imageURL(withDimension: 320)
print("GoogleLogin profile : \(String(describing: user.profile?.name)), \(String(describing: user.profile?.email))")
}
}

swift firebase google sign in not showing on console

I am trying to sign in to firestore auth using the following GoogleSignInViewController but it shows nothing on the firebase console -
import UIKit
import Firebase
import GoogleSignIn
class GoogleSignInViewController: UIViewController {
var googleSignIn = GIDSignIn.sharedInstance()
#IBOutlet weak var emailField: UITextField!
#IBOutlet weak var passwordField: UITextField!
#IBAction func googleLoginBtnAction(_ sender: UIButton) {
print("sign in tapped")
self.googleAuthLogin()
}
func googleAuthLogin() {
self.googleSignIn?.presentingViewController = self
self.googleSignIn?.clientID = "419387986978-pbs8h2drcjk60svqf1d5mgj0pa436r7b.apps.googleusercontent.com"
self.googleSignIn?.delegate = self
self.googleSignIn?.signIn()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "detailseg" {
let DestView = segue.destination as! DetailsViewController
}
}
}
extension GoogleSignInViewController: GIDSignInDelegate {
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
guard let user = user else {
print("Uh oh. The user cancelled the Google login.")
return
}
let userId = user.userID ?? ""
print("Google User ID: \(userId)")
let userIdToken = user.authentication.idToken ?? ""
print("Google ID Token: \(userIdToken)")
let userFirstName = user.profile.givenName ?? ""
print("Google User First Name: \(userFirstName)")
let userLastName = user.profile.familyName ?? ""
print("Google User Last Name: \(userLastName)")
let userEmail = user.profile.email ?? ""
print("Google User Email: \(userEmail)")
let googleProfilePicURL = user.profile.imageURL(withDimension: 150)?.absoluteString ?? ""
print("Google Profile Avatar URL: \(googleProfilePicURL)")
}
func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
}
}
It shows the login page as follows ( only for demonstrational purpose) -
Then, my app (Fireupgoodsa) takes permission from google to sign in -
Then, google takes permissioin to share my email id. information with the project -
Then, it goes to the DetailViewController (shown in red color below)-
Also, it shows alert message in my official email id.that my account was signed in to a new device i.e. my iOS simulator, which proves that sign in HAS taken place.
So far, so good -
but there is nothing on the firebase console -
This also didn't help me - Not getting the email using Google Authentication in Firebase
I had asked a similar bounty question - How to signoutout user from firebase console in swift
The bounty lapsed, but the problem was not sorted.
I have also deleted the project and created a new project. The screenshot of the project overview is shown below -
Now, why does not it show anything on the Firebase console. Is it something with the settings, project name. Do I need to add a tag container or something ? (Also, please see the address bar in the image above to see if something is wrong). What am I missing out on ?
This has been bugging me for quite a while.
I am desperate for help.
Please give me a hand with this, will you ?
I am posting the complete code for "class GoogleSignInViewController" and "class AppDelegate"-
class GoogleSignInViewController:-
import UIKit
import Firebase
import GoogleSignIn
class GoogleSignInViewController: UIViewController {
var googleSignIn = GIDSignIn.sharedInstance()
#IBOutlet weak var emailField: UITextField!
#IBOutlet weak var passwordField: UITextField!
#IBAction func googleLoginBtnAction(_ sender: UIButton) {
print("sign in tapped")
self.googleAuthLogin()
}
#IBAction func googleLogoutBtnAction(_ sender: Any) {
let firebaseAuth = Auth.auth()
do {
try firebaseAuth.signOut()
print ("user is signed out")
} catch let signOutError as NSError {
print ("Error signing out: %#", signOutError)
}
}
func googleAuthLogin() {
self.googleSignIn?.presentingViewController = self
self.googleSignIn?.clientID = "9727299xxxxx-m0brc61v3a32br7b34pdjxxxxxxxxxxx.apps.googleusercontent.com"
self.googleSignIn?.delegate = self
self.googleSignIn?.signIn()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "detailseg" {
let DestView = segue.destination as! DetailsViewController
}
}
}
extension GoogleSignInViewController: GIDSignInDelegate {
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!){
if let err = error {
print ("failed to log into Google", err)
return
}
print("successfully logged into Google",user)
guard let idToken = user.authentication.idToken else {return}
guard let accessToken = user.authentication.accessToken else {return}
let credentials = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: accessToken)
Auth.auth().signInAndRetrieveData(with: credentials, completion: { (user, error) in
if let err = error {
print ("failed to create with google account", err)
return
}
print("successfuly logged into Firebase with Google", user?.user.uid)
})
}
func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
}
}
class AppDelegate:-
import UIKit
import GoogleSignIn
import Firebase
import CoreData
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
// Override point for customization after application launch.
GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
GIDSignIn.sharedInstance().delegate = self
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return GIDSignIn.sharedInstance().handle(url as URL?)
}
func sign(_ signIn: GIDSignIn!,
didSignInFor user: GIDGoogleUser!,
withError error: Error!) {
// Check for sign in 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
}
// Get credential object using Google ID token and Google access token
guard let authentication = user.authentication else {
return
}
let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
accessToken: authentication.accessToken)
// Authenticate with Firebase using the credential object
Auth.auth().signIn(with: credential) { (authResult, error) in
if let error = error {
print("Error occurs when authenticate with Firebase: \(error.localizedDescription)")
}
// Post notification after user successfully sign in
// NotificationCenter.default.post(name: .signInGoogleCompleted, object: nil)
}
}
func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
// Perform any operations when the user disconnects from app here.
print("User has disconnected")
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
The above codes works for me and show me signed in FirebaseAuth with my gmail id.:-
Note -This answer shows just how the user google/gmail sign-in on the FirebaseAuth console(which is what this question is all about) . I have not posted the code to show details in the DetailsiewController. I will post that code later when I have designed that.
Furthermore, If you want to write your Firebase Auth User UID to Firestore Document ID you can refer to the "class UserIdtoFirestoreViewController" of the question in the link:-
How to Show Firebase Auth User UID and also my Firestore doc uid as Stripe customer id

Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) When working in swift trying to login to spotify

Code:
//
// AppDelegate.swift
// SplitterSwift3
//
// Created by VideoLabN on 4/8/18.
// Copyright © 2018 VideoLabN. All rights reserved.
//
import UIKit
import AWSAuthCore
import AWSMobileClient
import AWSCore
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var auth = SPTAuth()
// Add a AWSMobileClient call in application:open url
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
// called when user signs into spotify. Session data saved into user defaults, then notification posted to call updateAfterFirstLogin in ViewController.swift. Modeled off recommneded auth flow suggested by Spotify documentation
if auth.canHandle(auth.redirectURL) {
auth.handleAuthCallback(withTriggeredAuthURL: url, callback: { (error, session) in
if error != nil {
print("error!")
}
let userDefaults = UserDefaults.standard
let sessionData = NSKeyedArchiver.archivedData(withRootObject: session)
print(sessionData)
userDefaults.set(sessionData, forKey: "SpotifySession")
userDefaults.synchronize()
NotificationCenter.default.post(name: Notification.Name(rawValue: "loginSuccessfull"), object: nil)
})
return true
}
return false
}
//Add a AWSMobileClient call in application:didFinishLaunching
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplicationLaunchOptionsKey: Any]?) -> Bool {
return AWSMobileClient.sharedInstance().interceptApplication(
application, didFinishLaunchingWithOptions:
launchOptions)
}
}
//
// ViewController.swift
// SplitterSwift3
//
// Created by VideoLabN on 4/8/18.
// Copyright © 2018 VideoLabN. All rights reserved.
//
import UIKit
import SafariServices
import AVFoundation
import AWSAuthCore
import AWSAuthUI
class ViewController: UIViewController, SPTAudioStreamingPlaybackDelegate, SPTAudioStreamingDelegate {
// Variables
var auth = SPTAuth.defaultInstance()!
var session:SPTSession!
// Initialzed in either updateAfterFirstLogin: (if first time login) or in viewDidLoad (when there is a check for a session object in User Defaults
var player: SPTAudioStreamingController?
var loginUrl: URL?
// Outlets
#IBOutlet weak var loginSpotify: UIButton!
#IBOutlet weak var loginSplitter: UIButton!
#IBOutlet weak var testLabel: UILabel!
override func viewDidLoad() {
print("test")
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.setup()
//NotificationCenter.default.addObserver(self, selector: #selector(ViewController.updateAfterFirstLogin, name: NSNotification.Name(rawValue: "loginSuccessfull"), object: nil)
//self.updateAfterFirstLogin()
}
func setup () {
// insert redirect your url and client ID below
let redirectURL = "splitter-app://callback" // put your redirect URL here
let clientID = "207ce42c908f42e485c540be11720888" // put your client ID here
auth.redirectURL = URL(string: redirectURL)
auth.clientID = "client id goes here"
auth.requestedScopes = [SPTAuthStreamingScope, SPTAuthPlaylistReadPrivateScope, SPTAuthPlaylistModifyPublicScope, SPTAuthPlaylistModifyPrivateScope]
loginUrl = auth.spotifyWebAuthenticationURL()
//print("test")
}
func initializePlayer(authSession:SPTSession){
if self.player == nil {
self.player = SPTAudioStreamingController.sharedInstance()
self.player!.playbackDelegate = self
self.player!.delegate = self
try! player!.start(withClientId: auth.clientID)
self.player!.login(withAccessToken: authSession.accessToken)
}
}
#objc func updateAfterFirstLogin () {
loginSpotify.isHidden = true
let userDefaults = UserDefaults.standard
if let sessionObj:AnyObject = userDefaults.object(forKey: "SpotifySession") as AnyObject? {
let sessionDataObj = sessionObj as! Data
let firstTimeSession = NSKeyedUnarchiver.unarchiveObject(with: sessionDataObj) as! SPTSession
self.session = firstTimeSession
initializePlayer(authSession: session)
}
}
func audioStreamingDidLogin(_ audioStreaming: SPTAudioStreamingController!) {
// after a user authenticates a session, the SPTAudioStreamingController is then initialized and this method called
print("logged in")
//
self.player?.playSpotifyURI("spotify:track:58s6EuEYJdlb0kO7awm3Vp",
startingWith: 0, startingWithPosition: 0, callback: { (error) in
// if (error != nil) {
// print("playing!")
// }
//
// })
}
#IBAction func spotifyButtonPressed(_ sender: Any) {
let svc = SFSafariViewController(url: loginUrl!)
self.present(svc, animated: true, completion: nil)
//UIApplication.shared.open(loginUrl!, options: [:])
}
}
The application compiles just fine and launches on the simulator IPhone. The button to login to Spotify works, and opens a Safari instance prompting the user to login to Spotify.
Once the user has logged in, it then asks for permissions. Once the user accepts the permissions, the app crashes on line 16 of the appDelegate class with this error:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x0).
I have read up on this online and people are saying it is the equivalent to a null pointer exception, but I cannot find what is causing this error. Can anyone find the error?
Edit: Thanks to those that have responded! Here is my console output:
objc[19082]: Class VCWeakObjectHolder is implemented in both
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/AVConference.framework/Frameworks/ViceroyTrace.framework/ViceroyTrace
(0x12b9174d0) and
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/AVConference.framework/AVConference
(0x12aa65e38). One of the two will be used. Which one is undefined.
test 2018-04-15 13:33:50.341600-0400 SplitterSwift3[19082:1059086]
[AXRun-PID] Client requesting unsuspension of PID:-1 Name:
2018-04-15 13:33:50.441522-0400 SplitterSwift3[19082:1058985] [MC]
System group container for systemgroup.com.apple.configurationprofiles
path is
/Users/videolabn/Library/Developer/CoreSimulator/Devices/CEC32A65-63E0-4499-AB25-6BD13A7AE013/data/Containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2018-04-15 13:33:50.442782-0400 SplitterSwift3[19082:1058985] [MC]
Reading from private effective user settings. 2018-04-15
13:33:50.536744-0400 SplitterSwift3[19082:1058985] [App] if we're in
the real pre-commit handler we can't actually add any new fences due
to CA restriction (lldb)
The UIApplicationDelegate function application(_:open:sourceApplication:annotation:) was deprecated in iOS 10.
As of iOS 11.3 it seems that apps using this function will crash when it is invoked. The solution is is to use the replacement application(_:open:options:) instead.
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
if auth.canHandle(auth.redirectURL) {
auth.handleAuthCallback(withTriggeredAuthURL: url, callback: { (error, session) in
if error != nil {
print("error!")
}
let userDefaults = UserDefaults.standard
let sessionData = NSKeyedArchiver.archivedData(withRootObject: session)
print(sessionData)
userDefaults.set(sessionData, forKey: "SpotifySession")
NotificationCenter.default.post(name: Notification.Name(rawValue: "loginSuccessfull"), object: nil)
})
return true
}
return false
}
Also, there is no need to call synchronize for UserDefaults

Not presenting Safari view on click of Google sign in button

I am clicking on the google sign in button but it is not presenting the SafariView, but the delegate methods of GIDSignInUIDelegate is called.
Besides this the delegate methods of GIDSignInDelegate are not called from the App Delegate .
What are the possible reasons? Below is the code given:
My URL Scheme:
com.googleusercontent.apps.1028134765971-6ok9n9pemgs3709q70so3bn5u08e84f6
AppDelegate.h
//
// AppDelegate.swift
// ESO
//
// Created by BBI USER 1027 on 23/05/17.
// Copyright © 2017 BBI. All rights reserved.
//
import UIKit
import Firebase
import GoogleSignIn
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
let signIn = GIDSignIn.sharedInstance()
signIn?.clientID = FirebaseApp.app()?.options.clientID!
signIn?.scopes = ["https://www.googleapis.com/auth/plus.login"]
signIn?.delegate = self
return true
}
func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any])
-> Bool {
print(GIDSignIn.sharedInstance().handle(url,
sourceApplication:options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String,
annotation: [:]))
return GIDSignIn.sharedInstance().handle(url,
sourceApplication:options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String,
annotation: [:])
}
//MARK : Google sign in delegate methods
func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!,
withError error: NSError!) {
if (error == nil) {
// 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
// ...
} else {
print("\(error.localizedDescription)")
}
}
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
// ...
if let error = error {
// ...
return
}
guard let authentication = user.authentication else { return }
let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
accessToken: authentication.accessToken)
// ...
Auth.auth().signIn(with: credential) { (user, error) in
if let error = error {
// ...
return
}
// User is signed in
// ...
}
}
}
FBGoogleSigninViewController.swift
//
// FBGoogleSigninViewController.swift
// LoginModule
//
// Created by Shubham Ojha on 8/4/17.
// Copyright © 2017 BBI. All rights reserved.
//
import UIKit
import Firebase
import GoogleSignIn
class FBGoogleSigninViewController: UIViewController,GIDSignInUIDelegate {
#IBOutlet weak var segmentView: UISegmentedControl!
#IBOutlet weak var loginIDCustomTextField: CustomTextField!
#IBOutlet weak var passwordCustomTextField: CustomTextField!
#IBOutlet weak var loginIdLabel: UILabel!
// On click of this button I am not getting any response.
#IBOutlet weak var SignInButton: GIDSignInButton!
override func viewDidLoad() {
super.viewDidLoad()
GIDSignIn.sharedInstance().uiDelegate = self;
GIDSignIn.sharedInstance().signIn()
self.SignInButton.layer.cornerRadius = 5.0;
self.navigationController?.setNavigationBarHidden(false, animated: true)
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func segmentValueChanged(_ sender: Any) {
let segment = sender as! UISegmentedControl
if segment.selectedSegmentIndex == 0 {
self.loginIdLabel.text = "Login ID"
self.SignInButton.backgroundColor = UIColor.blue
}
else{
self.loginIdLabel.text = "Email ID"
self.SignInButton.backgroundColor = UIColor.red
}
}
// MARK: google sign in delegate methods
public func sign(inWillDispatch signIn: GIDSignIn!, error: Error!){
}
func sign(_ signIn: GIDSignIn!, present viewController: UIViewController!){
print(viewController.description)
}
}

Notify user reachability (Ashley Mills' Reachability)

I made an app, I want to add function that notify user when app's internet reachability is changed.
I use Ashley Mills' Reachability.swift file.
now I understand how it works, So I put code that when internet reachability is changed, it will print it's status in appDelegate.
However when I tried to put in function that alert user there isn't internet connection, It gets an error.
here is my code in app delegate.
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var reachability : Reachability?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
do {
let reachability = try Reachability.reachabilityForInternetConnection()
self.reachability = reachability
} catch ReachabilityError.FailedToCreateWithAddress(let address) {
}
catch {}
NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityChanged:", name: ReachabilityChangedNotification, object: reachability)
do {
try reachability?.startNotifier()
} catch {}
return true
}
func reachabilityChanged(notification: NSNotification) {
let reachability = notification.object as! Reachability
if reachability.isReachable() {
print("reached")
} else {
print("not reached")
}
}
This works well.
However the code in Viewcontroller,
class ViewController: UIViewController {
var reachability : Reachability?
#IBOutlet weak var label: UILabel!
#IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "HeyUserInternetDoesntWork", name: ReachabilityChangedNotification, object: nil)
//get call from appDelegate Notification.
}
func HeyUserInternetDoesntWork() {
if reachability!.isReachable() {
print("notify User working")
} else {
print("Notify user not working")
}
}
unexpectedly found nil while unwrapping an Optional value
It gets this error.
I am going to put code for alerting user after it works.
Question here,
How Can I make it this work?
It doesn't have to be use that method, but I want to keep using NSNotification.
Actually I am a new guy for coding, So please explain details.
Where do you init reachability property? this variable is always nil.
In func HeyUserInternetDoesntWork you try to use reachability and of course it gets error. You need to init property like this:
private let reachability = Reachability.reachabilityForInternetConnection()
After use func HeyUserInternetDoesntWork with 'dynamic' keyword like this:
dynamic func HeyUserInternetDoesntWork() {
if reachability!.isReachable() {
print("notify User working")
} else {
print("Notify user not working")
}
}
Because NSNotificationCenter observer selector should be dynamic.

Resources