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

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

新規登録して質問してみよう
ただいま回答率
85.49%
関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Xcode

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

Swift

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

Q&A

解決済

1回答

1350閲覧

シングルトンやユーザーディフォルトからのデータを関数にまとめる方法を教えてください

sssaqj

総合スコア7

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Xcode

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

Swift

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

0グッド

0クリップ

投稿2020/04/15 19:48

アプリ画面

シングルトンやユーザーディフォルトからのデータを関数にまとたい

タイマーマネージャーのシングルトンを持ったピッカービューで時間を設定するタイマーを作っています。時間を扱うために合計時間を時間、分、秒へと分解する箇所が複数あり冗長だなと思うので関数に処理をまとめたいと思います。
しかし、元の合計時間がシングルトンから引っぱってきたものと、ユーザーディフォルトからのものとが混在してうまくまとめる方法が考えられないのです。
どなたかご教示いただければ幸いです。

該当のソースコード

Swift

1class TimerManager { 2 static let shared = TimerManager() 3 var timer : Timer? 4 var setCount: Double? = nil 5 var count = 0.0 6 var remainCount: Double? = nil { 7 didSet { 8 onCountDidSet?(remainCount!) 9 } 10 } 11 var onCountDidSet: ((_ count: Double) -> Void)? = nil 12 13 func startCount() { 14 if timer == nil { 15 timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { 16 timer in self.timerCount(timer)} 17 } 18 } 19 func stopCount() { 20 count = 0.0 21 pauseCount() 22 } 23 func pauseCount() { 24 if let nowTimer = timer { 25 if nowTimer.isValid == true { 26 nowTimer.invalidate() 27 } 28 self.timer = nil 29 } 30 } 31 func timerCount(_ timer: Timer) { 32 if let _ = UserDefaults.standard.object(forKey: "timer_value") as? Int { 33 setCount = (UserDefaults.standard.object(forKey: "timer_value")) as? Double 34 } 35 count += 1.0 36 if let set_count = setCount { 37 remainCount = set_count - count 38 } 39 if let remain_count = remainCount { 40 if remain_count <= 0.0 { 41 count = 0.0 42 timer.invalidate() 43 print("finish") 44 } 45 } 46 } 47 var timer_status = "stop" 48 func timerStatus() { 49 if timer == nil { 50 timer_status = "stop" 51 } 52 else { 53 timer_status = "counting" 54 } 55 } 56} 57--------------------------------------------- 58class ViewController: UIViewController { 59 60 var alertController = UIAlertController() 61 @IBOutlet weak var countDownLabel: UILabel! 62 @IBAction func settingButtonAction(_ sender: Any) { 63 } 64 @IBAction func startButtonAction(_ sender: Any) { 65 TimerManager.shared.startCount() 66 } 67 @IBAction func stopButtonAction(_ sender: Any) { 68 TimerManager.shared.pauseCount() 69 } 70 var remain_counts = 0 71 72 func remainCount() { 73 TimerManager.shared.onCountDidSet = { 74 remainCount in self.remain_counts = Int(remainCount) 75 let hour = self.remain_counts / 3600 76 let mHour = self.remain_counts % 3600 77 let minites = mHour / 60 78 let sMinites = mHour % 60 79 let second = sMinites % 60 80 print(hour,minites, second) 81 self.countDownLabel.text = "残り (hour) 時間 (minites) 分 (second) 秒" 82 if remainCount <= 0.0 { 83 self.returnData() 84 } 85 } 86 } 87 88 func returnData(){ 89 self.alert(title: "終了", 90 message: "終了です") 91 } 92 func alert(title: String, message: String) { 93 alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) 94 alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) 95 present(alertController, animated: true) 96 } 97 98 override func viewDidLoad() { 99 super.viewDidLoad() 100 101 // 画面遷移時のタイマー作動/停止で表示を変える 102 TimerManager.shared.timerStatus() 103 let nowCount = TimerManager.shared.timer_status 104 let presenceCount = TimerManager.shared.count 105 106 // タイマー停止状態を判断 107 if nowCount == "stop" { 108 // カウンターもリセットされている(一時停止ではない) 109 if presenceCount == 0.0 { 110 if let time_value = UserDefaults.standard.object(forKey: "timer_value") as? Int { 111 print(time_value) 112 let hour = time_value / 3600 113 let mHour = time_value % 3600 114 let minites = mHour / 60 115 let sMinites = mHour % 60 116 let second = sMinites % 60 117 print(hour,minites, second) 118 countDownLabel.text = "残り (hour) 時間 (minites) 分 (second) 秒" 119 } else { 120 // 一時停止なら残り時間を表示 121 remainCount() 122 } 123 } 124 // タイマーが動いていれば残り時間を表示 125 } else { 126 remainCount() 127 } 128 } 129 130 override func viewWillAppear(_ animated: Bool) { 131 super.viewWillAppear(animated) 132 remainCount() 133 } 134 override func viewWillDisappear(_ animated: Bool) { 135 super.viewWillDisappear(animated) 136 TimerManager.shared.onCountDidSet = nil 137 } 138 139 override func viewDidAppear(_ animated: Bool) { 140 TimerManager.shared.timerStatus() 141 let nowCount = TimerManager.shared.timer_status 142 let presenceCount = TimerManager.shared.count 143 144 if nowCount == "stop" { 145 if presenceCount == 0.0 { 146 if let time_value = UserDefaults.standard.object(forKey: "timer_value") as? Int { 147 print(time_value) 148 let hour = time_value / 3600 149 let mHour = time_value % 3600 150 let minites = mHour / 60 151 let sMinites = mHour % 60 152 let second = sMinites % 60 153 print(hour,minites, second) 154 countDownLabel.text = "残り (hour) 時間 (minites) 分 (second) 秒" 155 // countDownLabel.text = String(time_value) 156 // print(time_value) 157 } else { 158 remainCount() 159 } 160 } 161 } else { 162 remainCount() 163 } 164 } 165} 166 167 func disassembly (value: Double) { 168 let value = Int(value) 169 let hour = value / 3600 170 let mHour = value % 3600 171 let minites = mHour / 60 172 let sMinites = mHour % 60 173 let second = sMinites % 60 174 self.countDownLabel.text = "残り (hour) 時間 (minites) 分 (second) 秒" 175 }

試したこと

最後のfunc disasseemblyのところのような関数を作ろうとしたのですが、シングルトンやユーザーディフォルトの理解が不十分であることはわかっています。色々なサイトから自分なりにまとめていったのですが、今の自分の頭では限界がきたためどなたかアドバイスいただければと思います。

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

x code 10.2.1 swift5.0.1 macOs Mojave 10.14.5

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

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

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

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

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

TsukubaDepot

2020/04/15 22:03

どこに詰まっているのかちょっとわかりにくい質問だと思います。 具体的にどのようにまとめようとして、どのようなエラーがでたのか(あるいは、一応こうできたけど、ここが理解できない、など)といった、より具体的な問題点を挙げてもらった方がいいかと思います。
sssaqj

2020/04/15 22:24 編集

let hour = self.remain_counts / 3600 let mHour = self.remain_counts % 3600 let minites = mHour / 60 let sMinites = mHour % 60 let second = sMinites % 60 self.countDownLabel.text = "残り \(hour) 時間 \(minites) 分 \(second) 秒" というのがself.remain_countsやtime_valueを分解するという箇所が複数回出てきています。これらを1つの関数にして、使い回し短い表現にできたら良いなと思ったのです。 しかし、 TimerManager.shared.onCountDidSet = { remainCount in self.remain_counts = Int(remainCount) や今回長すぎて載せれなかった別画面のタイマーセッティング画面で作ったタイマー時間の変数を if let time_value = UserDefaults.standard.object(forKey: "timer_value") as? Int で取り出しているのですが、これらのために短くする方法を自分では見出せなかったのです。 教本なんかによく同じような文章を繰り返していると短くした方が良いと書いているのを見かけるので、もっとうまく書く方法があるのじゃないかと思った次第です。
TsukubaDepot

2020/04/15 22:39

考え方は間違っていないと思います。 その考えを実行する一つの方法として、 func disassembly (value: Double) という関数を一つ作り、それなりにまとまっていると思います。 これを実際にご自身のプログラムに入れてみてコンパイルし、実行してみていますでしょうか。 そうでなければ、まず試されてみてはいかがでしょうか。
guest

回答1

0

自己解決

remainCount in self.remain_counts = Int(remainCount)
self.disassembly(value: self.remain_counts)

if let time_value = UserDefaults.standard.object(forKey: "timer_value") as? Int {
self.disassembly(value: time_value)

とすることで解決できました。アドバイスありがとうございました!!

投稿2020/04/15 23:12

sssaqj

総合スコア7

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

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

TsukubaDepot

2020/04/15 23:18

悩むより、まずはやってみるのがいいかと思います。 ただ、リファクタリング(コードの整理)を行うと、動いていたはずのコードが動かなくなるトラブルが発生することもあります。 なので、同時にバージョン管理(Xcodeだと標準機能であります)の方法も抑えておくと安心です。
sssaqj

2020/04/15 23:36

関数をようやく自分で書けるようになったような独学の初心者のためうまくいかなくなった時に途方に暮れてしまいます。バージョン管理、謎のGit repositoryも抑えに行きたいと思います。その辺がよくわからず、イチから打ち直してコピーするというバカなことをしていました。
TsukubaDepot

2020/04/15 23:48

いやいや、そんな卑下することはないと思いますよ。 頑張った分報われると思いますから。 少なくとも、今回の質問については方向性は間違っていないと思いますので、自信を持っていいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問