2013-05-09 60 views
6

Dường nhưphát hiện UILocalNotifications không được thừa nhận

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

didReceiveLocalNotification:(UILocalNotification *)notification

chỉ được kích hoạt nếu người dùng thừa nhận UILocalNotification, ví dụ bằng cách trượt thanh trượt hoặc chạm vào mục trong của iOS Kéo xuống thông báo.

Có cách nào để thông báo rằng UILocalNotification đã tắt nếu người dùng bỏ qua UILocalNotification và nhập lại ứng dụng bằng cách chỉ cần nhấp vào biểu tượng ứng dụng?

Tôi nên đề cập rằng điều này thực sự chỉ áp dụng cho các thông báo lặp lại vì việc phát hiện các thông báo không lặp lại có thể được phát hiện bằng cách quan sát tổng số. Đó là, khi họ bắn, biến mất từ ​​[[UIApplication sharedApplication] scheduledLocalNotifications].

Tôi đang tìm một cái gì đó giống như ..

[[UIApplication sharedApplication] unacknowledgedLocalNotifications]

Than ôi, tôi không thể tìm thấy bất cứ điều gì giống như nó.

+0

Nếu thông báo của bạn là * không * trong 'scheduledLocalNotifications', nó không còn được lên lịch vì vậy nó phải được kích hoạt. – matt

+0

'vừa chỉnh sửa câu hỏi. Tôi thực sự đã có văn bản trong đó nhưng muốn giữ mọi thứ đơn giản như tôi có thể (nghĩa là ít văn bản hơn). –

+3

Tôi có cảm giác rằng những gì bạn muốn không tồn tại, nhưng điều này sẽ tạo ra một yêu cầu tính năng * tuyệt vời * với phóng viên lỗi của Apple. – matt

Trả lời

5

Vâng, bạn có thể kiểm tra thông báo đã lên lịch bên trong [[UIApplication sharedApplication] scheduledLocalNotifications]. Để tìm hiểu xem thông báo lặp lại đã lên lịch có kích hoạt truy cập thuộc tính fireDate để xem ngày bắt đầu được đặt cho thông báo hay không. Sau đó kiểm tra thuộc tính repeatInterval.

Vì vậy, bạn có 2 biến, một là NSDate ban đầu, cho phép nói 2013-05-08 12:00 và thứ hai là khoảng thời gian lặp lại, cho phép nói hàng ngày. Và bằng cách thực hiện [NSDate date], bạn sẽ nhận được ngày hiện tại mà tôi đang ở (tại Thụy Điển) hiện là 2013-05-09 22:45. Điều này có nghĩa là có một thông báo mà người dùng chưa thực hiện.

Vì vậy, bạn sẽ cần phải tạo một phương thức sẽ lấy các đối số này và sau đó lặp lại từ ngày đầu tiên để xem có bao nhiêu thông báo đã bị bỏ lỡ cho đến ngày giờ hiện tại.

Bạn sẽ tìm thấy NSCalendar s dateByAddingComponents:toDate:options hữu ích.

+0

Sự thật được nói, tôi đang trong quá trình thực hiện điều này và nghĩ rằng Apple _had_ đã thực hiện việc này để cứu tôi một loạt các dòng. Cảm ơn! –

+0

Tôi cũng vậy, rất tiếc bạn phải tự mình thực hiện. Đó là một công việc nhỏ nhưng nó làm việc ra độc đáo. –

+0

Bất kỳ lý do nào bạn đang sử dụng NSCalendars và Components và không chỉ đơn giản là NSDate timeIntervalSinceNow? Vì vậy, bạn có thể như vậy một cái gì đó như 'cho (UILocalNotification * uiln trong [[UIApplication sharedApplication] scheduleLocalNotifications]) {if ([uiln.fireDate timeIntervalSinceNow] <0) // làm một số công cụ}' –

2

Mọi người đều có khả năng kể từ khi tiếp tục, nhưng tôi muốn chia sẻ giải pháp của mình cho vấn đề này. (Xin lỗi về các tên biến dài ...)

Ý tưởng rất đơn giản: luôn giữ cho fireDate trong tương lai.

didFinishLaunchingWithOptions thời gian -every hoặc didReceiveLocalNotification được gọi, chỉ cần hủy bỏ thông báo hiện tại của bạn và sắp xếp lại một cái mới với một fireDate một đơn vị khoảng thời gian trong tương lai

-Khi ra mắt ứng dụng của bạn lặp qua tất cả các thông báo lịch trình, nếu fireDate không phải trong tương lai bạn biết rằng nó đã bị bỏ qua

