在这个教程中,作者写道:
“在这些示例中,视图控制器是UIViewController的子类。如果在您的项目中,实现GIDSignInUIDelegate的类不是UIViewController的子类,请实现GIDSignInUIDelegate协议的signInWillDispatch:error:、signIn:presentViewController:和signIn:dismissViewController: 方法。”
因此,我按照他的建议编写了以下内容:
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
func application(application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Initialize sign-in
var configureError: NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError)")
GIDSignIn.sharedInstance().delegate = self
return true
}
// [START openurl]
func application(application: UIApplication,
openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
return GIDSignIn.sharedInstance().handleURL(url,
sourceApplication: sourceApplication,
annotation: annotation)
}
// [END openurl]
@available(iOS 9.0, *)
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
return GIDSignIn.sharedInstance().handleURL(url,
sourceApplication: options[UIApplicationOpenURLOptionsSourceApplicationKey] as! String?,
annotation: options[UIApplicationOpenURLOptionsAnnotationKey])
}
// [START signin_handler]
func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!,
withError error: NSError!) {
if (error == nil) {
print("Signed in!")
} else {
print("\(error.localizedDescription)")
}
}
// [END signin_handler]
// [START disconnect_handler]
func signIn(signIn: GIDSignIn!, didDisconnectWithUser user:GIDGoogleUser!,
withError error: NSError!) {
// Perform any operations when the user disconnects from app here.
// [START_EXCLUDE]
NSNotificationCenter.defaultCenter().postNotificationName(
"ToggleAuthUINotification",
object: nil,
userInfo: ["statusText": "User has disconnected."])
// [END_EXCLUDE]
}
我也有一个名为
LoginScreen.swift
的类,其中包含:import UIKit
class LoginScreen: UIViewController, GIDSignInUIDelegate {
override func viewDidLoad() {
super.viewDidLoad()
GIDSignIn.sharedInstance().uiDelegate = self
// Uncomment to automatically sign in the user.
GIDSignIn.sharedInstance().signInSilently()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
GIDSignIn.sharedInstance().uiDelegate = self
GIDSignIn.sharedInstance().signInSilently()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func signInWillDispatch(signIn: GIDSignIn!, error: NSError!) {
print("Nothing!")
}
// Present a view that prompts the user to sign in with Google
func signIn(signIn: GIDSignIn!,
presentViewController viewController: UIViewController!) {
self.presentViewController(viewController, animated: true, completion: nil)
}
// Dismiss the "Sign in with Google" view
func signIn(signIn: GIDSignIn!,
dismissViewController viewController: UIViewController!) {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
当我运行该应用程序时,我看到一个按钮使用谷歌登录
。 但是,当我单击它时,我会看到以下错误:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: 'When |allowsSignInWithWebView| is enabled, uiDelegate must
either be a |UIViewController| or implement the
|signIn:presentViewController:| and |signIn:dismissViewController:|
methods from |GIDSignInUIDelegate|.'
这里的问题是什么?我以为我已经包含了必要的方法......
============ 编辑 - 作为对 @emrys57 问题的跟进:
我在我的项目中附加了 GoogleService-Info.plist
文件:
当我注释掉这三个方法 (presentViewController
, dismissViewController
和 signInWillDispatch
),没有任何变化 - 我仍然得到相同的错误...
关于屏幕 - 这是我的故事板的样子:
我想在第三个屏幕上显示 Google 登录按钮。
这里的第二个屏幕包含一个 Tutorial
,其代码目前如下:
import UIKit
class Tutorial: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let background = CAGradientLayer().greenBlue()
background.frame = self.view.bounds
self.view.layer.insertSublayer(background, atIndex: 0)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
还有一件事 - 当我打开应用程序时,现在我看到了谷歌登录按钮: 当我点击它时 - 我得到了上述的错误:
2016-02-13 09:47:49.578 myapp[20870:800499] *** Terminating app due
to uncaught exception 'NSInvalidArgumentException', reason: 'When
|allowsSignInWithWebView| is enabled, uiDelegate must either be a
|UIViewController| or implement the |signIn:presentViewController:| and
|signIn:dismissViewController:| methods from |GIDSignInUIDelegate|.'
*** First throw call stack:
(...)
所以我猜当我点击按钮时,LoginScreen
正在运行...
=========== 另一个编辑:
当我将代码从我的LoginScreen
复制到ViewController
类中,并在那里添加按钮时 - 一切都正常工作,我可以看到google登录按钮,并且我可以登录!但是 - 按钮出现在应用的第一个屏幕上,这不是我想要的。我希望它出现在第三个屏幕上(在教程之后)。有人知道发生了什么事情,为什么我不能在第三个屏幕上放置登录按钮吗?
GoogleService-Info.plist
文件?显然,如果您的类不是UIViewcontroller,则只需要3个UIDelegate方法。但是你的视图控制器是的。因此,如果您注释掉这3个委托方法,会发生什么? - emrys57