シングルトンやユーザーディフォルトからのデータを関数にまとめる方法を教えてください
解決済
回答 1
投稿
- 評価
- クリップ 0
- VIEW 235
シングルトンやユーザーディフォルトからのデータを関数にまとたい
タイマーマネージャーのシングルトンを持ったピッカービューで時間を設定するタイマーを作っています。時間を扱うために合計時間を時間、分、秒へと分解する箇所が複数あり冗長だなと思うので関数に処理をまとめたいと思います。
しかし、元の合計時間がシングルトンから引っぱってきたものと、ユーザーディフォルトからのものとが混在してうまくまとめる方法が考えられないのです。
どなたかご教示いただければ幸いです。
該当のソースコード
class TimerManager {
static let shared = TimerManager()
var timer : Timer?
var setCount: Double? = nil
var count = 0.0
var remainCount: Double? = nil {
didSet {
onCountDidSet?(remainCount!)
}
}
var onCountDidSet: ((_ count: Double) -> Void)? = nil
func startCount() {
if timer == nil {
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) {
timer in self.timerCount(timer)}
}
}
func stopCount() {
count = 0.0
pauseCount()
}
func pauseCount() {
if let nowTimer = timer {
if nowTimer.isValid == true {
nowTimer.invalidate()
}
self.timer = nil
}
}
func timerCount(_ timer: Timer) {
if let _ = UserDefaults.standard.object(forKey: "timer_value") as? Int {
setCount = (UserDefaults.standard.object(forKey: "timer_value")) as? Double
}
count += 1.0
if let set_count = setCount {
remainCount = set_count - count
}
if let remain_count = remainCount {
if remain_count <= 0.0 {
count = 0.0
timer.invalidate()
print("finish")
}
}
}
var timer_status = "stop"
func timerStatus() {
if timer == nil {
timer_status = "stop"
}
else {
timer_status = "counting"
}
}
}
---------------------------------------------
class ViewController: UIViewController {
var alertController = UIAlertController()
@IBOutlet weak var countDownLabel: UILabel!
@IBAction func settingButtonAction(_ sender: Any) {
}
@IBAction func startButtonAction(_ sender: Any) {
TimerManager.shared.startCount()
}
@IBAction func stopButtonAction(_ sender: Any) {
TimerManager.shared.pauseCount()
}
var remain_counts = 0
func remainCount() {
TimerManager.shared.onCountDidSet = {
remainCount in self.remain_counts = Int(remainCount)
let hour = self.remain_counts / 3600
let mHour = self.remain_counts % 3600
let minites = mHour / 60
let sMinites = mHour % 60
let second = sMinites % 60
print(hour,minites, second)
self.countDownLabel.text = "残り \(hour) 時間 \(minites) 分 \(second) 秒"
if remainCount <= 0.0 {
self.returnData()
}
}
}
func returnData(){
self.alert(title: "終了",
message: "終了です")
}
func alert(title: String, message: String) {
alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alertController, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
// 画面遷移時のタイマー作動/停止で表示を変える
TimerManager.shared.timerStatus()
let nowCount = TimerManager.shared.timer_status
let presenceCount = TimerManager.shared.count
// タイマー停止状態を判断
if nowCount == "stop" {
// カウンターもリセットされている(一時停止ではない)
if presenceCount == 0.0 {
if let time_value = UserDefaults.standard.object(forKey: "timer_value") as? Int {
print(time_value)
let hour = time_value / 3600
let mHour = time_value % 3600
let minites = mHour / 60
let sMinites = mHour % 60
let second = sMinites % 60
print(hour,minites, second)
countDownLabel.text = "残り \(hour) 時間 \(minites) 分 \(second) 秒"
} else {
// 一時停止なら残り時間を表示
remainCount()
}
}
// タイマーが動いていれば残り時間を表示
} else {
remainCount()
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
remainCount()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
TimerManager.shared.onCountDidSet = nil
}
override func viewDidAppear(_ animated: Bool) {
TimerManager.shared.timerStatus()
let nowCount = TimerManager.shared.timer_status
let presenceCount = TimerManager.shared.count
if nowCount == "stop" {
if presenceCount == 0.0 {
if let time_value = UserDefaults.standard.object(forKey: "timer_value") as? Int {
print(time_value)
let hour = time_value / 3600
let mHour = time_value % 3600
let minites = mHour / 60
let sMinites = mHour % 60
let second = sMinites % 60
print(hour,minites, second)
countDownLabel.text = "残り \(hour) 時間 \(minites) 分 \(second) 秒"
// countDownLabel.text = String(time_value)
// print(time_value)
} else {
remainCount()
}
}
} else {
remainCount()
}
}
}
func disassembly (value: Double) {
let value = Int(value)
let hour = value / 3600
let mHour = value % 3600
let minites = mHour / 60
let sMinites = mHour % 60
let second = sMinites % 60
self.countDownLabel.text = "残り \(hour) 時間 \(minites) 分 \(second) 秒"
}
試したこと
最後のfunc disasseemblyのところのような関数を作ろうとしたのですが、シングルトンやユーザーディフォルトの理解が不十分であることはわかっています。色々なサイトから自分なりにまとめていったのですが、今の自分の頭では限界がきたためどなたかアドバイスいただければと思います。
補足情報(FW/ツールのバージョンなど)
x code 10.2.1 swift5.0.1 macOs Mojave 10.14.5
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
check解決した方法
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)
とすることで解決できました。アドバイスありがとうございました!!
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.36%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
TsukubaDepot
2020/04/16 07:03
どこに詰まっているのかちょっとわかりにくい質問だと思います。
具体的にどのようにまとめようとして、どのようなエラーがでたのか(あるいは、一応こうできたけど、ここが理解できない、など)といった、より具体的な問題点を挙げてもらった方がいいかと思います。
sssaqj
2020/04/16 07:21 編集
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/16 07:39
考え方は間違っていないと思います。
その考えを実行する一つの方法として、
func disassembly (value: Double)
という関数を一つ作り、それなりにまとまっていると思います。
これを実際にご自身のプログラムに入れてみてコンパイルし、実行してみていますでしょうか。
そうでなければ、まず試されてみてはいかがでしょうか。