Trong trường hợp của tôi, thông báo có khoảng thời gian lặp lại hàng tuần.đầu tiên tôi sắp xếp lại bất kỳ thông báo được thừa nhận trong didFinishLaunchingWithOptions:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    UILocalNotification* localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; 

    if (localNotif != nil) 
    { 
     [NotificationsHelper rescheduleNotification:localNotif]; 
    } 
} 

Và cũng trong didReceiveLocalNotification:

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *) notification 
{ 
    [NotificationsHelper rescheduleNotification:notification]; 
} 

Tại App Launch tôi rà soát tất cả các thông báo cho bất kỳ với một fireDate trong quá khứ:

- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
    [self checkLocalNotifications:application]; 
} 

Mã cho hàm "checkLocalNotifications" của tôi:

- (void) checkLocalNotifications:(UIApplication *) application 
{ 
    UIApplication* app  = [UIApplication sharedApplication]; 
    NSArray*  eventArray = [app scheduledLocalNotifications]; 

    for (int i = 0; i < [eventArray count]; i++) 
    { 
     UILocalNotification* notification = [eventArray objectAtIndex:i]; 

     if ([NotificationsHelper wasWeeklyRepeatingNotificationIgnored:notification]) 
     { 
      [NotificationsHelper rescheduleNotification:notification]; 

      NSLog(@"NotificationWasIgnored: %@ %@",notification.alertAction, notification.alertBody); 
     } 
    } 
} 

Mã cho tôi chức năng "wasWeeklyRepeatingNotificationIgnored":

+ (BOOL) wasWeeklyRepeatingNotificationIgnored:(UILocalNotification*) the_notification 
{ 
    BOOL result; 
    NSDate* now = [NSDate date]; 

    // FireDate is earlier than now 
    if ([the_notification.fireDate compare:now] == NSOrderedAscending) 
    { 
     result = TRUE; 
    } 
    else 
    { 
     result = FALSE; 
    } 

    return result; 
} 

Mã cho tôi chức năng "rescheduleNotification":

+ (void) rescheduleNotification:(UILocalNotification*) the_notification 
{ 
    UILocalNotification* new_notification = [[UILocalNotification alloc] init]; 

    NSMutableDictionary* userinfo = [[NSMutableDictionary alloc] init]; 

    [new_notification setUserInfo:userinfo]; 
    [new_notification setRepeatInterval:the_notification.repeatInterval]; 
    [new_notification setSoundName:UILocalNotificationDefaultSoundName]; 
    [new_notification setTimeZone:[NSTimeZone defaultTimeZone]]; 
    [new_notification setAlertAction:the_notification.alertAction]; 
    [new_notification setAlertBody:the_notification.alertBody]; 
    [new_notification setRepeatCalendar:[NSCalendar currentCalendar]]; 
    [new_notification setApplicationIconBadgeNumber:the_notification.applicationIconBadgeNumber]; 

    NSCalendar*  gregorian   = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 
    NSDateComponents* weekdayComponents = [gregorian components:NSWeekdayCalendarUnit 
                 fromDate:the_notification.fireDate]; 

    NSInteger weekday = [weekdayComponents weekday]; 
    NSDate* next_week = [self addDay:weekday toHourMinute:the_notification.fireDate]; 

    [new_notification setFireDate:next_week]; 

    [[UIApplication sharedApplication] scheduleLocalNotification:new_notification]; 
    [[UIApplication sharedApplication] cancelLocalNotification:the_notification]; 
} 
+0

Một lần nữa, điều này sẽ chỉ làm việc với UILN lặp lại vì nếu không, UILN sẽ không tồn tại trong hệ thống. Tức là, iOS sẽ xóa các UILN không lặp lại có khả năng kích hoạt. –

+0

Ngẫu nhiên, không bao giờ xin lỗi về tên biến dài .. IMHO, nó waaay tốt hơn để vượt qua như thế nào mô tả tên của bạn. Và mã đẹp. –

0

Nếu UILocalNotifications của bạn tăng số huy hiệu biểu tượng ứng dụng (ví dụ: số trong vòng tròn màu đỏ ở phía trên bên phải của biểu tượng của ứng dụng), sau đó là một ridiculously đơn giản cách để kiểm tra cho UILocalNotifications không được thừa nhận: chỉ cần kiểm tra những gì hiện applicationIconBadgeNumber là:

- (void)applicationWillEnterForeground:(UIApplication *)application 
{   
    int unacknowledgedNotifs = application.applicationIconBadgeNumber; 
    NSLog(@"I got %d unacknowledged notifications", unacknowledgedNotifs); 
    //do something about it... 

    //You might want to reset the count afterwards: 
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; 

} 
+0

huy hiệu không thay đổi nếu người dùng loại bỏ thông báo từ khay. – Maq