NEW: Learn to build amazing SwiftUI apps for macOS with my new book! >>

Local Notifications

Forums > SwiftUI

Hi Everyone Hope y'all are fine. I need your help, i'm trying to write a local notifications. Trying to use Pauls Adding local notifications. But is not working as i intended, I want the the local notifications to trigger when the time for prayer starts. See below code

private func placeReminders(for prayer: Prayer, completion: @escaping (Bool) -> Void) {
    let content = UNMutableNotificationContent()

    content.title = "Salahtider"
    content.sound = .default
    //content.subtitle = "Time for prayer! ⏱"

    if let fajr = prayer.fajr {
      content.subtitle = "Time for \(fajr)! ⏱"
    } else if let shuruk = prayer.shuruk {
      content.subtitle = "Time for \(shuruk)! ⏱"
    } else if let dhuhr = prayer.dhuhr {
      content.subtitle = "Time for \(dhuhr)! ⏱"
    } else if let asr = prayer.asr {
      content.subtitle = "Time for \(asr)! ⏱"
    } else if let maghrib = prayer.maghrib {
      content.subtitle = "Time for \(maghrib)! ⏱"
    } else if let isha = prayer.isha {
      content.subtitle = "Time for \(isha)! ⏱"
    }

    let components = Calendar.current.dateComponents([.hour, .minute], from: reminderTime )

    let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: false)

    let id = UUID().uuidString
    let request = UNNotificationRequest(identifier: id, content: content, trigger: trigger)

    UNUserNotificationCenter.current().add(request) { error in
      DispatchQueue.main.async {
        if error == nil {
          completion(true)
        } else {
          completion(false)
        }
      }
    }
  }

1      

Hi Lamin Think it to do with use of if let. This is used if the result is an optional. Try using a switch Example below as do not know what Prayer is, so I just used an enum

switch prayer {
case .fajr:
  content.subtitle = "Time for Fajr! ⏱"
case .shuruk:
  content.subtitle = "Time for Shuruk! ⏱"
case .dhuhr:
  content.subtitle = "Time for Dhuhr! ⏱"
case .asr:
  content.subtitle = "Time for Asr! ⏱"
case .maghrib:
  content.subtitle = "Time for Maghrib! ⏱"
case .isha:
  content.subtitle = "Time for Isha! ⏱"
}

however if it is a enum you can just do

content.subtitle = "Time for \(String(describing: prayer).capitalized)! ⏱"

1      

As you have specified how reminderTime is defined or derived, and If you're following Paul's example then shouldn't this line

let components = Calendar.current.dateComponents([.hour, .minute], from: reminderTime )

be

let components = Calendar.current.dateComponents([.hour, .minute], from: prayer.reminderTime! )

or the less risky?

let components = Calendar.current.dateComponents([.hour, .minute], from: prayer.reminderTime ?? Date() )

1      

Well i am getting my data from a network call so, my model is not exactly like Paul's example. Prayers is not enum is my model

struct Response: Codable {
  let date: String
  let prayerTimes: [String: String]
}

// MARK: - Prayer
struct Prayers: Codable {
  var reminderTime = Date()
  let fajr, shuruk, dhuhr, asr: String
  let maghrib, isha, hanafiASR: String

  enum CodingKeys: String, CodingKey {
    case fajr, shuruk, dhuhr, asr, maghrib, isha
    case hanafiASR = "hanafi asr"
  }

  static var examples =
  Prayers (
    fajr: "03:44",
    shuruk: "05:49",
    dhuhr: "13:09",
    asr: "17:05",
    maghrib: "20:29",
    isha: "22:36",
    hanafiASR: "18:06"
  )
}

1      

Your structure definition and call prarameter types don't match - Prayers and Prayer

struct Prayers: Codable {
private func placeReminders(for prayer: Prayer, completion: @escaping (Bool) -> Void) {

Since they don't match, how have you defined Prayer , or they should match instead?

1      

I've changed Prayer to Prayers

1      

We probably need more information but based on your code there is a few problems.

  1. Not sure where reminderTime is being derived in placeReminders, going to assume is a function on Prayers.
  2. Prayers implements reminderTime with a default of Date() which means that every Prayers instance will always contain the time it was instantiated.
  3. If placeReminders is using reminderTime then reminderTime will always be in the past, meaning the notification will probably never trigger.
  4. If the app is in the foreground, notifications won't display unless you explicity set up that handling.

You probably want to parse the string you are getting (fajr, hanafiASR) into Date's with a custom decoder, then when scheduling, schedule each property. There is no need for reminderTime if what you are actually trying to do is schedule all of these things.

1      

Hi @ericlewis can you please show me an example?

1      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Spend less time managing in-app purchase infrastructure so you can focus on building your app. RevenueCat gives everything you need to easily implement, manage, and analyze in-app purchases and subscriptions without managing servers or writing backend code.

Get Started

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.