# SDK: React Native

## ステップ1: PushSDKライブラリをインポートする

お好みのパッケージマネージャーを使ってPushSDKをインストールしてください。

{% tabs %}
{% tab title="Yarn" %}

```sh
yarn add @pushly/push-sdk-react-native
```

{% endtab %}

{% tab title="NPM" %}

```sh
npm install --save @pushly/push-sdk-react-native
```

{% endtab %}
{% endtabs %}

[<mark style="color:青色;">自動リンクは自動的に提供されます</mark>](https://reactnative.dev/blog/2019/07/03/version-60#native-modules-are-now-autolinked) React Nativeバージョン **0.60** 以降を使用している場合

## ステップ2: Androidのセットアップ

### ステップ2.1: Gradle

必要な依存関係を追加して、gradleスクリプトを更新します:

{% tabs %}
{% tab title="android/build.gradle" %}

```gradle
buildscript {
    ...
    dependencies {
        ...
        classpath 'com.google.gms:google-services:4.3.13'
    }
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="android/app/build.gradle" %}

```gradle
android {
    compileSdk 33
    ...

    defaultConfig {
        ...
        targetSdk 33
    }
}

apply plugin: 'com.google.gms.google-services'
```

{% endtab %}
{% endtabs %}

### ステップ2.2: Google Services

次のファイルを追加します `google-services.json` ファイルを `android/app` ディレクトリに。

## ステップ3: iOSのセットアップ

### ステップ3.1: Podsをインストールする

次の場所で `<project_root>/ios` ディレクトリ内で以下を実行します: `pod install`

### ステップ3.2: Notification Service Extensionを追加する

画像やカスタムアクションをサポートするリッチ通知を有効にするには、Notification Service Extensionが必要です。

アプリの **xcworkspace** を使ってXCodeを開きます。次に、 `File > New > Target` を選択し、続いて `Notification Service Extension` をiOSテンプレートタブ内で選択して、 `Next`.

<figure><img src="https://1832353165-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lry9Z27iWOZyQEGAgY7%2Fuploads%2FIKOtBgXyBx78VJBxuNs9%2Fimage.png?alt=media&#x26;token=b0055514-7e75-4ce8-a0b3-bbba8f2543c6" alt=""><figcaption></figcaption></figure>

"NotificationServiceExtension"を `Product Name` に入力し、アプリ拡張の他の設定詳細も入力してから、 `Finish` をクリックしますが、 **その後のダイアログでは有効化をクリックしないでください** 。

<figure><img src="https://1832353165-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lry9Z27iWOZyQEGAgY7%2Fuploads%2F96yVKAthjykdmnXGXlem%2Fimage.png?alt=media&#x26;token=b8ed3424-44e0-4259-b97b-bb1457411164" alt=""><figcaption></figcaption></figure>

クリック `キャンセル` モーダルが閉じた後にデプロイメントターゲットを設定できるように、サービス拡張の有効化を求めるダイアログで

<img src="https://1832353165-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lry9Z27iWOZyQEGAgY7%2Fuploads%2FcGXECnSyGjGGEUBg5KDM%2Fimage.png?alt=media&#x26;token=bc91b955-baa5-490f-a32b-dd7367657f9f" alt="" data-size="original">

デプロイメントターゲットを **メインのアプリケーションターゲットと同じ**に設定してください。特別な理由がない限り、 `Deployment Target` をiOS 11に設定するべきです。これはPushSDK Frameworkおよび最新のXCodeでサポートされるiOSの最低バージョンです。

### ステップ3.3: サービス拡張にPushly依存関係を追加する

次のファイルで `<project_root>/ios/Podfile`、 **NotificationServiceExtension** をメインターゲットと同じ階層に追加します:

{% tabs %}
{% tab title="Podfile" %}

```ruby
target 'NotificationServiceExtension' do
  pod 'Pushly', '>= 1.0', '< 2.0'
end
```

{% endtab %}

{% tab title="Podfileの例" %}

````ruby
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

platform :ios, min_ios_version_supported
prepare_react_native_project!

# `react-native-flipper` を使用している場合、`NO_FLIPPER=1` が設定されると iOS ビルドは失敗します。
# `react-native-flipper` は除外される (FlipperKit,...) に依存しているためです
#
# これを修正するには、`react-native.config.js` を使って `react-native-flipper` を除外することもできます
# ```js
# module.exports = {
#   dependencies: {
#     ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
# ```
flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled

linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
  use_frameworks! :linkage => linkage.to_sym
end

target 'PushlyDevApp' do
  config = use_native_modules!

  # フラグは環境変数の値に応じて変わります。
  flags = get_default_flags()

  use_react_native!(
    :path => config[:reactNativePath],
    # Hermes は現在デフォルトで有効です。このフラグを false に設定すると無効になります。
    # 今後のバージョンの React Native は get_default_flags() に依存する可能性がありますが、
    # React Native のアップグレード作業を助けるため、ここでは明示しています。
    :hermes_enabled => flags[:hermes_enabled],
    :fabric_enabled => flags[:fabric_enabled],
    # Flipper を有効にします。
    #
    # `use_frameworks!` が有効になっている場合、Flipper は動作せず、
    # 次の行を無効にする必要があります。
    # -- アーカイブの問題により無効化
    # :flipper_configuration => flipper_config,
    # アプリケーションルートへの絶対パス。
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  target 'PushlyDevAppTests' do
    inherit! :complete
    # テスト用Pods
  end

  post_install do |installer|
    react_native_post_install(
      installer,
      # パッチを適用するために `mac_catalyst_enabled` を `true` に設定します
      # Mac Catalystビルドに必要です
      :mac_catalyst_enabled => false
    )
    __apply_Xcode_12_5_M1_post_install_workaround(installer)
  end
end

target 'NotificationServiceExtension' do
  pod 'Pushly', '>= 1.0', '< 2.0'
end
````

{% endtab %}
{% endtabs %}

Podfileにサービス拡張の依存関係を追加したので、再度インストールを実行する必要があります。 `<project_root>/ios` ディレクトリ内で、以下を実行します: `pod install`.

### ステップ3.4: サービス拡張を更新する

次に、新しく作成されたNotification Service Extensionを開き、コードを以下の内容に置き換えます:

{% tabs %}
{% tab title="Swift" %}

```swift
import Pushly

class NotificationService: PNNotificationServiceExtension {
}
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec
// ヘッダーファイルのインポートは保持してください
#import "NotificationService.h"

@import Pushly;

@interface NotificationService ()

@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    
    [PNNotificationServiceExtensionHandler didReceiveExtensionRequest:request content:self.bestAttemptContent withContentHandler:contentHandler];
}

- (void)serviceExtensionTimeWillExpire {
    // 拡張機能がシステムによって終了される直前に呼び出されます。
    // 変更された内容の「最善の試行」を配信する機会として使用してください。そうしないと、元のプッシュペイロードが使用されます。
    [PNNotificationServiceExtensionHandler didRecieveExtensionTimeWillExpire:self.bestAttemptContent withContentHandler:self.contentHandler];

    self.contentHandler(self.bestAttemptContent);
}

@end
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Xcode が Pushly を見つけられないと警告する場合は、物理デバイス、またはビルド先として「Any iOS Device」が選択されていることを確認してください。
{% endhint %}

### ステップ3.4: メインアプリケーションターゲットに機能を追加する

{% hint style="warning" %}
Push Notifications機能は、 **メインのアプリケーションターゲット**.
{% endhint %}

のみに追加する必要があります。ルートプロジェクトを選択し、その後にメインのアプリケーションターゲット > `Signing & Capabilities`

<figure><img src="https://1832353165-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lry9Z27iWOZyQEGAgY7%2Fuploads%2FPEKQiayxyjIphpjeqxB1%2Fimage.png?alt=media&#x26;token=84e69c08-d120-4a48-a193-a272b9e4f109" alt=""><figcaption></figcaption></figure>

次をクリックします `+ Capability` を選択して、 `Push Notifications`.

次をクリックします `+ Capability` を選択して、 `Background Modes`.

を追加します。 `Background Modes` 機能を追加した後、 `Remote Notifications` が有効になっていることを確認してください。

<figure><img src="https://1832353165-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lry9Z27iWOZyQEGAgY7%2Fuploads%2FMAfJ7lisFKGMxQvjpIaB%2Fimage.png?alt=media&#x26;token=7b5b4afb-0a24-4b0a-8ef6-594f763231ea" alt=""><figcaption></figcaption></figure>

次をクリックします `+ Capability` を選択して、 `App Groups`.

次をクリックします `+` 内にある `App Groups` セクションのシンボルを使って新しい名前付きコンテナーを追加します。PushSDKが情報を正しく取得できるようにするには、コンテナー名を `group.{app-bundle-id}.push`.

<figure><img src="https://1832353165-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lry9Z27iWOZyQEGAgY7%2Fuploads%2FOR42sYi1kH4o1227pQpY%2Fimage.png?alt=media&#x26;token=c504305e-c703-4e7e-afff-834d9de68aac" alt=""><figcaption></figcaption></figure>

にする必要があります。メインのアプリケーションターゲットで、新しく作成したApp Groupの横のチェックボックスをオンにします。

### ステップ3.5: Notification Service Extensionに機能を追加する

次に、 **NotificationServiceExtension** ターゲットで `Signing & Capabilities` タブの下に表示されます。

次をクリックします `+ Capability` を選択して、 `App Groups`.

最後に、新しく作成したApp Groupの横のチェックボックスをオンにします。

## ステップ4: SDKの初期化

次のファイルで `index.tsx` または `app.tsx` ファイルで、以下のサンプル実装コードを使ってPushSDKを初期化します。

置き換えてください `REPLACE_WITH_SDK_KEY` を `setConfiguration` メソッド内で、プラットフォーム設定ページのSDK Keyに置き換えます。

{% tabs %}
{% tab title="index.tsx" %}

```tsx
...
import { PushSDK, LogLevel } from '@pushly/push-sdk-react-native';

export const App = () => {
    ...

    // useEffectブロック内でPushSDKを初期化することを推奨します
    // アプリケーションが次を呼び出そうとするのを防ぐため
    // 再レンダーのたびにPushSDK.setConfiguration()を実行しないようにするためです
    React.useEffect(() => {
        PushSDK.setLogLevel(LogLevel.INFO);
        PushSDK.setConfiguration({ appKey: 'REPLACE_WITH_SDK_KEY' });

        PushSDK.showNativeNotificationPermissionPrompt().then(({ granted }) => {
            console.log(`Permissions granted: ${granted}`);
        });
    }, []);
    
    // 残りのアプリ
    ...
};
```

{% endtab %}
{% endtabs %}

Androidデバイスまたはエミュレーター（エミュレーターに `Google Play Store Services` がインストールされていることを確認してください）、またはiOS向けにビルドする場合はiOSデバイスでアプリを実行し、正しくビルドされることを確認してください。

前のステップで追加したコードにより、アプリ起動時にプッシュ許可ダイアログが表示されます。これは [SDKメソッド](https://documentation.pushly.com/pushly-ja/integration/implementation-steps/react-native/broken-reference) を使ってダイアログを表示するタイミングを制御することでカスタマイズできます。

ダイアログを承認した後、プラットフォームにログインして `Notifications > Create Notification` に移動し、適切な **ネイティブ: iOS** または **ネイティブ: Android** チャネル

## 次のステップ

SDKが正しく動作していることを確認したら、次のような追加のオプション機能を続けて追加できます:

* [<mark style="color:青色;">通知の開封 / アプリリンク / ディープリンクの処理</mark>](https://documentation.pushly.com/pushly-ja/integration/implementation-steps/react-native/broken-reference)
* [<mark style="color:青色;">購読者のプロフィールに属性を付与する</mark>](https://documentation.pushly.com/pushly-ja/integration/implementation-steps/react-native/broken-reference)
* [<mark style="color:青色;">購読者がどのコンテンツとやり取りしたかに関する情報を送信する</mark>](https://documentation.pushly.com/pushly-ja/integration/implementation-steps/react-native/broken-reference)
