Swiftでアプリからアプリにプッシュ通知を送って見よう！

# はじめに
* この記事は、[__ニフクラ mobile backend__ ](http://mb.cloud.nifty.com/about.htm)（以下 __mBaaS__ ）を使用してプッシュ通知を配信する際、__Swiftを使って__「アプリからアプリへプッシュ通知を配信するため」のドキュメントです。
* 基本的には下記のObjective-CのドキュメントをSwift化しています
 * [プッシュ通知をアプリから送信する（プッシュ通知 (iOS) : 基本的な使い方）](http://mb.cloud.nifty.com/doc/current/push/basic_usage_ios.html#%E3%83%97%E3%83%83%E3%82%B7%E3%83%A5%E9%80%9A%E7%9F%A5%E3%82%92%E3%82%A2%E3%83%97%E3%83%AA%E3%81%8B%E3%82%89%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B "プッシュ通知 (iOS) : 基本的な使い方 | ニフクラ mobile backend ")

# 事前準備
## 動作環境
以下の環境で動作確認をしています。準ずる環境をご用意ください。

* Mac 10.12.3
* Xcode 8.2.1
* プッシュ通知受信用のiPhone6 10.0.1

## 環境準備
1. mBaaSのアカウント登録と新規アプリの作成をしてください（[参考](https://github.com/natsumo/NCMB_SwiftQuickStart#%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E6%96%B0%E8%A6%8F%E4%BD%9C%E6%88%90)）
1. 本ドキュメントプッシュ通知配信テスト用にXcode でプロジェクトを作成し、mBaaS iOS SDK の設定と初期化をしてください(★注1)
1. 上記とは別で、プッシュ通知__受信用__のiPhoneに、プッシュ通知受信の設定をしたアプリをビルドしておいてください(★注2) 

> (★注1)
> SDKの設定と初期化については以下を参照してください▼
> [__クイックスタート__](https://github.com/natsumo/NCMB_SwiftQuickStart)
> このプロジェクトは本ドキュメントの動作確認に必要です。
> ※ここで設定するmBaaS のアプリは必ず ★注2 と同じものを使用してください。
> (★注2) 
> プッシュ通知受信の設定をしたアプリをビルド方法は以下を参照してください▼
> [__【iOS Swift3】プッシュ通知を送ろう！__](https://github.com/NIFTYCloud-mbaas/Swift3PushApp)
> ※ここで設定するmBaaS のアプリは必ず ★注1 と同じものを使用してください。


# プッシュ通知を送る[基本形]
下記コードをコピーして、プッシュ通知配信テスト用に用意したXcode プロジェクト（環境準備の2.）の、AppDelegate に記入しSimulator で実行すると簡単に動作確認が可能です。（環境準備3.に配信されることを確認できます）

```swift:Swift3
let push = NCMBPush()
let data_iOS = ["contentAvailable" : false, "badgeIncrementFlag" : true, "sound" : "default"] as [String : Any]
push.setData(data_iOS)
push.setPushToIOS(true)
push.setTitle("-----Title-----")
push.setMessage("-----Message-----")
push.setImmediateDeliveryFlag(true) // 即時配信
push.sendInBackground { (error) in
    if error != nil {
        // プッシュ通知登録に失敗した場合の処理
        print("NG:\(error)")
    } else {
        // プッシュ通知登録に成功した場合の処理
        print("OK")
    }
}
```

# 最小限のプッシュ通知
プッシュ通知を配信するために、最小限必要なコードは以下の２点です。
Titleやmessageが無くてもプッシュ通知は配信が可能です。（その場合は、サイレントプッシュとなります）

```Swift:Swift3
// プッシュ通知を生成
let push = NCMBPush()
/* 配信OS */
push.setPushToIOS(true)
/* 配信タイミング */
push.setImmediateDeliveryFlag(true) // 即時配信
/* ↓その他設定がある場合はここに追記↓ */

/* ↑その他設定がある場合はここに追記↑ */
// 配信処理
push.sendInBackground { (error) in
    if error != nil {
        // プッシュ通知登録に失敗した場合の処理
    } else {
        // プッシュ通知登録に成功した場合の処理
    }
}
```

以降に案内しているプッシュ通知の追加詳細設定をする場合は、

```swift
/* ↓その他設定がある場合はここに追記↓ */

/* ↑その他設定がある場合はここに追記↑ */
```
ここに追記することで、設定できます◎

# プッシュ通知の設定項目

ここからはコントロールパネル画面と照らし合わせて表示しています◎

## タイトルとメッセージ
Titleやmessageは以下用に設定できます。
`-----Title-----`,`-----Message-----`の部分を自由に変更して試してみましょう。

```swift:Swift3
/* タイトル */
push.setTitle("-----Title-----")
/* メッセージ */
push.setMessage("-----Message-----")
```

* コンパネから配信する場合

![029.png](https://qiita-image-store.s3.amazonaws.com/0/112032/7b1186eb-270f-9fb5-5445-d4a400b2604d.png)


## 時間指定配信設定
即時配信（`setImmediateDeliveryFlag`）または、指定配信（`setDeliveryTime`）いずれかを必ず指定する必要があります。

```swift:Swift3
/* 即時配信 */
push.setImmediateDeliveryFlag(true)
```

* コンパネから配信する場合

![030.png](https://qiita-image-store.s3.amazonaws.com/0/112032/f0d2b481-6506-99d9-f08c-0438b46403b2.png)


```swift:Swift3
/* 配信日時指定 */
// 例) 日時指定 ※今より未来を設定
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm:ss"
let deliveryTime = formatter.date(from: "2017/03/31 15:30:00")
push.setDeliveryTime(deliveryTime)
```

* コンパネから配信する場合の設定

![031.png](https://qiita-image-store.s3.amazonaws.com/0/112032/2379a225-4bdc-ee76-2c81-4f7dbd815e75.png)


```swift:Swift3
// 例) 今から3分後
let deliveryTime = Date(timeIntervalSinceNow: 3*60)
push.setDeliveryTime(deliveryTime)

```

* 上記はコンパネからは設定できません


## 配信期限設定

```swift:Swift3
/* プッシュ通知の配信日時から設定したインターバル後を有効期限に設定 */
// 1日後
push.expire(afterTimeInterval: "1day")
// 1時間後
// push.expire(afterTimeInterval: "1hour")
```

* コンパネから配信する場合の設定

![038.png](https://qiita-image-store.s3.amazonaws.com/0/112032/10e04ae6-e27f-49d3-b497-e7795fbb38ec.png)
![040.png](https://qiita-image-store.s3.amazonaws.com/0/112032/836dc74c-1ead-50b7-6da8-868c09f9f2d7.png)


```swift:Swift3
/* プッシュ通知の有効期限を設定 */
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm:ss"
let expirationDate = formatter.date(from: "2017/03/31 15:30:00")
push.expire(at: expirationDate)
```

* コンパネから配信する場合の設定

![041.PNG](https://qiita-image-store.s3.amazonaws.com/0/112032/7ff7d813-78cc-8150-047e-df67d8be4665.png)

ちなみに、デフォルトでは10日間となっています。コンパネは以下の状態です。

![039.png](https://qiita-image-store.s3.amazonaws.com/0/112032/376841a4-45f1-d5e2-8b53-0c995baed068.png)


## リッチプッシュ設定

```swift:Swift3
push.setRichUrl("http://mb.cloud.nifty.com/")
```

* コンパネから配信する場合の設定

![032.png](https://qiita-image-store.s3.amazonaws.com/0/112032/0e3dc52a-77b9-93d4-acc2-1c54fb5c913a.png)

__注意__：リッチプッシュは受信する端末側にも別途実装が必要です

> 参考：受信アプリ側の設定
> https://github.com/natsumo/SwiftRichPushApp#リッチプッシュの取得

## JSON設定（ペイロード）

```swift:Swift3
push.setUserSettingValue(["key1" : "value1", "key2" : "value2"]);
```

* コンパネから配信する場合の設定

![033.PNG](https://qiita-image-store.s3.amazonaws.com/0/112032/25446e98-f77c-5f90-e596-b439cd8070e1.png)

__注意__：JSONは受信する端末側にも別途実装が必要です

> 参考：受信アプリ側でのJSON取得方法
> https://github.com/natsumo/SwiftPayloadApp_iOS10#ペイロード取得

## 絞り込み配信設定

```swift:Swift3
/* installation を指定して絞り込み */
let query = NCMBInstallation.query()
query?.whereKey("objectId", equalTo: "***objectId***")
push.setSearchCondition(query)
```

* コンパネから配信する場合の設定

![036.PNG](https://qiita-image-store.s3.amazonaws.com/0/112032/94aedbfe-ad21-8c22-0c5f-5c458125c426.png)


```swift:Swift3
/* アプリのバージョンが2.0より古い端末に絞り込み */
let query = NCMBInstallation.query()
// query?.whereKey("appVersion", lessThan: "2.0")
push.setSearchCondition(query)
```

* コンパネから配信する場合の設定

![037.PNG](https://qiita-image-store.s3.amazonaws.com/0/112032/82b765c1-3c28-972a-9fd5-8f790937a1de.png)

ちなみに、デフォルトでは全配信となります。コンパネは以下の状態です。

![035.PNG](https://qiita-image-store.s3.amazonaws.com/0/112032/952f35cb-df05-f7ac-39d6-0c8513446ac7.png)




## パーミッション設定

```swift:Swift3
/* 準備中 */
```

# [おまけ] Android端末に配信する場合

Android端末へ配信する場合は、以下のコードで配信登録が可能です。

```swift:Swift3
let push = NCMBPush()
let data_Android = ["action" : "ReceiveActivity", "title" : "testPush"] as [String : Any]
push.setData(data_Android)
push.setDialog(true)
push.setPushToAndroid(true)
push.setTitle("-----Title-----")
push.setMessage("-----Message-----")
push.setImmediateDeliveryFlag(true) // 即時配信
push.sendInBackground { (error) in
    if error != nil {
        // プッシュ通知登録に失敗した場合の処理
        print("NG:\(error)")
    } else {
        // プッシュ通知登録に成功した場合の処理
        print("OK")
    }
}
```

> 参考：Android端末でのプッシュ通知受信設定は以下をご参考ください
> [【Android】プッシュ通知機能！](https://github.com/NIFTYCloud-mbaas/android_push_demo)
> ※APIキーは必ず同じものを使用しください

# 参考

* iOS SDK リファレンス（NCMBPush）
 * http://mb.cloud.nifty.com/assets/sdk_doc/ios/doc/html/Classes/NCMBPush.html
* プッシュ通知登録API
 * http://mb.cloud.nifty.com/doc/current/rest/push/pushRegistration.html