質問

繰り返し間隔で日、週、月にセットアップされている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}

このオブジェクトには、次の火災日を表示するために必要な値またはデータが含まれています...しかし、私はそれを見つけることができません!誰かが私がプログラムでそれをどこで手に入れることができるか知っていますか?

ありがとう

役に立ちましたか?

解決

次の火災日は不動産として利用できるとは思わないが、むしろ計算された fireDaterepeatInterval. 。日付の計算は、異なるタイムゾーンや他の厄介なもので難しい場合があります。あなたの例では、毎日の繰り返しを選択し、次の火災日を計算するために、次の点に沿って何かをすることができます。

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, 、 必ず:

  1. の量を把握します repeatInterval 通知の元の火災日の間にありました(つまり、 fireDate プロパティ)そして今。
  2. それらを通知に追加します fireDate.

これが1つのアプローチです。

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は午後2時に01/01です
  • 通知 repeatIntervalNSDayCalendaryUnit (つまり、毎日繰り返します)
  • 日付は午後3時に08/01です

上記のコードは、差を7日間(01/01 + 7日= 08/01)に計算し、に追加します fireDate, 、したがって設定されます nextFireDate08/01午後2時. 。しかし、それは過去です、私たちは望んでいます nextFireDate することが 09/01午後2時!

したがって、上記のコードとあなたを使用する場合 repeatIntervalNSDayCalendaryUnit, 、次に、これらの行を追加します。

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];
}

この答えをコミュニティウィキとしてマークしました。計算を行うためのより良い方法が見つかった場合は、お気軽に編集してください!

日付が将来的になるまで、repeaterintervalを追加するだけです。

-(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;
    }

これがあります Swift 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)
    }

}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top