GIDSignInButton の見た目のカスタマイズ

この前初めて、Firebase Authentication を使用した Google でのサインインを実装しました。

GoogleSignIn のパッケージが提供してくれているデフォルトの `GIDSignInButton`の見た目のカスタマイズがどこまでできるかを調べてみたので、それについて記載します。

SwiftUI を使用したコードになっています。

# 環境

- Xcode 13.4.1
- Firebase 9.0.0
- GoogleSignin 6.0.0 の GoogleSignIn（**GoogleSignInSwiftではない方**）
- iPhone 13 (15.5) Simulator：ライトモード

# カスタマイズ可能な部分

`GIDSignInButton`クラスのコードを確認したところ、そのクラスから提供されているカスタマイズ可能なプロパティは、以下2つです

- `GIDSignInButtonStyle`：レイアウトのスタイル
- `GIDSignInButtonColorScheme`：カラースキーム

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/05c07bca-06fa-9809-3a64-5a6948b3606d.png)

## レイアウトのスタイル

現時点で定義されているタイプは、以下の３つになります。

- `kGIDSignInButtonStyleStandard`: 230 x 48 （テキストは「Sign in」）
- `kGIDSignInButtonStyleWide`:     312 x 48 （テキストは「Sign in with Google」）
- `kGIDSignInButtonStyleIconOnly`: 48 x 48 (テキストなし、固定サイズ、アイコンのみ)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/652a0610-7050-0c00-7620-083ff8d6855a.png)

それぞれこのようになります。

|`kGIDSignInButtonStyleStandard`|`kGIDSignInButtonStyleWide`|`kGIDSignInButtonStyleIconOnly`|
|---|---|---|
|![Simulator Screen Shot - iPhone 13 - 2022-08-21 at 08.42.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/25cd45d6-900f-55c5-108f-a09f63640c92.png)|![Simulator Screen Shot - iPhone 13 - 2022-08-21 at 08.44.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/ce03a1df-5c95-45ff-bfee-568a9781031c.png)|![Simulator Screen Shot - iPhone 13 - 2022-08-21 at 08.44.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/d97d8dbf-e5ae-30f6-5e86-9bbcd0b0525a.png)|

アイコンだけというのも使い道ありそうな気がしました。

あと特に書いてなかったんですが、standard と wide で表示されるテキストも違うんだというのが気づきでした。

詳細を調べてみたので、気になる方は以下を開いてみてください。
結論、**standard は「Sign in」で、wide は「Sign in with Google」と表示されるようになっており**、特に私の実装ミスなどではなかったです。

<details><summary>standard と wide で表示されるテキストの違いについて</summary>


