2017-06-04 1 views
0

iOSのローカル通知に重大な問題があります。私はObjective-Cで書かれたアプリを持っています。これは、通知が発生した時刻だけでなく、指定された時刻に指定された日に毎週火曜日に曜日を選択できるようにします。通知が発生した時刻に問題はありませんが、正しく動作します。しかし、その日を指定すると、奇妙なことが起こります。最初は、一度だけ発射されますが、指定された日数ではなく毎日発射されます。それから、最初の1週間後に、彼らは毎日火を放ちますが、1回だけではありません。代わりに、日数が指定された回数だけ起動します(日曜日、月曜日、火曜日が選択されると、毎日、指定した時刻に3回連続して通知されます)。予定されているローカル通知が不規則です

これは私が通知を設定するために使用しているコードです。

「保存」ボタンをタップすると、最初に起こるのは、新しいもののために、すべて通知をクリアすることです。

//cancels all notifications upon save 
[[UIApplication sharedApplication] cancelAllLocalNotifications]; 

次に、私は

NSDate *now = [NSDate date]; 
NSCalendar *calendar = [NSCalendar currentCalendar]; 
NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitWeekOfYear|NSCalendarUnitWeekday|NSCalendarUnitHour|NSCalendarUnitMinute fromDate:now];//get the required calendar units 
(一日の時間を選択するために使用されている)現在の時間のための仕様だけでなく、私のUIPickerからコンポーネントを取得するにはNSDate、NSCalendarとNSCalendarComponentsを使用


次に、UIPickerから時刻の単位と実際の時刻をピッカーから取得します。

NSDateComponents *pickedComponents = [calendar components:(NSCalendarUnitHour | NSCalendarUnitMinute) fromDate:picker.date]; 
NSDate *minuteHour = [calendar dateFromComponents:pickedComponents]; 
[[NSUserDefaults standardUserDefaults] setObject:minuteHour forKey:@"FireTime"]; 


はその後、私は通知

NSString *reminder = @"Reminder text!"; 

次の通知の実際の設定であるに表示するテキストを設定します。それらはすべて同じです(もちろん、曜日は変更されています)ので、私は日曜日のものだけを表示します。

//sunday 
UILocalNotification *localNotificationSunday = [[UILocalNotification alloc] init]; 
if ([sundayTempStatus isEqual:@"1"]) 
{ 

    //permanently save the status 
    [[NSUserDefaults standardUserDefaults] setObject:@"1" forKey:@"Sunday"]; 

    //set up notifications 
    //if it is past sunday, push next week 
    if (components.weekday > 1) 
    { 
     components.day = components.day + 7; //if already passed sunday, make it next sunday 
    } 

    //components.day = 1; 
    components.hour = [pickedComponents hour]; 
    components.minute = [pickedComponents minute]; 

    NSDate *fireDate = [calendar dateFromComponents:components]; 

    localNotificationSunday.fireDate = fireDate; 
    localNotificationSunday.alertBody = reminder; 
    localNotificationSunday.timeZone = [NSTimeZone systemTimeZone]; 
    localNotificationSunday.repeatInterval = NSCalendarUnitWeekOfYear; 
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotificationSunday]; 
} 
else 
{ 
    [[NSUserDefaults standardUserDefaults] setObject:@"0" forKey:@"Sunday"]; 
} 


すべてのヘルプは大歓迎され、そして任意の追加情報やコードが必要な場合、私は喜んでそれを提供します。

答えて

1

コードが繰り返しになると、エラーが発生しやすくなります。私はリマインダのスケジューリングを考慮する必要がある簡単な方法を書いてきました。

- (void)scheduleNotificationForDayOfWeek:(int)dayOfWeek withPickedComponents:(NSDateComponents *)pickedComponents andReminderString:(NSString *)reminderString { 
    NSCalendar *calendar = [NSCalendar currentCalendar]; 
    UILocalNotification *notification = [[UILocalNotification alloc] init]; 

    NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitWeekOfYear|NSCalendarUnitWeekday|NSCalendarUnitHour|NSCalendarUnitMinute fromDate:[NSDate date]]; 
    components.hour = [pickedComponents hour]; 
    components.minute = [pickedComponents minute]; 

    NSDateComponents *additionalComponents = [[NSDateComponents alloc] init]; // to be added onto our date 
    if ([components weekday] < dayOfWeek) { 
     additionalComponents.day = (dayOfWeek - [components weekday]); // add the number of days until the next occurance of this weekday 
    } else if ([components weekday] > dayOfWeek) { 
     additionalComponents.day = (dayOfWeek - [components weekday] + 7); // add the number of days until the next occurance of this weekday 
    } 

    NSDate *fireDate = [calendar dateFromComponents:components]; 
    fireDate = [calendar dateByAddingComponents:additionalComponents toDate:fireDate options:0]; // add on our days 

    notification.fireDate = fireDate; 
    notification.alertBody = reminderString; 
    notification.timeZone = [NSTimeZone systemTimeZone]; 
    notification.repeatInterval = NSCalendarUnitWeekOfYear; 
    [[UIApplication sharedApplication] scheduleLocalNotification:notification]; 
} 

これは実際にはかなり簡単です。曜日(たとえば、0 =日曜日、1 =月曜日)で呼び出すと、その日の繰り返しリマインダーがスケジュールされます。あなたの日曜日のコードで私のテストであなたの問題を再現することができなかったので、私はそのコードを繰り返すうちのどこかでエラーを起こさなければならないと考えました。

この方法では、発射日の取得が簡略化されています。 NSDateComponentsを使用して、その曜日の次の発生を簡単に取得します。これは、[self scheduleNotificationForDayOfWeek:0 withPickedComponents:pickedComponents andReminderString:@"Hello, world!"];(毎週日曜日に指定されたコンポーネントで「Hello、world!」と表示されます)

このスニペットを使用すると、コード内の繰り返し文のほとんどを取り除くことができます。設定通知の仕方私にとっては、これは完全に機能しました。

関連する問題