μ΄λ²μ μΆμν μ±μ 컨μ
μ΄ μμμΌκΈ°
μΈλ°, μ¬μ©μκ° μ€μ ν μμΉ¨, μ μ¬, μ λ
μκ°μ λ‘컬μλ¦Όμ μ€μ μΌκΈ°λ₯Ό κΉλ¨Ήμ§ μκ³ μμ±ν μ μλλ‘ νλ©΄ μ΄λ¨κΉ? νλ μκ°μ λ―Έλ£¨κ³ λ―Έλ€μλ Local Notification
μ 곡λΆν΄λ³΄λ €κ³ ν©λλ€
μλ¦Όμλ μ± λ΄λΆμμ κ°λ°μκ° μ€μ ν 컨ν
μΈ λ₯Ό κΈ°κΈ°μ μ λ¬νλ λ‘컬μλ¦Όκ³Ό μλ²μμ μ¬μ©μ κΈ°κΈ°μ μλ¦Όμ μ λ¬νλ μ격μλ¦Ό(νΈμ μλ¦Ό)
2κ°μ§κ° μμ΅λλ€.
μ΄λ²μλ λ‘컬μλ¦Ό
μ μ€μ μ μΌλ‘ λ€λ€λ³΄κ² μ΅λλ€.
λ‘컬μλ¦Όμ κ²½μ° μμ κ·Έλ¦Όκ³Ό κ°μ΄, μ¬μ©μκ° μλ¦Όμ μμ½νλ©΄ Notification Center
μ μμ΄κ² λκ³ μ€μ ν trigger
쑰건μ λ§κ² μ¬μ©μμ ν΄λν°μ μλμ λμμ€λλ€.
Notification
μ μμ²νκΈ° μν΄μλ
identifier
content
trigger
κ° μλ¦Όμ κ³ μ ν μλ³μ, μ΄λ€ λ΄μ©μ μ¬μ©μκ²μ 보μ¬μ€μ§, κ·Έλ¦¬κ³ μ΄λ€ νμ΄λ°μ μλ¦Όμ μ€μ§λ₯Ό μ€μ ν΄μ€μΌ ν©λλ€.
μ¬μ©μκ° μ€μ ν μκ°μ λ‘컬μλ¦Όμ΄ μ€λλ‘ κ΅¬νν΄λ³΄κ² μ΅λλ€.
1 ) identifier
μ°μ , λ‘컬μλ¦Ό μμ½μ νκΈ° μν΄μλ μλ¦Όμ λν identifier
λ₯Ό μ€μ νλ κ³Όμ μ΄ νμν©λλ€.
identifier
κ° λμΌνλ€λ©΄ μ¬λ¬ μλ¦Όμ 보λ΄λ μλ¦Όμ΄ μμ λλ ννλ‘ λ³κ²½λ©λλ€.
struct Alert: Codable {
var id: String = UUID().uuidString
var date: Date
var isOn: Bool
//μκ°μ νννκΈ° μν΄μ
var time: String {
let timeFormatter = DateFormatter()
timeFormatter.dateFormat = "hh:mm"
return timeFormatter.string(from: date)
}
//μ€μ , μ€νλ₯Ό νννκΈ° μν΄μ
var day: String {
let timeFormatter = DateFormatter()
timeFormatter.dateFormat = "a"
timeFormatter.locale = Locale(identifier: "ko")
return timeFormatter.string(from: date)
}
}
μ°λ¦¬λ μ€μ ν μκ°μ λ§κ² μλμ λμμ£Όλλ‘ ν μμ μ λλ€.
κ·ΈλΌ μ±μ μ’ λ£νλλΌλ μ°λ¦¬κ° μ€μ ν μκ°μ΄ μ± λ΄μ μ μ₯λμ΄ μμ΄μΌν©λλ€.
DataBase
μ μ μ₯ν μ λ μμ§λ§ User Defaults
λ₯Ό ν΅ν΄μ μ±λ΄μ μ μ₯ν μ μλλ‘ μ€μ ν΄λ³΄κ² μ΅λλ€.
(λΈλ‘κ·Έμμ UserDefaults
κΈ°λ³Έ μλ£νμ΄ μλ κ²½μ° μ΄λ»κ² μ μ₯ν΄μΌ ν μ§λ₯Ό κ³ λ―Όνμλλ° μ€λκ³Ό κ°μ λ°©λ²μΌλ‘ ν΄κ²°ν μ μμ΅λλ€.)
κ³ μ ν μλ³μλ UUID
λ₯Ό ν΅ν΄μ κ³ μ ν id λ₯Ό μμ±νλλ‘ μ€μ νκ³ , μ°λ¦¬λ μ¬μ©μκ° μ€μ ν μκ°κ³Ό ν΄λΉ μλμ On,Off νλμ§λ₯Ό μ μ₯νλλ‘ μ»€μ€ν
νμ
μ λ§λ€μ΄μΌ νκΈ° λλ¬Έμ Codable
νμ
μΌλ‘ μ€μ ν©λλ€.
π₯ μΈμ½λ©, λμ½λ©μ ν΅ν΄μ μμ <-> μΈλΆν¬ν μΌλ‘ λ³ννκΈ° μν΄μ
2) Content & Trigger
extension UNUserNotificationCenter {
func addNotificationRequest(by alert: Alert) {
let content = UNMutableNotificationContent()
content.title = "μ€μ ν μκ°μ΄μμ"
content.body = "μμ¬λ₯Ό κΈ°λ‘ν΄λ³΄μΈμ"
content.sound = .default
content.badge = 1
let component = Calendar.current.dateComponents([.hour, .minute], from: alert.date)
let trigger = UNCalendarNotificationTrigger(dateMatching: component, repeats: alert.isOn)
let request = UNNotificationRequest(identifier: alert.id, content: content, trigger: trigger)
self.add(request, withCompletionHandler: nil)
}
}
μ°λ¦¬κ° μμ μ€μ ν ꡬ쑰체λ₯Ό ν΅ν΄μ content
μ trigger
λ₯Ό λ§λ€μ΄μ μλ¦Όμ μμ½ ν΄λ³΄κ² μ΅λλ€.
content
μ κ²½μ°μλ μλμ 4κ°μ§λ₯Ό μ€μ ν΄ μ€ μ μμ΅λλ€.
trigger
μ κ²½μ°μλ μλμ 3κ°μ§ νΈλ¦¬κ±°λ₯Ό μ΄μ©ν μ μμ΅λλ€.
μμ κ°μ΄ id, content, trigger
λ₯Ό μ€μ ν΄μ£Όκ³ NotificationCenter
μ NotificationRequest
λ₯Ό μΆκ°νλ©΄ λ©λλ€.
κ·ΈλΌ μ¬μ©μ 컀μ€ν
νμ
μ User Defaults
μ μ μ₯νκΈ° μν΄μλ μ΄λ»κ² ν΄μΌν κΉμ?
var alertList: [Alert] = []
let userNotificationCenter = UNUserNotificationCenter.current()
func makeAlertList() -> [Alert] {
guard let data = UserDefaults.standard.value(forKey: "alerts") as? Data,
let alerts = try? PropertyListDecoder().decode([Alert].self, from: data) else { return [] }
return alerts
}
μ°μ UserDefaults μ μ μ₯λ λ°μ΄ν°λ₯Ό λ°°μ΄ alertListμ μ μ₯νκΈ° μν΄μλ λμ½λ©
ν΄μ£Όλ κ³Όμ μ΄ νμν©λλ€.
λμ½λ© λ κ°λ€μ Alert νμ λ°°μ΄μ μ μ₯μν€κ³ ν΄λΉ λ°°μ΄μ λ°νν©λλ€.
@IBAction func addButtonClicked(_ sender: UIBarButtonItem) {
let sb = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: "AddViewController") as! AddViewController
vc.pickedDate = { [weak self] date in
guard let self = self else { return }
let newAlert = Alert(date: date, isOn: true)
var alerts = self.makeAlertList()
//νμ¬ λ°°μ΄μ μΆκ°
alerts.append(newAlert)
alerts.sort { $0.date < $1.date }
self.alertList = alerts
//μ μ λν΄νΈμ μλ‘μ΄ μλμ μΆκ°
UserDefaults.standard.set(try? PropertyListEncoder().encode(self.alertList), forKey: "alerts")
self.userNotificationCenter.addNotificationRequest(by: newAlert)
self.tableView.reloadData()
}
self.present(vc, animated: true, completion: nil)
}
λ°λλ‘, μ¬μ©μκ° μ€μ ν μλ μ 보λ₯Ό(ID)
User Defaults μ μ μ₯νκΈ° μν΄μλ μΈμ½λ©
μμ
μ΄ νμν©λλ€.
μλ¦ΌμΌν°μ μλμ΄ νμ λκΈ° μν΄μλ μ¬μ©μκ° κΆνμ νμ©ν΄μΌλ§ μλ¦ΌμΌν°μ μλ¦Όμ΄ νμλ μ μμ΅λλ€.
imagePicker
μμ κΆν μ€μ μ μν΄μ κΆν문ꡬλ₯Ό plistλ‘ μ€μ νλ κ²κ³Όλ λ¬λ¦¬ μμ€ν
μμ κΆν λ¬Έκ΅¬κ° λ―Έλ¦¬ ꡬνλμ΄ μμ΅λλ€.
let userNotificationCenter = UNUserNotificationCenter.current()
//μ¬μ©μλ‘λΆν° κΆνμ λ°λλ‘ νλ μ€μ
let authorizationOptions = UNAuthorizationOptions(arrayLiteral: [.alert, .badge, .sound])
userNotificationCenter.requestAuthorization(options: authorizationOptions) { _, error in
if let error = error {
print("ERROR: \(error.localizedDescription)")
}
}
μμ κ°μ μ½λλ₯Ό μλμ μ΄μ©ν viewμ viewDidLoadμ μμ±ν΄μ μ¬μ©νλ©΄ λ©λλ€.
βοΈUNNotificiationλ currnet λ₯Ό μ¬μ©ν΄μΌ ν©λλ€
μ 체μ½λλ κΉνλΈλ₯Ό ν΅ν΄μ νμΈ ν μ μμ΅λλ€.
κ°μλ₯Ό λ€μΌλ©΄μ λ¨μν μλμ€μ λΏλ§ μλλΌ
UserDefaults
μ 컀μ€ν
νμ
μ μ€μ νλ λ²λ± λͺ°λλ κΈ°μ (?) μννκ² μκ°νκ³ μλ κ°λ λ€μ νλ² λ 곡λΆν μ μμμ΅λλ€.
μ΄μ μ± μ λ°μ΄νΈλ₯Ό μν΄ μΆκ°μ μΌλ‘
λ₯Ό μμ£Όλ‘ νμ΅μ νκ³ λ΄μ©μ μ 리νλ μκ°μ κ°μ§κ² κ°μ΅λλ€.