`GIDSignInButton.m`の[ここ](https://github.com/google/GoogleSignIn-iOS/blob/5ce850448e89500aca5b095af7247eb46dc0ca18/GoogleSignIn/Sources/GIDSignInButton.m#L558-L566)の実装を見てみました。👀

なんだか違いそうな雰囲気ですね・・・

```obj_c
- (NSString *)buttonText {
  switch (_style) {
    case kGIDSignInButtonStyleWide:
      return [GIDSignInStrings signInWithGoogleString];
    case kGIDSignInButtonStyleStandard:
    case kGIDSignInButtonStyleIconOnly:
      return [GIDSignInStrings signInString];
  }
}
```

[`GIDSignInStrings.h`](https://github.com/google/GoogleSignIn-iOS/blob/main/GoogleSignIn/Sources/GIDSignInStrings.h)はこのようになってました。

あ確かに違うらしい。

```obj_c
// "Sign In"
+ (nullable NSString *)signInString;

// "Sign in with Google"
+ (nullable NSString *)signInWithGoogleString;
```

ダメ押しで`GIDSignInStrings.m`の方も見てみると、
まだ文字列は出てこないですが、ローカライズ対応されていることがわかりますね。

```obj_c
// Button texts used as both keys in localized strings files and default values.
static NSString *const kStandardButtonText = @"Sign in";
static NSString *const kWideButtonText = @"Sign in with Google";

・・・

+ (nullable NSString *)signInString {
  return [self localizedStringForKey:kStandardButtonText text:kStandardButtonText];
}

+ (nullable NSString *)signInWithGoogleString {
  return [self localizedStringForKey:kWideButtonText text:kWideButtonText];
}
```

で、文字列が定義されているのは、[`en.lproj/GoogleSignIn.strings`](https://github.com/google/GoogleSignIn-iOS/tree/main/GoogleSignIn/Sources/Strings/en.lproj)です。

```obj_c
/* Sign-in button text */
"Sign in" = "Sign in";

/* Long form sign-in button text */
"Sign in with Google" = "Sign in with Google";
```

というわけで standard と wide でどういうわけか文字列が違うことがわかりました。
今回はUI なので、実装すれば文字列の違いはすぐ気づきますが、自分の実装ミスなのか仕様なのか判断に迷うので、コードコメントにでも書いといてほしいですね（となぜかここで不満... :sweat_drops: ）

ちなみに今回確認しているのは、GoogleSignIn のProductの方なのですが、SwiftUI 向けの GoogleSignInSwift のProductの方でもこれは変わらず、standard と wide で表示されるテキストが異なります。（[ここ](https://github.com/google/GoogleSignIn-iOS/blob/5ce850448e89500aca5b095af7247eb46dc0ca18/GoogleSignInSwift/Sources/GoogleSignInButtonStrings.swift#L24-L29)）

```swift
/// Button text used as both key in localized strings files and default value
/// for the standard button.
private let standardButtonText = "Sign in"
/// Button text used as both key in localized strings files and default value
/// for the wide button.
private let wideButtonText = "Sign in with Google"
```

</details>




## カラースキーム

現時点で定義されているタイプは、以下の2つになります。

- `kGIDSignInButtonColorSchemeDark`：ダーク →という名前だけど色は青
- `kGIDSignInButtonColorSchemeLight`：ライト（こっちがデフォルト）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/86d33b6b-05ae-d9e4-b43c-54998ab595f1.png)

それぞれこのようになります。

|`kGIDSignInButtonColorSchemeDark`|`kGIDSignInButtonColorSchemeLight`|
|---|---|
|![Simulator Screen Shot - iPhone 13 - 2022-08-21 at 08.47.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/1b2e031f-7c47-316b-72dd-571362dea208.png)|![Simulator Screen Shot - iPhone 13 - 2022-08-21 at 08.50.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401966/11d40230-8a25-922a-58df-f4c5a2985e67.png)|

# コード

こんな感じで実装しました。**SwiftUI で GoogleSignIn の Product を使用して実装する**には、UIViewRepresentable に準拠した構造体を作って実装していく必要がありますが、そんなにコード量は多くなかったです。

```swift
import Foundation
import SwiftUI
import GoogleSignIn

struct GoogleSignInButton: UIViewRepresentable {
    typealias UIViewType = GIDSignInButton

    func makeUIView(context: Context) -> GIDSignInButton {
        let button = GIDSignInButton()
        button.style = .iconOnly  // レイアウトのスタイルの定義
        button.colorScheme = .light  // カラースキームの定義
        return button
    }

    func updateUIView(_ uiView: GIDSignInButton, context: Context) {
    }
}
```

:::note warn
記事を書き終えてから気づきましたが、GoogleSignIn は SwiftUI に対応しているので、GoogleSigIn のProductではなく、GoogleSignInSwift のProductを使う方が良いかと思います。
:::

追記：GoogleSignInSwift についての記事を書きました。

https://qiita.com/kamimi01/items/faba70cb86839383a51a


# おわりに

アイコンオンリーのスタイルがあったことや、カラースキームを変えられることは知らなかったので、書いてみました。
今回の内容は、[`GIDSigInButton.h`](https://github.com/google/GoogleSignIn-iOS/blob/main/GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignInButton.h)を見れば一発でわかる内容だったので、気になる方はそちらを参照ください。

細かいUIの実装が見たい場合は、[`GIDSignInButton.m`](https://github.com/google/GoogleSignIn-iOS/blob/main/GoogleSignIn/Sources/GIDSignInButton.m)にあります。

ちなみに個人的には意外とカスタマイズ性低いなと感じたので、自分で自作ボタンを作ることにしました :sweat: 

どなたかのお役に立てば幸いです。そして何か間違い等ありましたら、ご指摘いただけますと嬉しいです。 :blush: