36617

[code]

    import UIKit
    import Firebase
    import FirebaseAuth
    import GoogleSignIn
    
    class LoginViewController: UIViewController, UITextFieldDelegate,GIDSignInDelegate, GIDSignInUIDelegate {
    
    @IBOutlet var mailField: UITextField!
    @IBOutlet var passwdField: UITextField!
    
    @IBOutlet weak var googleSignIn: GIDSignInButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        mailField.delegate = self
        passwdField.delegate = self
    
        GIDSignIn.sharedInstance().clientID = FIRApp.defaultApp()?.options.clientID
        GIDSignIn.sharedInstance().delegate = self
        GIDSignIn.sharedInstance().uiDelegate = self
    }
    
    @IBAction func googleSignInClicked(sender: AnyObject) {
        GIDSignIn.sharedInstance().signIn()
    }
    
    
    func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!,
                withError error: NSError!) {
        print("Google Sing In didSignInForUser")
        if let error = error {
            print(error.localizedDescription)
            return
        }
        let authentication = user.authentication
        let credential = FIRGoogleAuthProvider.credential(withIDToken: (authentication?.idToken)!,accessToken: (authentication?.accessToken)!)
        //ユーザ登録後の処理....
    
    }
    
    func signIn(signIn: GIDSignIn!, didDisconnectWithUser user:GIDGoogleUser!,
                withError error: NSError!) {
        print("Google Sing In didDisconnectWithUser")
        // Perform any operations when the user disconnects from app here.
        // ...
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    @objc(textFieldShouldReturn:) func textFieldShouldReturn(_ mailField: UITextField) -> Bool{
        mailField.resignFirstResponder()
        return true
    }
    
    func passwdFieldShouldReturn(_ passwdField: UITextField) -> Bool{
        passwdField.resignFirstResponder()
        return true
    }
    
    
    @IBAction func loginBtn(_ sender: Any) {
        var mailAdress = mailField.text
        var password = passwdField.text
    
        //ワーニングが出るため別の方法を使用したほうがいい可能性有り
    
        FIRAuth.auth()?.signIn(withEmail: mailAdress!, password: password!) { (user, error) in
            if let error = error {
                print("サインインできません \(error)")
                let alert: UIAlertController = UIAlertController(title: "エラー", message: "メールアドレスまたはパスワードが間違っています", preferredStyle:  UIAlertControllerStyle.alert)
                let defaultAction: UIAlertAction = UIAlertAction(title: "リトライ", style: UIAlertActionStyle.default, handler:{
                    (action: UIAlertAction!) -> Void in
                    //処理部分だが、そのままAlertを閉じさせればいいためコードなし
    
                })
                alert.addAction(defaultAction)
                self.present(alert, animated: true, completion: nil)
                return
                //ログイン失敗時の処理
            }
    
            if let user = user {
                print("user : \(user.email!) サインインできました")
                let storyboard: UIStoryboard = self.storyboard!
                let nextView = storyboard.instantiateViewController(withIdentifier: "joined") as!JoinedViewController
                self.present(nextView, animated: true, completion: nil)
                //ログイン成功時の処理
            }
        }
    
     }
    
[/code]

この様な形で現在書いているのですが

Type 'LoginViewController' does not conform to protocol 'GIDSignInDelegate'

とエラーが出てしまいます。これらのコードはどの様な形で実装したらいいのでしょうか？

Protocol requires function 'sign(_:didSignInFor:withError:)' with type
'(GIDSignIn!, GIDGoogleUser!, Error!) -> Void'; do you want to add a stub?
(GoogleSignIn.GIDSignInDelegate)

と書かれているので

func sign(_:didSignInFor:withError:)

という感じでしょうか？誰か教えてください！

追記  
[![画像の説明をここに入力](https://i.stack.imgur.com/Yy4ih.png)](https://i.stack.imgur.com/Yy4ih.png)


CC BY-SA 3.0
2017-07-23T12:21:27.427
36613
2017-07-23T13:37:48.690
2017-07-23T12:44:12.370
13543
13543
question
swift swift3 xcode8
FirebaseのGoogleログイン時に使うデリゲートGIDSignInDelegateのエラー


コメントした通りですが、Swift 3がObjective-CのメソッドをSwiftに移入する場合には、[SE-0005 Better
Translation of Objective-C APIs Into Swift](https://github.com/apple/swift-
evolution/blob/master/proposals/0005-objective-c-name-
translation.md)が適用されて、メソッド名の書き換えが行われます。したがって、外部フレームワークをSwiftに移入した時には、どんな名称になるのかSwift2までの規則的なやり方ではわかりにくい時があります。

詳細にはどのルールのどの部分がどのように適用されたのかはわかりませんが、想像するに`signIn`の`In`が引数の型名`GIDSignIn`の語尾と一致するために型名と判断されて、2:
**Prune redundant type names**
の規則が適用され、「`In`は冗長な型名だからメソッド名やラベル名からは省く」と判定されたのでしょう。(`User`と言うのは明らかに型名なのでその規則が適用されているものと思われるのですが、`In`を型名と判断して省略してしまうとは…。)

Xcodeからのサジェスチョン _do you want to add a stub?_
を受け入れてメソッドヘッダーを作らせれば良いでしょう。手動でやる場合、`sign(_:didSignInFor:withError:)`と言うSwiftのメソッド参照用表記はパラメータラベルのみを表していて、仮パラメータ名・型指定やコンマが省略されているので、こんな感じになるはずです。

[code]

    func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, :withError error: Error!) {
        //
    }
    
[/code]

(Xcodeのコード補完が有効な状態で作業していれば、`sign`あたりまで入力すると表示される候補の一覧の中にあるはずです。)

中身に記載する処理としては、実態としてはこのメソッドは`sign:didSignInFor‌​User:withError:`を表しているので、あなたがご掲載のコードにある:

[code]

    func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!,
                withError error: NSError!) {
        //...
    }
    
[/code]

の中身の処理を新しいメソッドに移動させてやることになるでしょう。(`NSError!`型が`Error!`型に変わっているなど、データ型の変更もあるので、若干コードの書き換えが必要かもしれません。)要はメソッド宣言のヘッダー部分だけさっきのように書き換えてやることになります。

おそらく、こちらのメソッド:

[code]

    func signIn(signIn: GIDSignIn!, didDisconnectWithUser user:GIDGoogleUser!,
                withError error: NSError!) {
        //...
    }
    
[/code]

も同様の書き換えが必要になるだろうと思われます。Xcodeのサジェスチョンやコード補完の機能を利用して正しいメソッドヘッダーに書き換えてください。

* * *

正直コードだけ見てSwiftのバージョンを判定するのが難しいほど、古い時代のSwiftのコードを無判別に取り込まれているように感じます。(おそらくそのせいで他にも修正すべき箇所が多数出るでしょう。)別回答にも書きましたが、そう言ったことを自分で修正できないのであれば、必ずSwiftのバージョンを確かめて、
**Swift3用のコード以外は利用しないことを強くお勧め** しておきます。


CC BY-SA 3.0
2017-07-23T13:37:48.690
36617
2017-07-23T13:37:48.690
13972
36613
answer