LoginSignup
3
8

More than 3 years have passed since last update.

[Swift勉強会] カウントアップアプリを改造して,通知をn秒後に通知を出してみる (n>0)

Last updated at Posted at 2020-08-09
1 / 14

前回までの内容

カウントアップアプリの作成まではこちら
作:https://qiita.com/appgrape


今回のゴール

  • 通知の基本文法がわかる
  • UISwitchの基本的な使い方がわかる
  • Switchをオンにした時に通知される
    • アプリ内で通知が来る
  • カウントアップで指定した数秒後に通知が出せる

完成アプリ

完成品がこちらになります
ダウンロード (1).gif


アプリの実装


UISwitchの実装

UIの実装

前回までと同様にMain.StoryboardにUIパーツを配置する(今回はUISwitch)
スクリーンショット 2020-08-07 17.18.53.png

次に設置したUISwitchをクリックし,画面右のAttributes Inspectorをクリックする
するとAttributes Inspectorの一番上に,Switchの初期状態をセットするStateがあるのでオンからオフに変える
スクリーンショット 2020-08-07 17.26.54.png

そしてAssistant Editorを起動してViewController.SwiftにUISwitchを紐付ける.
スクリーンショット 2020-08-07 17.25.05.png

名前はonSwitchDidChangedとした.
画像のようにTypeUISwitchとする

コードの実装

次にコードを書く

ViewController.swift
@IBAction func onSwitchDidChanged(_ sender: UISwitch) {
    //switchを押すとこの中身が動く
    if sender.isOn {
        //switchをオンにするとswitch tapped!が出力される
        print("switch tapped!")
    }
}

実際に動かしてみる
2020-08-08 at 21.28.38.png

image.png


通知の実装

通知の実装ではStoryboardをいじることはない
(全部コードで完結する)


通知の許可を取る

通知機能のあるiOSアプリには,まず起動時に通知の許可を取る必要がある
次のコードを追加する

AppDelegate.swift
import UIKit
import UserNotifications //<-通知関係を使用する時に必要
//~~(中略)~~
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
//ここから
        // 通知許可の取得
        UNUserNotificationCenter.current().requestAuthorization(
        options: [.alert, .sound, .badge]){ //許可を取るもの:
                                            // .alert -> 通知のポップアップを許可するか,
                                            // .sound -> 通知音を許可するか,
                                            // .badge -> 通知時にアプリアイコンに通知数の表示を許可するか
            (granted, _) in
            if granted{
                UNUserNotificationCenter.current().delegate = self
            }
        }
//ここまで追加
    return true
}
//~~(中略)~~
//コード末尾に追加
extension AppDelegate: UNUserNotificationCenterDelegate{
}

2020-08-08 at 21.28.38.png

このコードを書くと,アプリ起動時に1回だけ通知許可のポップアップが出てくる.
ただこれは許可を取っただけなので,通知自体は実装されていない.


通知のテストをしてみる

前のページで通知の許可を取ったため,次は実際にswitchを押して通知させてみる.
次のコードを追加する

ViewController.swift
import UIKit
import UserNotifications //<-通知関係を使用する時に必要
//~~(中略)~~
@IBAction func countDounButton(_ sender: Any) {
}
//ここから
@IBAction func onSwitchDidChanged(_ sender: UISwitch) {
    //switchを押すとこの中身が動く
    if sender.isOn {
        //switchをオンにすると通知が来る
        showNotification()
    }
}

func showNotification() {
    let content = UNMutableNotificationContent() //<-通知のコンテンツを入れる定数contentを初期化
    content.title = "countUpAppForBeginners" //<-通知のタイトル
    content.body = "switchをオンにしました。" //<-通知の詳細文
    content.sound = UNNotificationSound.default //<-通知の音はデフォルトのやつ

    let request = UNNotificationRequest(identifier: "changedSwitch", content: content, trigger: nil)
    //通知のリクエストを任意の名前(identifier),内容(content),発動条件(trigger)をつけて定数に保存する

    UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
    //通知センターに通知のリクエストを追加する
}

実際に試してみる
ダウンロード (2).gif

動かない


実はlet requestのtriggerがnilだと,即座に通知が呼ばれる
しかし通知するアプリが起動中は通知はこない(設定でアプリ内でも通知可能)
つまり通知は機能してるが見えない状態
なので3秒後に通知に設定して確認する


3秒後に通知してみる

ViewController.swiftに次のコードを追加,編集する

ViewController.swift
func showNotification() {
    let content = UNMutableNotificationContent()
    //content:通知に表示するものを編集する
    content.title = "countUpAppForBeginners"
    content.body = "switchをオンにしました。"
    content.sound = UNNotificationSound.default

    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: TimeInterval(3), repeats: false) //3秒後に通知させる

    let request = UNNotificationRequest(identifier: "changedSwitch", content: content, trigger: trigger)//<-ここをnilからtriggerに変える
        UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
    }

試してみる
ダウンロード (1).gif

注意点としてtrriger=0だとエラーが出る


n秒後に通知してみる(n > 0)

最後にカウントアップで設定した値秒後に通知を実装する
前回のところでtrriger=0だとエラーが出ると述べた.
試していないがおそらく負の値でもエラーが出るのでカウントアップを1未満にならないように設定する.

ViewControlelr.swift
//~~(前略)~~
//数字を格納する場所
var count = 1 //<- 初期値を0から1に
//~~(中略)~~
@IBAction func countDounButton(_ sender: Any) {
    //-ボタンを押すとラベルの文字をカウントダウン
    if count > 1 {
        //countが1未満にならないようにカウントダウンさせる
        count = count - 1
        countLabel.text = String(count)
    }
    //カウントにあわせて文字の色を変更
    changeTextColor()
}
//~~(中略)~~
//n秒後に通知させる(n>0)
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: TimeInterval(count), repeats: false) //countをTimerIntervalに変換する
//~~(後略)~~

試してみる
ダウンロード.gif

これで完成


おまけ:アプリ内で通知させてみる

AppDelegateに次のコードを追加するだけ

AppDelegate.swift
extension AppDelegate: UNUserNotificationCenterDelegate{
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        // アプリ起動中でも通知させる
        completionHandler([.alert, .sound])
    }
}

最後に

今回はUISwitchの使い方と通知の実装をざっくりと説明しました.
質問,訂正があればコメント欄かtwitterにお願いします

3
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
8