Swift: преобразование локального уведомления в уведомление пользователя IOS 10

Недавно я обновил свой проект до IOS 10, из-за чего все локальные уведомления, которые я зарегистрировал, не срабатывали. Я попытался преобразовать локальное уведомление в пользовательские уведомления, но оно не имеет такого же эффекта. Вот исходный код, который я пытался преобразовать. Внутри viewDidLoad:

        guard let settings = UIApplication.shared.currentUserNotificationSettings else { return
        }
        if settings.types == UIUserNotificationType() {
            let ac = UIAlertController(title: "Cant Schedule", message: "No Permission", preferredStyle: .alert)
            ac.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
            present(ac, animated: true, completion: nil)
            return
        }


        var dateComp: DateComponents = DateComponents()
        dateComp.year = 2017;
        dateComp.month = 01;
        dateComp.day = 28;
        dateComp.hour = 11;
        dateComp.minute = 0;
        (dateComp as NSDateComponents).timeZone = TimeZone.current

        let calender:Calendar = Calendar(identifier: Calendar.Identifier.gregorian)
        let date:Date = calender.date(from: dateComp)!


        let notification = UILocalNotification()
        notification.fireDate = date
        notification.alertBody = "Notification!"
        notification.alertAction = "You just Received a notification!"
        notification.soundName = UILocalNotificationDefaultSoundName
        notification.userInfo = ["customField1": "w00t"]
        notification.repeatInterval = NSCalendar.Unit.weekOfYear
        UIApplication.shared.scheduleLocalNotification(notification)

Это привело к тому, что локальное уведомление срабатывало в 11:00 каждую субботу.

Вот код, который я использовал, чтобы добиться того же эффекта в IOS 10:

func scheduleNotification(at date: Date) {
let calendar = Calendar(identifier: .gregorian)
let components = calendar.dateComponents(in: .current, from: date)
let newComponents = DateComponents(calendar: calendar, timeZone: .current, month: components.month, day: components.day, hour: components.hour, minute: components.minute)

let trigger = UNCalendarNotificationTrigger(dateMatching: newComponents, repeats: true)

let content = UNMutableNotificationContent()
content.title = "Notification"
content.body = "You just Received a notification!"
content.sound = UNNotificationSound.default()

let request = UNNotificationRequest(identifier: "textNotification", content: content, trigger: trigger)


UNUserNotificationCenter.current().add(request) {(error) in
    if let error = error {
        print("Error")
    }
}
}

В представленииDidLoad:

UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) {(accepted, error) in
    if !accepted {
        print("Error")
    }
}

Этот код отлично работает, если пользователь выбирает дату с помощью datePicker, но я не могу понять, как программно установить дату уведомления на ту же дату, что и в локальном уведомлении (2017-28-01 11:00) , а также как сделать так, чтобы уведомление срабатывало каждую неделю в одно и то же время, так как нет свойства repeatInterval.


person Ryan Hampton    schedule 28.01.2017    source источник
comment
как сделать так, чтобы уведомление срабатывало каждую неделю в одно и то же время: stackoverflow.com/a/40856269/341994   -  person matt    schedule 28.01.2017
comment
Спасибо. Не могли бы вы объяснить, как вы могли указать только, например, понедельник в 11:00? Я не совсем понимаю, как вы могли бы передать эту информацию только в переменную.   -  person Ryan Hampton    schedule 28.01.2017
comment
компоненты даты с часом 11 и днем ​​недели 2   -  person matt    schedule 28.01.2017


Ответы (1)


Не могли бы вы объяснить, как вы могли указать только, например, понедельник в 11:00

Это просто вопрос исключения всего, что не относится к повторяющемуся значению. Таким образом, в вашем случае вы хотите указать компоненты даты hour:11 и weekday:2 и ничего больше.

Чтобы понять, как это работает, запустите это на игровой площадке:

let dc = DateComponents(hour:11, weekday:2)
let greg = Calendar(identifier: .gregorian)
let d = greg.nextDate(after: Date(), matching: dc, matchingPolicy:.nextTime)

Вы увидите, что d будет в ближайший понедельник в 11:00.

Это именно то, что UNNotificationTrigger будет делать, чтобы выяснить, когда отправлять это уведомление.

Теперь, если вы также установите триггер repeats, вы только что указали каждый понедельник в 11:00.

person matt    schedule 28.01.2017
comment
Спасибо за вашу помощь! - person Ryan Hampton; 28.01.2017