2016-02-12 140 views
1

我执行本教程https://developers.google.com/identity/sign-in/ios/sign-in?configured=true&ver=swift终止应用程序由于未捕获的异常“NSInvalidArgumentException” - 在

在拍摄过程中,谷歌的标志,因为我可以看到有作者写的ios谷歌标志:

In these examples, the view controller is a subclass of UIViewController. If, in your project, the class that implements GIDSignInUIDelegate is not a subclass of UIViewController, implement the signInWillDispatch:error:, signIn:presentViewController:, and signIn:dismissViewController: methods of the GIDSignInUIDelegate protocol.

所以后,他建议我写如下:

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) 
} 


} 

当我运行应用程序时,我看到按钮sign in with google。但是当我点击它时,我看到错误:

这里有什么问题?我以为我包括必要的方法...

============编辑 - 作为跟进@ emrys57问题:

我有GoogleService-Info.plist文件附加在我的项目:

enter image description here

当我注释掉的3种方法(presentViewControllerdismissViewControllersignInWillDispatch)没有什么变化 - 我仍然得到同样的错误..

大约T t他画面 - 这是我的故事板看起来像:

enter image description here

,我想显示谷歌日志按钮,在第三屏幕上。

这里的第二个屏幕包含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. 
    } 

} 

还有一两件事 - 当我打开应用程序,我现在看到的谷歌登录按钮:

enter image description here

,当我点击它 - 我得到了提到的错误:

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并添加了按钮 -​​ 一切正常,我看到一个谷歌登录按钮,我可以登录!但 - 该按钮出现在应用程序的第一个屏幕上,这不是我想要的。我希望它出现在第三个屏幕上(在教程之后)。有人知道这里发生了什么,为什么我不能把登录按钮放在第三个屏幕上?

+1

在LoginScreen实例化的地方并不清楚。出现此消息时,LoginScreen正在运行,因此uiDelegate已设置?你添加了“GoogleService-Info.plist”文件吗?显然你只需要3个UIDelegate方法,如果你的类不是UIViewcontroller。但你的是。那么如果你注释掉3个委托方法会发生什么? – emrys57

+0

@ emrys57我为您的问题添加了答案,请参阅我上面的修改,谢谢! – randomuser1

+1

这变得越来越困难。如果今天晚些时候这个问题仍然存在,我会尝试运行你的代码,但我现在必须去关注我的妻子。 – emrys57

回答

1

func signIn(signIn: GIDSignIn!, presentViewController viewController: UIViewController!)距离GIDSignInUIDelegate协议的方法,但上面的代码指出AppDelegate采用GIDSignInDelegate(未“UI”)协议,和你的GIDSignInUIDelegate不提供方法。这两个类都采用了错误的协议,或者这些方法存在错误的类。

+0

好吧,我把presentViewController和dismissViewController两个方法移到了我的' LoginScreen'类,但不幸的是,它并没有成功。我究竟做错了什么? – randomuser1

+0

也许你应该用新的代码更新你的问题,或者提出一个新的问题。很难从这里看到。另外,对不起,我要睡觉了。祝你好运! – emrys57

+0

我在你的建议后编辑了我的问题中的代码,但问题仍然出现 – randomuser1

8

我知道这已经太晚了,但如果你将GIDSignIn.sharedInstance().uiDelegate = self放入viewDidAppear中,而不是viewDidLoad,那对别人很有帮助!

+1

viewWillAppear固定为我... – allaire

0

不是这个问题的问题,但这也可能是由于Obj-C到Swift 3命名的自动生成导致的,导致GIDSignInUIProtocol的方法签名与Google的SDK所期望的不同。

添加这些转发方法的GIDSignInUIProtocol实施将解决这一问题对于这种情况 -

func signIn(signIn: GIDSignIn!, presentViewController viewController: UIViewController!) { 
    self.sign(signIn, present: viewController) 
} 

func signIn(signIn: GIDSignIn!, dismissViewController viewController: UIViewController!) { 
    self.sign(signIn, dismiss: viewController) 
} 
+0

但这也不适合我!这是一个SDK故障 – iProgrammer

0

更新了斯威夫特3:

低于签到按钮操作的代码行使用方法

GIDSignIn.sharedInstance().uiDelegate = self 
GIDSignIn.sharedInstance().delegate = self 
GIDSignIn.sharedInstance().signIn() 

Note: Comments above lines of code if you are using it anywhere in your ViewController...! otherwise it will be fine.

享受学习....!

相关问题