Help us understand the problem. What is going on with this article?

React NativeのインストールからGoogle OAuthを導入して、Google Calendar APIを叩く (iOS編)

More than 1 year has passed since last update.

はじめに

React NativeでGoogle OAuthの導入とGoogle Calendar APIを叩く話をします。
今回使うのは純正のSDKをラップしてる https://github.com/devfd/react-native-google-signin を利用します。

React Nativeのインストール

既にインストール及びEject済みの場合は読み飛ばしてください。
登場するコマンドのtreeやnpm, watchmanなどはhomebrew等で入れておいてください。
Xcodeが必要です。

下記のコマンドでreact nativeをインストールします。

create-react-native-appをインストール
# npm install -g create-react-native-app
# npm install -g react-native-cli

次にアプリケーションを作成します。

アプリケーションを作成する
$ create-react-native-app Enjoy

インストールが終わると下記のような階層になっています。

ReactNativeアプリの階層
$ tree . -L 2
.
└── Enjoy
    ├── App.js
    ├── App.test.js
    ├── README.md
    ├── app.json
    ├── node_modules
    └── package.json

これで、React Nativeのインストールが完了しました。
次に、Ejectをします。

Eject
$ cd Enjoy
$ npm run eject

開始してエンターキーを押すとアプリケーション名を聞かれるので、適当に入れていきます。

アプリケーション名の入力

$ npm run eject

> Enjoy@0.1.0 eject /Users/memory/Dropbox/WORKSPACE/memory-agape/mem.enjoy/rn/Enjoy
> react-native-scripts eject


...省略

? How would you like to eject from create-react-native-app? React Native: I'd like a regular React Native project.
We have a couple of questions to ask you about how you'd like to name your app:
? What should your app appear as on a user's home screen? Enjoy # 今回はEnjoy
? What should your Android Studio and Xcode projects be called? (Enjoy) Enjoy # 今回はEnjoy

Ejectが完了すると、package.jsonなどの中身が変わり、また、ios及びandroidディレクトリが生成されます。
treeコマンドで見てみます。

treeコマンド
$ tree . -L 2
.
└── Enjoy
    ├── App.js
    ├── App.test.js
    ├── README.md
    ├── android
    ├── app.json
    ├── index.js
    ├── ios
    ├── node_modules
    └── package.json

4 directories, 6 files

これで、Ejectが完了し、ちゃんとReact Nativeとしての形となりました。
シミュレータが起動するかどうかテストしてみます。

シミュレータを起動する
$ npm run ios

npm run iosを実行するとビルドが始まります。実行する前にXcodeを起動し、予めコンポーネントやシミュレータのインストールをしておいてください。
詳しくはこれを御覧ください https://facebook.github.io/react-native/docs/getting-started.html#xcode (英文)

うまく成功すると下記のようなシミュレータが起動し、Viewが表示されます。
Screen Shot 2017-11-15 at 18.21.39.png

以上でReact Nativeの導入完了です。

Google OAuthボタンを導入する

では、本題でGoogle OAuthのボタンを導入していきます。
下記のコマンドより、react-native-google-signin をインストールします。

react-native-google-signinをインストール
$ npm install react-native-google-signin --save

その後、各プロジェクトにネイティブライブラリを紐付けるために、react-native linkを使用します。

$ react-native link react-native-google-signin

ネイティブライブラリの紐付けを完了したあとに、podで、Google SDK類をインストールします。

はじめにPodfileを生成します。

Podfileの生成
$ cd Enjoy/ios
$ pod init

Podfileの中身を下記のようにします。必要であれば適宜変更してください。

Podfile
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'enjoy' do
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  # use_frameworks!

  # Pods for enjoy
  pod 'GoogleSignIn'
  pod 'GoogleAuthUtilities'
  pod 'GoogleUtilities'
  pod 'GoogleAppUtilities'

end

pod install で必要モジュール類をインストールします。

インストール
$ pod install

その後、iOSのインストールガイドに従って、必要ファイル類をダウンロードします。

Google Cloud Consoleよりプロジェクトを作成する。

  • https://console.cloud.google.com/projectcreate にアクセス
  • 下記の図のようにプロジェクト名等を入力します。 Screen_Shot_2017-11-15_at_18_45_42.png
  • プロジェクトを選択します。
    Screen_Shot_2017-11-15_at_18_48_24.png

  • Google Calendar APIを有効にするためライブラリ一覧に移動します。
    Screen_Shot_2017-11-15_at_18_55_01.png

  • calendarで検索し、APIを選択します。
    Screen_Shot_2017-11-15_at_18_54_33.png

  • APIを有効にします。
    Screen_Shot_2017-11-15_at_18_59_20.png

  • 次に、クライアントIDを作成するために認証情報ページへ移動します。
    Screen_Shot_2017-11-15_at_18_50_19.png

  • 認証情報を作成します。
    Screen_Shot_2017-11-15_at_18_52_30.png

  • 同意画面の設定を促されるので、表示のとおりに進めます。
    Screen_Shot_2017-11-15_at_19_00_40.png

  • 同意画面に必要な情報を入力し、設定を保存します。
    Screen_Shot_2017-11-15_at_19_02_42.png

  • 画面上部タブの「認証情報」をクリックして改めて、認証情報を作成します。
    Screen_Shot_2017-11-15_at_18_52_30.png

  • クライアントIDを作成します。
    Screen_Shot_2017-11-15_at_19_05_47.png
    (※) Bundle IDはEnjoy/ios/enjoy.xcworkspaceをXcodeで開き、下記図のように調べられます。
    Screen_Shot_2017-11-15_at_19_10_57.png

  • クライアントIDが生成されるのでコピーしておきます。
    Screen_Shot_2017-11-15_at_19_12_25.png

