反応と流れでイオンチャットアプリを構築する方法


Update: Here is an excellent post on the vision for 2020's tech trends in cloud computing between the CEO of Ionic, , and CEO of Stream, .


プラットフォーム間に大きな違いがありますReact Native and Flutter 比較してIonic . イオンは、今日のウェブを動かすオープンテクノロジーが将来であり、モバイルアプリを構築するために使用されるべきであると信じています.そのアプローチのために、イオンは、両方のWebとモバイルデバイスのための同じコードベースを再利用することができます唯一の人気のプラットフォームの一つです-あなたのコードを維持することができます(自分自身を繰り返すことはありません).
フラッタとネイティブに反応する一方で、Web技術スタックを置き換えます.フラッタは、このrendering engine , ネイティブのフックをiOS and Android’s native rendering engine .
イオンの利点は、Webベースの技術を使用しているし、単一のコードベースを再利用することができます.一方、フラッタとネイティブの反応は、コードを再利用することはできませんしかし、彼らのパフォーマンスは、ネイティブアプリケーションの感じにはるかに近いです.それでも、あなたのコードを乾燥させておく能力を持つことは、どんなアプリケーションででも主要なゴールでなければなりません.
このチュートリアルでは、私はどのようにリアルタイムでチャットイオンを使用してアプリケーションを構築する方法を歩いていきます.React (はい、Web用に使用するのと同じバージョン)とStream’s real-time Chat API .

If you want to skip ahead, a demo is available on Appetize, so you can evaluate performance yourself (note that Appetize does slow things down quite a bit though). You can also download the signed APK for Android for a more performant experience. Here is the React / Ionic GitHub repo and here is the API GitHub repo.

There are a few requirements for this, primarily the version of Node.js (I prefer to use nvm for Node version management), XCode for iOS if you’re on macOS or Android Studio if you’re on macOS or Windows and want to build against Android, and yarn for dependency management.


コードしましょう!🤓

イオンのインストール


始めるIonic , ダウンロードIonic CLI 糸の使用
$ yarn global add ionic
インストールされると、新しいCLIを使用してコマンドラインからイオンにログインします.
$ ionic login
今のところ、それは我々がしなければならないすべてです.私たちは使用するつもりですCreate React App (次のステップ)インストールを続けます.

2 . Create Reactionアプリと依存関係をインストールする


イオンをインストールした方法と同様に、NPMを使用して、CREATE ROORT APP ( CRA )をグローバルにインストールしましょう.
$ yarn global add create-react-app
次に、新しいディレクトリを作成します.私は仕事をするつもりです~/Code ディレクトリを選択するディレクトリを使用します.
$ cd ~/Code
さて、Create Reaction App ( CRA )-を使って反応をインストールします.ionic-chat が生成されるディレクトリの名前です.
$ npx create-react-app ionic-chat
に入るionic-chat ディレクトリと、必要な依存関係のインストールを開始します.
$ yarn add stream-chat stream-chat-react axios react-router react-router-dom @ionic/react
私たちの依存関係がインストールされているので、先に行くとセットアップの次の手順に移動しましょう.

3 . HerokuでAPIを設定する


APIは、小さいが、チャットで重要な役割を果たしている.APIは、ログイン画面からユーザー資格情報を受け入れ、チャットアプリケーション内で使用するためのJWTを生成します.また、チャネルにユーザーを追加します.
APIをスピンするには、私はシンプルな含まれているone-click Heroku ボタン.これはHerokuの新しいアプリケーションを生成し、使用するためにストリームチャットトライアルを作成します.

Herokuボタンをクリックすると、アプリケーション名を追加するように求められます.「展開」をクリックしてheroku展開プロセスを起動します.

一旦インストールされるならば、Heroku(Heroku創造は彼らを生み出しました)から環境変数を得て、彼らをあなたにドロップしてください.あなたの反応アプリでenvファイル.環境変数は、Herokuダッシュボードの「設定」セクションの下にありますshown in this blog post by Heroku . 「StreamRange URL」という環境変数は一つだけです.APIキーと秘密は: 最初のキーであり、2番目の秘密です.

Alternatively, if you would like to skip Heroku, you can clone this GitHub repo and run the API with the yarn start command – be sure to run yarn install before starting and also be sure to fill out your .env with credentials found on the Stream dashboard (you will need to enable a free chat trial).


IOSシミュレータをインストールする(オプション)


Xcodeがインストールされているなら、ほとんどすべての設定があります.そうでない場合は、xcodeをダウンロードしたいので、そうすることができますhere . XcodeはデフォルトでIOSのシミュレータにバンドルされています.
xcodeをインストールしたくない場合は、必要に応じてthis npm package , どのスタンドアロンiOSシミュレータをインストールします.
$ yarn global add ios-sim

