كيفية الاستيلاء على موعد الحريق التالي من كائن UilocalNotification
-
29-09-2019 - |
سؤال
لدي كائن UilocalNotification الذي قمت بإعداده مع فترات متكررة اليوم والأسبوع والشهر. لا أواجه أي مشاكل على الإطلاق في الوصول إلى تاريخ نيران الكائن:
[cell.detailTextLabel setText:[notification1.fireDate description]];
لكنني أواجه مشاكل في الحصول على تاريخ الحريق التالي. إذا قمت بطباعة كائن Notification1 أعلاه إلى وحدة التحكم ، أحصل على هذا:
<UIConcreteLocalNotification: 0x613e060>{fire date = 2010-11-29 03:53:52 GMT, time zone = America/Denver (MST) offset -25200, repeat interval = 16, next fire date = 2010-11-30 03:53:52 GMT}
يحتوي هذا الكائن على القيمة أو البيانات التي أحتاجها لعرض تاريخ الحريق التالي ... لكن لا يمكنني العثور عليها! هل يعرف أي شخص أين يمكنني الحصول عليه برمجياً؟
شكرًا
المحلول
لا أعتقد أن تاريخ الحريق التالي متاح كعقار ولكنه محسوب من fireDate
و repeatInterval
. يمكن أن يكون حساب التاريخ صعبًا مع مناطق زمنية مختلفة وغيرها من الأشياء السيئة. في المثال الخاص بك ، اخترت تكرارًا يوميًا ولحساب تاريخ الحريق التالي ، يمكنك القيام بشيء على غرار:
NSCalendar *calendar = localNotif.repeatCalendar;
if (!calendar) {
calendar = [NSCalendar currentCalendar];
}
NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease];
components.day = 1;
NSDate *nextFireDate = [calendar dateByAddingComponents:components toDate:localnotif.fireDate options:0];
إذا كنت تستخدم فترة تكرار أخرى ، فسيتعين عليك تغيير الرمز وفقًا لذلك. إذا كنت ستستخدم NSMonthCalendarUnit
سيكون عليك استخدام components.month = 1
في حين أن.
نصائح أخرى
لحساب التالي تاريخ النار لتكرار UILocalNotification
, ، عليك أن:
- اكتشف مقدار
repeatInterval
كان هناك بين تاريخ الحريق الأصلي للإخطار (أي أنهfireDate
الممتلكات) والآن. - أضفها إلى الإخطار
fireDate
.
هنا نهج واحد:
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
NSDateComponents *difference = [calendar components:notif.repeatInterval
fromDate:notif.fireDate
toDate:[NSDate date]
options:0];
NSDate *nextFireDate = [calendar dateByAddingComponents:difference
toDate:notif.fireDate
options:0];
يعمل هذا في العديد من السيناريوهات ، ولكن إليك سيناريو لا يعمل فيه:
لنفترض أن:
- الإخطار `FireDate هو 01/01 في الساعة 2:00 مساءً
- الإخطار
repeatInterval
هوNSDayCalendaryUnit
(أي كرر يوميا) - التاريخ الآن هو 08/01 في الساعة 3:00 مساءً
سيحسب الرمز أعلاه الفرق إلى 7 أيام (01/01 + 7 أيام = 08/01) ، أضفه إلى fireDate
, ، وبالتالي ضبط nextFireDate
إلى 08/01 في الساعة 2 مساءً. لكن هذا في الماضي ، نريد nextFireDate
أن تكون 09/01 في الساعة 2 مساءً!
لذلك إذا كنت تستخدم الرمز أعلاه و repeatInterval
هو NSDayCalendaryUnit
, ، ثم أضف هذه الخطوط:
if ([nextFireDate timeIntervalSinceDate:[NSDate date]] < 0) {
//next fire date should be tomorrow!
NSDateComponents *extraDay = [[NSDateComponents alloc] init];
extraDay.day = 1;
nextFireDate = [calendar dateByAddingComponents:extraDay toDate:nextFireDate options:0];
}
لقد حددت هذه الإجابة على أنها ويكي المجتمع ، لا تتردد في تحريرها إذا وجدت طريقة أفضل للقيام بالحساب!
أود فقط إضافة REPERINTERVAL حتى يكمن التاريخ في المستقبل:
-(NSDate*)nextFireDateForNotification:(UILocalNotification*)notification {
NSCalendar *calendar = notification.repeatCalendar;
if (!calendar) {
calendar = [NSCalendar currentCalendar];
}
NSDate* date = [notification.fireDate copy];
while (date.timeIntervalSinceNow > 0) {
date = [calendar dateByAddingUnit:notification.repeatInterval value:1 toDate:date options:0];
}
return date;
}
في هذا سريع 4 واستخدام التقويم nextDate
Func.
extension UILocalNotification {
var nextFireDate: Date? {
guard let fireDate = fireDate else { return nil }
let today = Date()
let cal = Calendar.current
if fireDate.compare(today) == .orderedDescending {
return fireDate
}
let s: Set<Calendar.Component>
switch repeatInterval {
case .year: s = [.month, .day, .hour, .minute, .second]
case .month: s = [.day, .hour, .minute, .second]
case .day: s = [.hour, .minute, .second]
case .hour: s = [.minute, .second]
case .minute: s = [.second]
default: return nil // Not supporting other intervals
}
let components = cal.dateComponents(s, from: fireDate)
return cal.nextDate(after: today, matching: components, matchingPolicy: .nextTimePreservingSmallerComponents)
}
}