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

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

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

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

Q&A

解決済

1回答

369閲覧

swift アラーム機能について

ives

総合スコア19

Swift

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

0グッド

0クリップ

投稿2018/08/13 13:09

swiftでUISwitchを押すと指定の時間にアラームが鳴るアプリを作っています。指定時間にちゃんと鳴るのですが
UISwitchをオフにした時にストップするようにしたいです。下記のコードだと40秒後くらいにオフにしなくても自動でアラームがストップしてしまいます。自分でもelse以下にself.audioPlayer.stop()と書いてみたのですがうまくいきませんどなたか知恵をお借りできたら幸いです。よろしくお願い申し上げます。

swift

1import UIKit 2import AVFoundation 3 4class SecondViewController: UIViewController,AVAudioPlayerDelegate, UITableViewDelegate, UITableViewDataSource{ 5 6 //追加② 7 let TODO = ["15分後", "30分後", "45分後"] 8 9 var timer = Timer() 10 var startTime:Double = 0.0 11 var audioPlayer: AVAudioPlayer! 12 @IBOutlet weak var tableView: UITableView! 13 @IBAction func `switch`(_ sender: UISwitch) 14 { 15 if (sender.isOn) { 16 //switchがonならtimer起動 17 timer = Timer.scheduledTimer(withTimeInterval: 1 * 2, repeats: true, block: { timer in 18 //15分後にアラーム鳴る 19 self.audioPlayer.play(atTime:self.audioPlayer.deviceCurrentTime + 1 * 2) 20 }) 21 } else { 22 //offならtimer停止 23 timer.invalidate() 24 print("stopped") 25 self.audioPlayer.stop() 26 } 27 } 28 @IBAction func switch2(_ sender: UISwitch) 29 { 30 if (sender.isOn) { 31 //switchがonならtimer起動 32 timer = Timer.scheduledTimer(withTimeInterval: 60 * 30, repeats: true, block: { timer in 33 //15分後にアラーム鳴る 34 self.audioPlayer.play(atTime:self.audioPlayer.deviceCurrentTime + 60 * 30) 35 }) 36 } else { 37 //offならtimer停止 38 timer.invalidate() 39 print("stopped") 40 self.audioPlayer.stop() 41 } 42 } 43 @IBAction func switch3(_ sender: UISwitch) 44 { 45 if (sender.isOn) { 46 //switchがonならtimer起動 47 timer = Timer.scheduledTimer(withTimeInterval: 60 * 45, repeats: true, block: { timer in 48 //15分後にアラーム鳴る 49 self.audioPlayer.play(atTime:self.audioPlayer.deviceCurrentTime + 60 * 45) 50 }) 51 } else { 52 //offならtimer停止 53 timer.invalidate() 54 print("stopped") 55 self.audioPlayer.stop() 56 } 57 } 58 59 60 override func viewDidLoad() { 61 super.viewDidLoad() 62 63 if let url=Bundle.main.url(forResource:"1",withExtension:".mp3" ){ 64 //上記の***の箇所でファイル名と拡張子を指定し変数urlに代入します。 65 do { 66 audioPlayer=try AVAudioPlayer(contentsOf:url) 67 audioPlayer?.play(atTime:1 * 10) 68 //処理が成功したらaudioPlayerに指定したurlを代入し、playメソッドを呼び出します。 69 }catch{ 70 audioPlayer=nil 71 } 72 }else{ 73 fatalError("Url is nil") 74 //URLが空の場合など処理が走らなかった場合はエラー文を表示します。 75 } 76 audioPlayer.delegate = (self as AVAudioPlayerDelegate) 77 audioPlayer.prepareToPlay() 78 79 } 80 81 override func didReceiveMemoryWarning() { 82 super.didReceiveMemoryWarning() 83 // Dispose of any resources that can be recreated. 84 } 85 //追加③ セルの個数を指定するデリゲートメソッド(必須) 86 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 87 return TODO.count 88 } 89 90 //追加④ セルに値を設定するデータソースメソッド(必須) 91 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 92 // セルを取得する 93 let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 94 // セルに表示する値を設定する 95 cell.textLabel!.text = TODO[indexPath.row] 96 return cell 97 } 98}

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

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

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

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

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

xAxis

2018/08/14 03:02

基本的な所から確認なのですがそのmp3ファイルの曲の長さは40秒程度、ということはないですか?
ives

2018/08/14 05:34

map3の長さは15秒でコード内でreapeats: trueにしてるので3回ほど再生(再再生される間に2秒程のタイムラグがありそれも出来れば直したいです)されたのち、止まってしまいます.
xAxis

2018/08/14 06:04 編集

mp3ファイルの長さの件了解しました。 そのタイムラグがあるのって`switch`関数ではないですか?
xAxis

2018/08/14 06:06

後viewDidLoad()内にあるaudioPlayer.delegate = (self as AVAudioPlayerDelegate) この部分、audioPlayer.delegate = selfで良さそうです。
xAxis

2018/08/14 06:08

例にもれず最小構成で上記のコードと同じようなものを作ったのですが普通にリピートしてくれてますね。
xAxis

2018/08/14 06:15

とりあえず`switch`関数内のself.audio.player(atTime:)の一行下にprint(self.audioPlayer.isPlaying)を書いてください。そしてその結果を教えてください。
ives

2018/08/14 08:47

スイッチを押し12秒ほどで停止→2秒後にリピート開始 この動作を5回程確認しました ありがとうございます永遠にリピートされそうです。欲を言うとリピートする間の2秒程のタイムラグを無くすことはできるでしょうか?
xAxis

2018/08/14 09:07

self.audioPlayer.play(atTime:self.audioPlayer.deviceCurrentTime + 1 * 2) 多分これがタイムラグの原因じゃないかな。self.audioPlayer.play()に書き換えて試してみてください。
ives

2018/08/14 12:59

スムーズになりましたがdebugで見た時の9回目の true表示の時に鳴りません。でも以前よりだいぶスムーズになりました(特にUISwitchをオンにした瞬間のタイムラグがなくなりました)
xAxis

2018/08/14 14:51

リファレンス流し読みなのですがタイムラグは.play(atTime:)で任意の時間を設定する時に使うようですね。今日はもう遅いので明日またデバッグにお付き合いします。
guest

回答1

0

ベストアンサー

質問とその後の追記をまとめると

  1. 再生された音楽のリピートをしたい
  2. 再生終了から次の再生までのタイムラグをなんとかしたい

の二点になるかと思います。

一つ目の回答ですが、Timerのrepeatをtrueにしてリピート機能としていますが結局どこで再生が止まってしまうのかは話を深掘りしてみてもわからずじまいでした。なのでTimerのrepeatをtrueにするのではなくfalseにして、AVAudioPlayerのリピート機能を有効にしたらいいのではないかと思います。

コードは

swift

1myPlayer.numberOfLoops = -1

ですね。numberOfLoopsにマウスカーソルを合わせてcontrol + commandでJump to Definitionするとどういう風な使い方が出来るかがコメントアウトされた部分に書いてあります。その中の一文をザックリ言うと「負の数を入れると止めるまで無限ループするよ」ってな感じです。なので上記のコードで大丈夫でしょう。

二つ目の回答ですが、タイムラグを無くしたい、と言うことは即座に再生してしまえばいいでしょう。

swift

1self.myPlayer.play(atTime: self.myPlayer.deviceCurrentTime + 10)

とすると10秒待って再生されてしまうので

swift

1self.myPlayer.play()

とすれば即座に再生できます。

投稿2018/08/15 03:40

xAxis

総合スコア1349

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

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

ives

2018/08/15 09:49

ご丁寧にありがとうございます。
ives

2018/08/16 04:02

あなたのお陰で本当に助かりました。(0から100まで教えていただいたような形になり申し訳なさも感じています笑)プログラミングは今年の4月から始めた初心者ですがこれから精進していこうと思います。 この度はありがとうございました。また困ったことがありましたらどうぞよろしくお願いします。
xAxis

2018/08/16 04:14

どうやら解決したようで何よりです。 上記の回答で書いてある"Jump to Definition"ですが困った時は一旦これをしてクラスだったりメソッドだったりを確認してみる習慣をつけると良いですよ。英語で書いてありますが分かりやすい英語で書かれてありますし、分からなければMac純正アプリの辞書で調べると大抵の単語は出てきます。 始めたてだと分からない事も多々あるかもしれませんが、私の答えられる範囲でしたらまたどうぞ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問