์ฑ์ ์๋น์คํ๋ค๋ณด๋ฉด ๋ฒ๊ทธ๊ฐ์ ๋๋ ์ ๋ฐ์ดํธ ์๋ด ๋ฑ์ ์ด์ ๋ก ๋จ 1ํ๋ง ๋์ํ๋ ์ฝ๋๊ฐ ํ์ํ ๋๊ฐ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, TiTi์์๋ ๋น์ด์๋ ๊ธฐ๋ก ๊ฐ์ฒด์ธ Daily๊ฐ ์ฌ๋ผ์ง์ง ์์์ Logํ๋ฉด์ ๊ธฐ๋ก์ด ์๋ ๊ฒ ์ฒ๋ผ ๋ณด์ด๋ ๋ฒ๊ทธ๊ฐ ์์๋๋ฐ์,
๋ณด๋ค์ํผ ๊ธฐ๋ก์ด ๋น์ด ์๋๋ฐ๋ ๋ ์ง ์๋์ ์ ์ด ์ฐํ ์์ต๋๋ค (๊ธฐ๋ก์ด ์๋ ๊ฒฝ์ฐ์๋ง ์ ์ด ์ฐํ ์์ด์ผํจ)
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ ๋ ๊ฐ์ง ๋์์ด ํ์ ํ์ต๋๋ค.
1. ์ฌ์ฉ์๊ฐ ๊ธฐ๋ก์ ํธ์งํด์ ๊ทธ ๋ ์ ๊ธฐ๋ก์ ๋ชจ๋ ์ง์ฐ๋ ๊ฒฝ์ฐ Daily๊ฐ์ฒด๋ฅผ ์ญ์ ํ๋ค.
2. ๋ฒ๊ทธ ๊ฐ์ ์ ์ ์กด์ฌํ๋ ๋น์ด์๋ Daily๊ฐ์ฒด๋ฅผ ๋ชจ๋ ์ญ์ ํ๋ค.
์ฌ๊ธฐ์ 2๋ฒ์ ์ฌ์ฉ์๊ฐ ์ฑ์ ์ง์ ํ ๋ 1ํ๋ง ์์ ํ๋ฉด ๋๋ ๋ด์ฉ์ ๋๋ค.
์ฌ๋ฌ๋ฒ ๋์ํด๋ ๋ฌธ์ ๋ ์๊ฒ ์ง๋ง, ๋น์ด ์๋ Daily๊ฐ์ฒด๋ฅผ ์ฐพ๊ธฐ ์ํด ํ์ฌ ์กด์ฌํ๋ Daily ๊ฐ์ฒด๋ฅผ ์์ ํ์ ํด์ผํ๊ณ 1ํ ์์ ์ดํ์๋ ๋น์ด ์๋ Daily๊ฐ์ฒด๊ฐ ์กด์ฌํ์ง ์์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ํ์ ์๋ ๋์์ ๋ฐ๋ณตํ๊ฒ ๋๋ ๊ฒ์ด์ฃ !
์๋ฌดํผ, ์ด๋ฐ ์ด์ ๋ก 1ํ๋ง ์์ ํ๊ฒ ๋ ์ฝ๋๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํด์๋ ์ฌ๋ฌ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
1. ์์ ์ ํ์๋ฅผ ๊ด๋ฆฌํ์ง ์๊ธฐ
๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ ๋๋ค.
private func removeEmptyDailys() {
RecordsManager.shared.dailyManager.removeEmptyDailys()
}
// RecordsManager.shared.dailyManager.removeEmptyDailys()
func removeEmptyDailys() {
dailys = dailys.filter { daily in
return daily.totalTime > 0
}
self.saveDailys()
}
์ด ํจ์๋ฅผ ์ฑ์ ์ผค๋ ๋ง๋ค ๋์ํ๋๋ก ํ๋ ๊ฒ์ด์ฃ .
์์ ๋งํ๋๋ก ์ด๋ dailys๋ฅผ ์์ ํ์ํ๊ธฐ ๋๋ฌธ์ ๋งค์ฐ ๋นํจ์จ์ ์ ๋๋ค. ๐๐ป
2. UserDefaults๋ก๊ด๋ฆฌํ๊ธฐ
private func removeEmptyDailys() {
guard let _ = UserDefaults.standard.object(forKey: "didRemoveEmptyDailys") as? Bool else {
RecordsManager.shared.dailyManager.removeEmptyDailys()
UserDefaults.standard.setValue(true, forKey: "didRemoveEmptyDailys")
return
}
}
์ด ๋ฐฉ๋ฒ์ ์ค์ ๋ก 1ํ๋ง ๋์ํ๊ฒ ๋ฉ๋๋ค.
ํ์ง๋ง, UserDefaults์ ๋ฃ์ Bool๊ฐ์ด ์ค์ ๋ก๋ ์๋ฌด ์๋ฏธ๊ฐ ์๋ ๊ฐ์ด ๋ฉ๋๋ค.
1ํ ๋์ ์ ์๋ UserDefaults์ ๊ฐ์ด ์๊ธฐ ๋๋ฌธ์ guard๋ฌธ ๋ด๋ถ๋ฅผ ์คํํฉ๋๋ค.
์ดํ์๋ UserDefaults์ ๊ฐ์ด ์๊ณ , ๊ทธ ๋ง์ 1ํ ๋์์ ํ๋ค๋ ์๋ฏธ์ด๊ธฐ ๋๋ฌธ์ true/false ์ด๋ค ๊ฐ์ด ๋ค์ด๊ฐ๋ ๋ฌด๊ดํฉ๋๋ค.
์ฆ, UserDefaults์ ๊ฐ์ด ์กด์ฌ ํ๋์ง์ ์ฌ๋ถ๋ก ๋์ ์ฌ๋ถ๋ฅผ ํ๋จํ๊ฒ ๋๋ ๊ฒ์ ๋๋ค.
UserDefaults๋ก ๊ฐ์ ์ ์ฅํ๋๊ฒ ์กฐ์ฐจ 1ํ์ฑ์ธ ๊ฒ์ด์ฃ .
UserDefaults๋ ๋นํ๋ฐ์ฑ์ด๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ฐจ์งํ๊ฒ ๋ฉ๋๋ค.
๋ฌผ๋ก ์์ ๊ฐ์ด์ง๋ง, ์ด๋ฌํ 1ํ์ฑ ๋์์ด ์ฌ๋ฌ๊ฐ๊ฐ ๋๋ค๋ฉด ๋ถ๋ช ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ญ๋น ๋ ๊ฒ์ ๋๋ค.
์ด๋ฅผ ๊ฐ์ ํ๊ธฐ ์ํด ํ๋์ UserDefaults ๊ฐ์ผ๋ก ์ฌ๋ฌ ๊ฐ์ 1ํ์ฑ ๋์๋ค์ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๊ณ ์ํ์ต๋๋ค.
3. 1ํ์ฑ ๋์์ Version์ผ๋ก ๊ด๋ฆฌํ๊ธฐ
์ ์ ๊ฐ ์ ๋ฐ์ดํธ ํ๋ ๋ฒ์ ์ ๊ธฐ๋กํ์ฌ,
1ํ์ฑ ๋์์ ์ํํ ๋ฒ์ ์ ํตํด ๊ด๋ฆฌํ๋ ๊ฒ์ ๋๋ค.
์ข ๋ ์ฝ๊ฒ.. ์ค๋ช ํด๋ณด์๋ฉด
์๋ฅผ ๋ค์ด, `removeEmptyDailys`๊ฐ 2.1 ๋ฒ์ ์ ์ ๋ฐ์ดํธ ๋๋ค๊ณ ๊ฐ์ ํ๊ฒ ์ต๋๋ค.
- ์ฌ์ฉ์๊ฐ 2.0 ๋ฒ์ ์ ์ฐ๋ค๊ฐ 2.1 ๋ฒ์ ์ผ๋ก ์
๋ฐ์ดํธ ํ๊ณ ์ฑ์ ์ผ ๋ค๋ฉด? -> removeEmptyDailys ์ํโญ๏ธ
- ์ฌ์ฉ์๊ฐ 2.1 ๋ฒ์ ์ ์ฐ๋ ์ฌ์ฉ์๊ฐ ์ฑ์ ์ผ ๋ค๋ฉด? -> removeEmptyDailys ์ํโ
- ์ฌ์ฉ์๊ฐ 2.1 ๋ฒ์ ์ ์ฐ๋ค๊ฐ 3.0 ๋ฒ์ ์ผ๋ก ์
๋ฐ์ดํธ ํ๊ณ ์ฑ์ ์ผ ๋ค๋ฉด? -> removeEmptyDailys ์ํโ
์ด๋ฐ ๋ฐฉ์์ผ๋ก ๋์ํ ์ ์๊ฒ ๊ตฌํํ๋ ๊ฒ์ ๋๋ค !
์ฌ๊ธฐ์ ์ฌ์ฉ์๊ฐ ์ฐ๋ ๋ฒ์ ์ UserDefaults์ ์ ์ฅํด์ ๊ด๋ฆฌํ๊ณ ,
์ํํ ๋ก์ง์ ์ด๋ค ๋ฒ์ ์์ ์ํ๋ ์ง๋ฅผ enum์ผ๋ก ์ ์ฅํด์ ๊ด๋ฆฌํ ๊ฒ์ ๋๋ค.
๋ง์ ๋๋ฌด ์ด๋ ค์ฐ๋..
๋์์ ๊ด๋ฆฌํ Version๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
struct Version {
}
๋จผ์ , ํ์ฌ ์ฌ์ฉ์๊ฐ ์ด๋๊น์ง ์ ๋ฐ์ดํธ ๋์๋์ง ๊ธฐ๋ก์ ํด์ผ๊ฒ ์ฃ ? == ์ฌ์ฉ์๊ฐ ์ฐ๋ ๋ฒ์
๊ทธ ๋ฒ์ ์ UserDefaults์ ๊ธฐ๋ก ํ ๊ฒ์ ๋๋ค. ์ด๋ฅผ, lastUpdateVersion์ด๋ผ๊ณ ํ๊ฒ ์ต๋๋ค.
static private var lastUpdateVersion: String {
UserDefaults.standard.object(forKey: "lastUpdateVersion") as? String ?? "2.0"
}
lastUpdateVersion์ ์ ์ ๊ฐ ์ฑ์ ์ ๋ฐ์ดํธ ํ๊ธฐ ์ง์ ์ ์ฌ์ฉํ๋ ์ฑ์ ๋ฒ์ ์ ๋ด๊ณ ์๊ฒ ๋ฉ๋๋ค.
default value๋ฅผ 2.1๋ก ํด์ค ์ด์ ๋ ์ฒ์ ํด๋น ์ฝ๋๋ฅผ ๋์ ์ํฌ ๋ UserDefaults์ ๊ฐ์ด ์๊ธฐ ๋๋ฌธ์,
Keys์ ์๋ ๋ก์ง์ด ๋ชจ๋ ์คํ๋๊ฒ ํ๊ธฐ ์ํด Keys์ค์ ๊ฐ์ฅ ์์ ๊ฐ ๋ณด๋ค ์์ ๋ฒ์ ์ default value๋ก ๊ฐ์ง๋๋ค.
1ํ์ฑ ๋ก์ง๋ค์ ๊ด๋ฆฌํ๊ธฐ ์ํด key๊ฐ์ ๋ง๋ญ๋๋ค.
private enum Keys: String, CaseIterable {
case removeEmptyDailys = "2.1"
case anotherOnceLogic = "2.7"
}
์ฌ๊ธฐ์ ๊ฐ์ง๋ rawValue๋ ์ ์ ๊ฐ ์ด ๋ฒ์ ๋ณด๋ค ๋ฎ์ ๋ฒ์ ์ ์ผ๋ค๊ฐ ์ฑ์ ์ ๋ฐ์ดํธ ํ๋ค๋ฉด ํด๋น ๋ก์ง์ ์ํํ ๊ฑฐ์ผ!
๋ผ๋ ์๋ฏธ๋ฅผ ๋ด๊ณ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด,
์ ์ ๊ฐ 2.1๋ณด๋ค ๋ฎ์ ๋ฒ์ ์ ์ฐ๋ค๊ฐ ์ฑ์ ์ ๋ฐ์ดํธ ํ๋ค๋ฉด removeEmptyDailys๋ฅผ ์ํํ ๊ฑฐ์ผ!
๋ผ๋ ์๋ฏธ์ ๋๋ค.
์ด์ ,
- ์ฌ์ฉ์๊ฐ 2.0 ๋ฒ์ ์ ์ฐ๋ค๊ฐ 2.1 ๋ฒ์ ์ผ๋ก ์
๋ฐ์ดํธ ํ๊ณ ์ฑ์ ์ผ ๋ค๋ฉด? -> removeEmptyDailys ์ํโญ๏ธ
- ์ฌ์ฉ์๊ฐ 2.1 ๋ฒ์ ์ ์ฐ๋ ์ฌ์ฉ์๊ฐ ์ฑ์ ์ผ ๋ค๋ฉด? -> removeEmptyDailys ์ํโ
- ์ฌ์ฉ์๊ฐ 2.1 ๋ฒ์ ์ ์ฐ๋ค๊ฐ 3.0 ๋ฒ์ ์ผ๋ก ์
๋ฐ์ดํธ ํ๊ณ ์ฑ์ ์ผ ๋ค๋ฉด? -> removeEmptyDailys ์ํโ
์ ๋ก์ง๋ค์ ์ํํ๊ธฐ ์ํด ๋ค์๊ณผ ๊ฐ์ ํจ์๋ฅผ ๋ง๋ญ๋๋ค.
/// (extension String) static let currentVersion: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
static func update() {
if lastUpdateVersion == String.currentVersion { return }
for key in Keys.allCases {
if !check(forKey: key) { continue }
switch key {
case .removeEmptyDailys:
removeEmptyDailys()
case .anotherOnceLogic:
anotherOnceLogic()
}
}
UserDefaults.standard.setValue(String.currentVersion, forKey: "lastUpdateVersion")
}
static private func check(forKey key: Versions.Keys) -> Bool {
let checkVer = key.rawValue
return checkVer.compare(lastUpdateVersion, options: .numeric) == .orderedDescending
}
์ฝ๋๋ฅผ ์ฐฌ์ฐฌํ ์ดํด ๋ณผ๊ฒ์.
if lastUpdateVersion == String.currentVersion { return }
์ ์ ๊ฐ ์ ๋ฐ์ดํธ ํ๊ธฐ ์ง์ ๋ฒ์ (lastUpdateVersion)๊ณผ ์ ๋ฐ์ดํธ ํ ๋ฒ์ (currentVersion)์ด ๋์ผํ๋ฉด, ๋์ํ์ง ์์ต๋๋ค.
(์ด๋ฏธ ์ ๋ฐ์ดํธ๊ฐ ์๋ฃ ๋์๋ค๋ ์๋ฏธ์ ๋๋ค)
for key in Keys.allCases {
if !check(forKey: key) { continue }
switch key {
case .removeEmptyDailys:
removeEmptyDailys()
case .anotherOnceLogic:
anotherOnceLogic()
}
}
check()๋ฅผ ํตํด key์ ๋ฒ์ ๊ณผ ์ ๋ฐ์ดํธํ๊ธฐ ์ง์ ๋ฒ์ ์ ๋น๊ตํฉ๋๋ค.
key์ ๋ฒ์ ์ด ๋ ๋์ ๊ฒฝ์ฐ์๋ง true์ ๋๋ค.
check()๊ฐ true๋ผ๋ฉด ์ ๋ฐ์ดํธ๊ฐ ํ์ํ๋ค๋ ์๋ฏธ์ ๋๋ค.
ํด๋น key์ ๋ง๋ ๋ก์ง์ ํจ์๋ก ์์ฑํด๋๊ณ , ์คํํฉ๋๋ค.
removeEmptyDailys๋ก ์๋ฅผ ๋ค๋ฉด,
์ฌ์ฉ์๊ฐ ์ ๋ฐ์ดํธ ์ ์ 2.0๋ฒ์ ์ ์ฌ์ฉํ๊ณ ์์๋ค๋ฉด check๋ true์ ๋๋ค.
๊ทธ๋ ๋ค๋ฉด switch๋ฌธ์ ํตํด removeEmptyDailys()๋ฅผ ์คํํ๊ฒ ๋ ๊ฒ์ ๋๋ค.
UserDefaults.standard.setValue(String.currentVersion, forKey: "lastUpdateVersion")
๋ก์ง์ด ๋ชจ๋ ์ํ๋๊ณ ๋๋ฉด, lastUpdateVersion๊ฐ์ ํ์ฌ ๋ฒ์ ์ผ๋ก ๋ฐ๊ฟ ์ค๋๋ค.
์ฆ, 2.0๋ฒ์ ์ ์ฌ์ฉํ๊ณ ์๋ ์ฌ์ฉ์๊ฐ 2.1 ๋ฒ์ ์ผ๋ก ์ ๋ฐ์ดํธ ํ๋ค๋ฉด lastUpdateVersion์ 2.1๋ก ๋ณ๊ฒฝ๋ ๊ฒ์ ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ค์์ ์ฑ์ ์ผฐ์ ๋, update()์์
if lastUpdateVersion == String.currentVersion { return }
์ ์กฐ๊ฑด๋ฌธ์ ๊ฑธ๋ ค ์๋ ์ฝ๋๋ฅผ ์ํํ์ง ์๊ฒ ์ฃ ?
์ฆ, ์ ๋ฐ์ดํธ ๋ก์ง์ 1ํ๋ง ์ํํ๊ฒ ๋๋ ๊ฒ์ ๋๋ค.
์กฐ๊ฐ๋ ์ฝ๋๋ฅผ ๋ชจ์์ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
struct Versions {
static private var lastUpdateVersion: String {
UserDefaultsManager.get(forKey: .lastUpdateVersion) as? String ?? "2.0"
}
private enum Keys: String, CaseIterable {
case removeEmptyDailys = "2.1"
case anotherOnceLogic = "2.7"
}
static func update() {
if lastUpdateVersion == String.currentVersion { return }
for key in Keys.allCases {
if !check(forKey: key) { continue }
switch key {
case .removeEmptyDailys:
removeEmptyDailys()
case .anotherOnceLogic:
anotherOnceLogic()
}
}
UserDefaults.standard.setValue(String.currentVersion, forKey: "lastUpdateVersion")
}
static private func check(forKey key: Versions.Keys) -> Bool {
let checkVer = key.rawValue
return checkVer.compare(lastUpdateVersion, options: .numeric) == .orderedDescending
}
static private func removeEmptyDailys() {
//code
}
static private func anotherOnceLogic() {
//code
}
}
์ด๋ ๊ฒ ํ๋ฉด, UserDefaults๊ฐ ํ๋๋ก 1ํ๋ง ๋์ํ๋ ๋ก์ง๋ค์ ๊ด๋ฆฌ ํ ์ ์์ต๋๋ค!
์ธ๋ถ์์๋ update() ํจ์ ํธ์ถ๋ง์ผ๋ก ์ ๋ฐ์ดํธ๋ฅผ ์งํํ ์ ์์ต๋๋ค.
Versions.update()
๋ ์ข์ ์๊ฒฌ์ด ์๋ค๋ฉด ๋๊ธ ๋ถํ๋๋ฆฝ๋๋ค ๐