The full instructions on how to use it are located here: https://www.npmjs.com/package/ios-sim


アンドロイドスタジオをインストールする(オプション)


MacOSでIOSで実行すると、コードをテストする最速の方法であるようですしかし、あなたがWindowsの上にいるか、単にAndroidを使うのが好きであるならば、私は以下をカバーします.
ヘッドオーバーAndroid Studio download page と選択のダウンロードを選択します.Androidのスタジオは、iOS、Windows、およびMacOSで利用可能です.これは大きなファイルです-ダウンロードは合理的な時間を取ることがあります.
ダウンロードしたらインストール手順に従ってAndroidのスタジオを開きます.我々は必要なSDKをダウンロードし、Androidの仮想デバイス(AVD)を作成するつもりです.
Android Studioオープンで、「構成」をクリックしてください.

さて、SDK Managerのオープンで、「Android 9.0(Pie)」を選択し、「Apply」をクリックします.

ダウンロードが開始されます.完了すると、メイン画面に戻ると、“設定”ボタンをクリックし、“AVDマネージャ”をクリックします.AVD Managerの画面では、“+仮想デバイスを作成”をクリックします.
次に、“ピクセル3 XL”デバイスを選択し、[次へ]をクリックします.あなたのAPIレベルの“パイ(28)”を選択し、“次へ”ボタンが続きます.

最後に、「完了」をクリックしてください.一度完了すると、安全にAVDの画面から出ることができますし、AVDマネージャで新しく作成されたAVDを表示されます.

When you click on the "green play button", your AVD will launch!



おめでとう!あなたは正常にAndroidのスタジオ内のAVDを生成しました!我々はまだそれを使用するつもりはないが、AVDは、このチュートリアルで後でテストするときに便利になります.

ファイルの作成


