2016-02-12 143 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.

享受學習....!

相關問題