質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

バックグラウンド処理

バックグラウンド処理とは、マルチタスク環境において、ユーザーに対して前面に表示させている処理の裏側で実行させる処理のことを呼びます。バックグラウンド処理を行う事によって、ユーザーが他の作業に携わることが可能となります。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

解決済

1回答

2471閲覧

Swift タイマーの停止処理が上手く機能しません

umasan4

総合スコア2

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

バックグラウンド処理

バックグラウンド処理とは、マルチタスク環境において、ユーザーに対して前面に表示させている処理の裏側で実行させる処理のことを呼びます。バックグラウンド処理を行う事によって、ユーザーが他の作業に携わることが可能となります。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

0クリップ

投稿2020/06/12 09:03

前提・実現したいこと

Swiftでバックグラウンドでも動作するタイマー

発生している問題・エラーメッセージ

数時間調べても分からなかったので、初めて質問させていただきます
稚拙な文で至らない点もあるかと思いますが、よろしくお願いします

Swiftでアプリを閉じた状態、バックグラウンドでも動作する作業用タイマーを作成しています
(25分をカウントし → 停止・ローカル通知 → 5分のカウント → 停止・ローカル通知 → 先頭に戻る)のようなタイマーです

なんとか形にはなってきたのですが、タイマーの停止の処理が上手く機能しません

アプリの画面展開中はキチンと停止してくれるのですが、アプリを閉じた状態では
タイマーが停止せず、00:-1...00:-2 のように 00:00を下回ってカウントダウンし続けてしまいます

アプリを閉じた状態でもタイマーを停止させるには、どのような処理が必要になりますか?

エラーメッセージ等は発生していません

該当のソースコード

//---ViewDidLoad--- override func viewDidLoad() { super.viewDidLoad() } //---スタートボタン--- @IBAction func startButton(_ sender: Any) { //スタート押された時間の保持 startTime = Date() //タイマーの起動 TimerStart() } //---ストップボタン--- @IBAction func stopButton(_ sender: Any) { //ストップ押された時間の保持 stopTime = Int(Date().timeIntervalSince(startTime)) + stopTime //タイマーを破棄 timer.invalidate() } //---リセットボタン--- @IBAction func resetButton(_ sender: Any) { //タイマーを破棄 timer.invalidate() //ストップ時に保持する時間をリセット stopTime = 0 } //---タイマー--- func TimerStart() { timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(update), userInfo: nil, repeats: true) } //---タイマーに呼び出される--- @objc func update() { //スタートからの経過時間を代入 countTime = Int(Date().timeIntervalSince(startTime)) //経過時間からsetTime(秒)を引き、再代入する setTime = 1500 countTime = (setTime - countTime) - stopTime //経過時間のフォーマット let min = countTime / 60 % 60 let sec = countTime % 60 let timeLabel = String(format: "%02d:%02d", min, sec) //ラベルに反映 timeCountLabel.text = timeLabel //停止処理をセット StopTimer() } //---タイマーを停止--- func StopTimer() { //カウントが00:00になった場合 if countTime == 0 { //タイマーを破棄 timer.invalidate() //ストップ時に保持する時間をリセット stopTime = 0 //タイマーを切りかえ switch setTime { case 1500: setTime = 300 timeCountLabel.text = "05:00" case 300: setTime = 1500 timeCountLabel.text = "25:00" default: print("error") } //ローカル通知を行う localCoal() } } //---ローカル通知--- @objc func localCoal() { //通知する内容の指定 let content = UNMutableNotificationContent() content.title = "タイマーが終了しました" content.body = "" content.sound = UNNotificationSound.default //以上の内容のリクエストを作成 let request = UNNotificationRequest(identifier: "Timer", content: content, trigger: nil) //上で作成したリクエストを加える UNUserNotificationCenter.current().add(request) //通知のリセット UNUserNotificationCenter.current().removeAllPendingNotificationRequests() }

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

iOS: 13.5
Xcode: 11.5

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

なんとか形にはなってきたのですが、タイマーの停止の処理が上手く機能しません

アプリの画面展開中はキチンと停止してくれるのですが、アプリを閉じた状態では
タイマーが停止せず、00:-1...00:-2 のように 00:00を下回ってカウントダウンし続けてしまいます

アプリを閉じた状態でもタイマーを停止させるには、どのような処理が必要になりますか?

実際に試していないので推測ですが、アプリを起動後、バックグラウンドで走らせたあと30分くらい経過してフォアグランドに戻した場合、ラベルの表示がマイナスになっている、ということでしょうか。

既にお気づきかもしれませんが、アプリがバックグラウンドに入った場合にはタイマも停止してしまいます。したがって、タイマ割り込みも発生せず、次回起動した時点で指定したコールバック関数が呼び出されます。なので、表示がマイナスになるのではないでしょうか。

いずれにしても、継続的な処理はできませんので、別の方法を考える必要がありそうです。

指定した時刻に通知を出すのであれば、たとえば UserNotifications を使う方法がありそうです。

下記の記事の「タイマー通知」の節(と初期設定)が参考になりますし、試しに実装してみたらほぼそのまま使えたので、参考になればと思います。

投稿2020/06/15 09:48

TsukubaDepot

総合スコア5086

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

umasan4

2020/06/17 00:46

回答、ありがとうございます そのように試してみます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問