我々はすべてを設定している;今、私たちのコードを動作させるために必要なファイルを追加する時間です!一握りのファイルを作成する必要がありますので、注意深くお願いします.
  • ディレクトリのルートでionic.config.json 次のコンテンツを使用します.
  • {
      "name": "Ionic Chat",
      "type": "custom",
      "integrations": {}
    }
    
  • インpublic/index.html , 現在のHTMLを次のようにスワップアウトします.
  • <html lang="en">
      <head>
        <meta charset="utf-8" />
        <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1.0,
        minimum-scale=1.0, maximum-scale=1.0, viewport-fit=cover user-scalable=no"
        />
    
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta
          name="apple-mobile-web-app-status-bar-style"
          content="black-translucent"
        />
        <meta name="theme-color" content="#ffffff" />
        <meta name="apple-mobile-web-app-title" content="Ionic Chat" />
    
        <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    
        <title>Ionic Chat</title>
      </head>
      <body ontouchstart="">
        <noscript>You need to enable JavaScript to run this app.</noscript>
        <div id="root"></div>
      </body>
    </html>
    
  • に入るsrc/ ディレクトリいくつかのファイルを作り、変更します.
  • アプリで.CSSは、既存のすべてのCSSをスワップアウトします.
    @import url("https://fonts.googleapis.com/css?family=Open+Sans");
    
    html,
    body {
      background: #ffffff;
      padding: env(safe-area-inset-top) env(safe-area-inset-right) env(
          safe-area-inset-bottom
        ) env(safe-area-inset-left);
      font-family: "Open Sans", sans-serif;
    }
    
    .no-scroll .scroll-content {
      overflow: hidden;
    }
    
    ::placeholder {
      color: #3f3844;
    }
    
    .login-root {
      text-align: center;
      margin-top: 25%;
    }
    
    .login-card > h4 {
      margin-bottom: 22px;
    }
    
    .login-card > input {
      padding: 4px 6px;
      margin-bottom: 20px;
      border: 1px solid #d3d3d3;
      background: hsla(0, 0%, 100%, 0.2);
      border-radius: 4px !important;
      font-size: 16px;
      color: #24282e;
      -webkit-box-shadow: none;
      box-shadow: none;
      outline: 0;
      padding: 0 16px 1px;
      -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
      box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
      height: 50px;
      width: 300px;
    }
    
    .login-card button {
      font-size: 16px;
      background-color: #3880ff;
      border-radius: 4px;
      line-height: 1.4em;
      padding: 14px 33px 14px;
      margin-right: 10px;
      border: 0 solid rgba(0, 0, 0, 0);
      color: #ffffff;
      box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08), 0 2px 4px rgba(0, 0, 0, 0.12);
      border-radius: 6px;
      text-transform: none;
      outline: none;
    }
    
    .str-chat__loading-indicator {
      text-align: center;
      margin-top: 15%;
    }
    
    .str-chat-channel {
      background-color: #ffffff !important;
    }
    
    .str-chat__header-livestream {
      box-shadow: none !important;
      background: transparent;
    }
    
    .str-chat__square-button {
      display: none !important;
    }
    
    .str-chat__input {
      box-shadow: none !important;
    }
    
    .rta__textarea {
      padding: 4px 6px;
      margin-bottom: 20px;
      border: 1px solid #d3d3d3 !important;
      background: hsla(0, 0%, 100%, 0.2);
      border-radius: 4px !important;
      font-size: 14px !important;
      color: #24282e !important;
      -webkit-box-shadow: none !important;
      -webkit-appearance: none !important;
      box-shadow: none !important;
      outline: none !important;
      padding: 0 16px 1px;
      -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
      box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
      height: 50px;
    }
    
    .str-chat__textarea {
      height: 45px !important;
    }
    
    .str-chat__input-footer--count {
      margin-top: 4px;
      margin-left: 4px;
    }
    
    .footer {
      margin-bottom: 50px;
    }
    
    アプリで.JSは、このJavaScriptのための既存のコードを交換します(このロジックはファイル間のルーティングを気にかけます).
    import React from "react";
    import { BrowserRouter as Router, Switch } from "react-router-dom";
    
    import Chat from "./Chat";
    import Login from "./Login";
    
    import UnauthedRoute from "./UnauthedRoute";
    import AuthedRoute from "./AuthedRoute";
    
    const App = () => (
      <Router>
        <Switch>
          <UnauthedRoute path="/auth/login" component={Login} />
          <AuthedRoute path="/" component={Chat} />
        </Switch>
      </Router>
    );
    
    export default App;
    
    ファイルを作成するAuthedRoute.js そして以下の内容をファイルにドロップします.
    import React from "react";
    import { Redirect, Route } from "react-router-dom";
    
    const AuthedRoute = ({ component: Component, loading, ...rest }) => {
      const isAuthed = Boolean(localStorage.getItem("token"));
      return (
        <Route
          {...rest}
          render={props =>
            loading ? (
              <p>Loading...</p>
            ) : isAuthed ? (
              <Component history={props.history} {...rest} />
            ) : (
              <Redirect
                to={{
                  pathname: "/auth/login",
                  state: { next: props.location }
                }}
              />
            )
          }
        />
      );
    };
    
    export default AuthedRoute;
    
    チャットという名前のファイルを作成します.JSと次のコードを使用します(これは、すべてチャットのロジックです).
    import React, { Component } from "react";
    import { IonApp, IonContent } from "@ionic/react";
    import {
      Chat,
      Channel,
      ChannelHeader,
      Thread,
      Window,
      MessageList,
      MessageInput
    } from "stream-chat-react";
    import { StreamChat } from "stream-chat";
    
    import "./App.css";
    import "@ionic/core/css/core.css";
    import "@ionic/core/css/ionic.bundle.css";
    import "stream-chat-react/dist/css/index.css";
    import "stream-chat-react/dist/css/index.css";
    
    class App extends Component {
      constructor(props) {
        super(props);
    
        const { id, name, email, image } = JSON.parse(localStorage.getItem("user"));
    
        this.client = new StreamChat(localStorage.getItem("apiKey"));
        this.client.setUser(
          {
            id,
            name,
            email,
            image
          },
          localStorage.getItem("token")
        );
    
        this.channel = this.client.channel("messaging", "ionic-chat", {
          image: "https://i.imgur.com/gwaMDJZ.png",
          name: "Ionic Chat"
        });
      }
    
      render() {
        return (
          <IonApp style={{ paddingTop: "2px" }}>
            <IonContent>
              <Chat client={this.client} theme={"messaging light"}>
                <Channel channel={this.channel}>
                  <Window>
                    <ChannelHeader />
                    <MessageList />
                    <div className="footer">
                      <MessageInput />
                    </div>
                  </Window>
                  <Thread />
                </Channel>
              </Chat>
            </IonContent>
          </IonApp>
        );
      }
    }
    
    export default App;
    
    次に、ファイル名Login.js そして、以下のコードを使用します(これはアプリケーションにauthを追加します).
    import React, { Component } from "react";
    import axios from "axios";
    
    import "./App.css";
    
    class Login extends Component {
      constructor(props) {
        super(props);
    
        this.state = {
          loading: false,
          name: "",
          email: ""
        };
    
        this.initStream = this.initStream.bind(this);
      }
    
      async initStream() {
        await this.setState({
          loading: true
        });
    
        const auth = await axios.post(process.env.REACT_APP_TOKEN_ENDPOINT, {
          name: this.state.name,
          email: this.state.email
        });
    
        localStorage.setItem("user", JSON.stringify(auth.data.user));
        localStorage.setItem("token", auth.data.token);
        localStorage.setItem("apiKey", auth.data.apiKey);
    
        await this.setState({
          loading: false
        });
    
        this.props.history.push("/");
      }
    
      handleChange = e => {
        this.setState({
          [e.target.name]: e.target.value
        });
      };
    
      render() {
        return (
          <div className="login-root">
            <div className="login-card">
              <h4>Ionic Chat</h4>
              <input
                type="text"
                placeholder="Name"
                name="name"
                onChange={e => this.handleChange(e)}
              />
              <br />
              <input
                type="email"
                placeholder="Email"
                name="email"
                onChange={e => this.handleChange(e)}
              />
              <br />
              <button onClick={this.initStream}>Submit</button>
            </div>
          </div>
        );
      }
    }
    
    export default Login;
    

    Remember to swap out the REACT_APP_TOKEN_ENDPOINT environment variable in your .env with your Heroku endpoint credentials.


    では、ファイル名UnauthedRoute.js 認証されずに入力するユーザーを収容するには、次の手順に従います.
    import React from "react";
    import { Redirect, Route } from "react-router-dom";
    
    const UnauthedRoute = ({ component: Component, loading, ...rest }) => {
      const isAuthed = Boolean(localStorage.getItem("token"));
      return (
        <Route
          {...rest}
          render={props =>
            loading ? (
              <p>Loading...</p>
            ) : !isAuthed ? (
              <Component history={props.history} {...rest} />
            ) : (
              <Redirect
                to={{
                  pathname: "/"
                }}
              />
            )
          }
        />
      );
    };
    
    export default UnauthedRoute;
    
    ファイルを作成するwithSession.js :
    import React from "react";
    import { withRouter } from "react-router";
    
    export default (Component, unAuthed = false) => {
      const WithSession = ({ user = {}, streamToken, ...props }) =>
        user.id || unAuthed ? (
          <Component
            userId={user.id}
            user={user}
            session={window.streamSession}
            {...props}
          />
        ) : (
          <Component {...props} />
        );
    
      return withRouter(WithSession);
    };
    

    4 .イオンビルドスクリプトをパッケージにインストールします。JSONファイル


    "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "ionic:build": "react-scripts build",
        "ionic:serve": "react-scripts start"
    }
    
    Capacitor そばIonic オープンソースのフレームワークは、プログレッシブネイティブWebアプリケーション、モバイル、およびデスクトップアプリケーションを構築することができますイオンによって提供されます.これはイオンアプリの最適化ですしかし、それは任意のフレームワークについてだけで使用することができます.
    我々は、IOSとAndroidのために我々のビルドを持ち上げて、準備するために、コンデンサを使っています.まず最初に、しかし、コンデンサをインストールしましょう!
    $ ionic capacitor add ios
    
    次に、ルートディレクトリから以下のコマンドを実行してください.
    $ yarn start
    
    IOSで開きます.
    $ ionic capacitor open ios
    

    または、Androidで開く
    $ ionic capacitor open android
    

    私はMacOSを実行しているので、私はIOSシミュレータを使用するつもりです.アフターランニングionic capacitor open ios , Xcodeが起動します.あなたはそれがプロジェクトをインデックスするために約1分待ち、その後、実行ボタンを押すことができます.

    IOSシミュレータは、インストールされたアプリケーションで起動する必要があります.

    先に行くとお名前とメールアドレスでログインします.心配しないで、あなたの情報は、ローカルストレージに格納され、任意の種類のサードパーティ製プラットフォームに永続されていません.一度チャットウィンドウが読み込まれると、離れてチャットすることができます!

    次は何ですか。


    私はあなたが作成したCodeBaseに対して開発を継続することをお勧めします.あなたがどんな問題にでも走らせたならば、あなたは常にそうすることができますclone the repo from GitHub 新鮮なスタート.
    IOSやAndroidなどのスタンドアロンデバイスにアプリケーションを展開するという点では、イオンはどのように行うにはチュートリアルの大きなセットを持っています.IOSとAndroidの両方のチュートリアルcan be found in the Ionic docs .
    もっと知りたいStream Chat ? 我々のインタラクティブを見てくださいAPI tour これは、ストリームとスクラッチからチャットを作成する様々な手順を介して歩いていきます.
    ストリームも素晴らしいAPI documentation そして、美しいUI Kit これは、リアルタイムメッセージングプラットフォームの任意のタイプを構築することができます.
    最後に、少なくとも、私たちの様々なをチェックアウトすることを忘れないでくださいSDKs for Stream Chat , チュートリアルを含むiOS/Swift and Android/Java/Kotlin .
    デモのような?我々は、同様に利用可能なインタラクティブデモがありますthe Stream Chat website .
    ハッピーコーディング!✌