上記にて、GoogleのクライアントIDの取得は完了です。

Google project configuration

※上記では省略されているのでダウンロードの手順を明記しておきます。
- 設定ファイルのダウンロードを選びます。
Screen_Shot_2017-11-15_at_19_14_19.png

  • ダウンロード対象のプロジェクトを選択します。
    Screen_Shot_2017-11-15_at_19_15_22.png

  • Google SignInを有効化する
    Screen_Shot_2017-11-15_at_19_18_52.png

  • GoogleService-Info.plist をダウンロードする
    Screen_Shot_2017-11-15_at_19_19_03.png
    Screen_Shot_2017-11-15_at_19_21_02.png

上記で、Google project configurationは完了です。

XcodeでinfoのURL Typesを変更する

  • Xcodeを開き、URL Typesの値をGoogleService-info.plistを元に2つ追加します。(追加するのはREVERSED_CLIENT_IDの値(value)とBUNDLE_IDの値(value)です。) Screen_Shot_2017-11-15_at_19_27_41.png

上記で完了です。

AppDelegate.mを修正し、Google OAuthを読み込む

再度、シェルに戻り、 npm run iosを走らせて、 stdout上にBUILD SUCCESSEDとでれば正常に設定ができています。
Screen_Shot_2017-11-15_at_19_39_17.png

実際にGoogle OAuthボタンのレンダリングとカレンダー取得のコードを書いていく

  • 下記は本家のサンプルを調整したものなので、適宜変えてください。
App.js
import React, { Component } from 'react';
import {
    StyleSheet,
    View,
} from 'react-native';
import {
    GoogleSignin,
    GoogleSigninButton
} from 'react-native-google-signin';

import GoogleCalendar from './GoogleCalendar';

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center',
    },
});

export default class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            user: null
        };
    }

    componentDidMount() {
        this.setupGoogleSignin();
    }

    async setupGoogleSignin() {
        try {
            await GoogleSignin.configure({
                iosClientId: "先程コピーしてきたクライアントIDをここに貼り付ける",
                offlineAccess: false,
                // カレンダーAPIを叩ける用に本家のサンプルよりスコープを追加しています。
                scopes: [
                    'https://www.googleapis.com/auth/calendar',
                    'https://www.googleapis.com/auth/calendar.readonly',
                ],
            });

            const user = await GoogleSignin.currentUserAsync();
            this.setState({
                user
            });

        } catch(err) {
            console.log("Google signin error", err.code, err.message);
        }
    }

    signIn() {
        GoogleSignin.signIn()
            .then((user) => {
                this.setState({user: user});
            })
            .catch((err) => {
                console.log('WRONG SIGNIN', err);
            })
            .done();
    }

    signOut() {
        GoogleSignin.revokeAccess().then(() => GoogleSignin.signOut()).then(() => {
            this.setState({user: null});
        })
            .done();
    }

    render() {
        let view = null;
        if (this.state.user) {
            view = <GoogleCalendar user={this.state.user} />;
        } else {
            view = <GoogleSigninButton
                    style={
                        {
                            width: 212,
                            height: 48,
                        }
                    }
                    size={GoogleSigninButton.Size.Standard}
                    color={GoogleSigninButton.Color.Auto}
                    onPress={this.signIn.bind(this)}
                />;
        }
        return (
            <View style={styles.container}>
                {view}
            </View>
        );
    }
}
  • GoogleCalendar.jsを作り、カレンダーAPIを叩くためのコードを用意します。
GoogleCalendar.js
import React, { Component } from 'react';
import {
    StyleSheet,
    Text,
    View,
} from 'react-native';

export default class GoogleCalendar extends Component {
    constructor(props) {
        super(props);
        this.state = {
            events: [],
        };
    }
    componentDidMount() {
        this.getEvents();
    }
    async getEvents() {
        // アクセストークンだけを取り出します。
        const { accessToken } = this.props.user;

        // 必要に合わせて、カレンダーの対象を選んでください。
        const calendarId = 'primary';

        // カレンダーの取得する開始日時を指定します。
        const timeMin = (new Date()).toISOString();

        try {
            // カレンダーAPIを叩きます。 (React Nativeのfetchを利用します。)
            const url = `https://www.googleapis.com/calendar/v3/calendars/${calendarId}/events?singleEvents=true&orderBy=startTime&timeMin=${encodeURIComponent(timeMin)}&access_token=${encodeURIComponent(accessToken)}`;
            const response = await fetch(url);
            const responseJson = await response.json();
            this.setState({
                events: responseJson.items,
            });
        } catch (error) {

        }
    }
    render() {
        return (
            <View>
                {this.state.events.map((event) => {
                    return (
                        <Text key={event.id}>
                            {event.start.dateTime}{event.end.dateTime}
                        </Text>
                    )
                })}
            </View>
        );
    }
}
  • 成功すると下記のようにSign Inボタンが表示されます。 Screen Shot 2017-11-15 at 19.52.05.png

クリックすると… 下記のようにSFSafariViewControllerが起動し、正常なGoogleOAuthを行うことができるようになります。

Screen_Shot_2017-11-15_at_20_00_36.png

認証を進めると、カレンダー情報に記載されている日付がISO8601形式で取得できているのが確認できました!
Screen Shot 2017-11-15 at 20.02.26.png

最後は駆け足になってしまいましたが、React NativeのインストールとGoogle OAuth, またGoogle Calendar APIを叩く話は以上になります。
余談ですが、今回はGoogle Calendar APIのevent取得のみを対象としていますが、他のAPIを叩くことももちろん可能です。(React NativeのfetchはPOSTなども投げれるので。)

久しぶりに長い記事書いた…。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした