Подтвердить что ты не робот

Обновлен номер значка iOS

Я создал пользовательский календарь для iOS, и я пытаюсь использовать номер значка, чтобы показать номер дня, но цифры не менялись после одного дня, я имею в виду, что они должны обновляться, вот мой код: я нужно что-то вроде приложения с погодой, это приложение не отправляет никаких push-сообщений!

    int a = [DateComponents showDay];
    [UIApplication sharedApplication].applicationIconBadgeNumber = a ;
4b9b3361

Ответ 1

В iOS это нелегко сделать. Вы можете приблизиться, но не обновлять значок надежно каждый день, если пользователь не откроет приложение время от времени.

Вам нужно использовать UILocalNotification. Вы можете создавать и планировать "молчаливое" уведомление, которое обновляет значок приложения без предупреждения пользователя или воспроизведения звукового сигнала, подобного этому:

UILocalNotification* notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:seconds];
notification.timeZone = [NSTimeZone systemTimeZone];
notification.alertBody = nil;
notification.soundName = nil;
notification.applicationIconBadgeNumber = dayTomorrow;

[[UIApplication sharedApplication] scheduleLocalNotification:notification];
[notification release];

где dayTomorrow - это int завтрашнего дня месяца. и seconds - некоторый временной интервал - это может быть что-то вроде интервала до полуночи. Когда это уведомление будет доставлено, для пользователя не будет никаких предупреждений или звуков, но значок приложения должен быть обновлен до нового значения. Вы можете сделать это уведомление повторяющимся каждый день, используя свойство repeatInterval, но проблема здесь заключается в том, что на следующий день вам нужно изменить dayTomorrow на другое значение и снова на следующий день. Но повторное оповещение всегда будет иметь такое же значение в applicationIconBadgeNumber.

Таким образом, я думаю, что единственный способ достичь чего-либо, близкого к тому, что вы хотите, - запланировать кратное из этих локальных уведомлений - вы можете запланировать до 64 заранее - каждый день в день, и каждый с этим значением дня, установленным как applicationIconBadgeNumber. Они должны быть не повторяющимися, поэтому убедитесь, что вы установили repeatInterval в nil (или не устанавливаете его, поскольку значение nil является значением по умолчанию). Предполагая, что все эти уведомления будут надежно доставлены iOS, вы сможете без проблем обновить номер значка и не беспокоить пользователя до 64 дней. После этого значок перестанет обновляться... , если вам не удастся запланировать больше уведомлений, то есть когда пользователь откроет приложение. Что вы можете попробовать сделать, это отменить все существующие запланированные уведомления при запуске приложения:

[[UIApplication sharedApplication] cancelAllLocalNotifications];

а затем пройдите через 64 ​​дня вперед, планируя уведомление за полночь каждый день с правильным днем ​​месяца для свойства applicationIconBadgeNumber. Пока пользователь открывал ваше приложение не реже одного раза в 64 дня, вы сохранили бы значок значка в актуальном состоянии. Если вы планируете, чтобы пользователи приложения открывали приложение часто (например, несколько раз в день), тогда оптимизация может заключаться в проверке количества запланированных уведомлений перед их отменой и создании 64 новых, например:

if ([[[UIApplication sharedApplication] scheduledLocalNotifications] count] < 10)
{
    //there are 10 or fewer days' worth of notifications scheduled, so create and
    //schedule more here, up to 64 in total.
}

Несколько других замечаний:

  • Я не уверен, насколько надежны локальные уведомления. Push-уведомления не гарантируются, но я надеюсь и ожидаю, что локальные уведомления будут доставлены. например если телефон выключен в полночь и включен только в 7 утра, я надеюсь, что местное уведомление, запланированное на полночь, будет немедленно доставлено. Но я никогда не тестировал это.
  • Если ваше приложение открыто при отправке запланированного уведомления, вызывается application:didReceiveLocalNotification:, но значок значка не будет обновляться. Поэтому, чтобы удовлетворить этот случай, я предлагаю обновить значок значка до текущего дня каждый раз, когда приложение запускается (или возвращается на передний план из фона).
  • Не уверен, что Apple сделает это использование значка значка. При рассмотрении вашего приложения они могут почувствовать, что это запутывает пользователя, поскольку он обычно используется для указания количества элементов новых/измененных данных в приложении. Поэтому ваше приложение может быть отклонено для этого.
  • В идеале Apple предоставит API для разработчиков, чтобы предоставить такую ​​информацию "с первого взгляда" пользователю, независимо от того, что достигнуто путем изменения значка/значка приложения каким-то образом или виджетами и т.д. Что я описанный выше, должен работать, но, очевидно, является небольшим количеством kludge, чтобы обойти текущие ограничения iOS. Встроенное приложение для календаря меняет свой значок каждый день, чтобы показать день месяца, и я вижу, что многие приложения могут извлечь выгоду из этого поведения - например. приложение погоды может отображать значок погодных условий в текущем местоположении.

EDIT:

Здесь фрагмент кода для отмены любых существующих локальных уведомлений и расписания 64 в будущем в полночь и с правильным днем ​​месяца, указанным в качестве номера значка:

[[UIApplication sharedApplication] cancelAllLocalNotifications];

NSCalendar* calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents* components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]];

[components setHour:0];
[components setMinute:0];
[components setSecond:0];

NSDate* midnightToday = [calendar dateFromComponents:components];

const int SECONDS_PER_DAY = 60 * 60 * 24;

for (int i = 1; i <= 64; i++)
{
    NSDate* futureDate = [midnightToday dateByAddingTimeInterval:i * SECONDS_PER_DAY];
    NSDateComponents* components = [calendar components:NSDayCalendarUnit fromDate:futureDate];

    UILocalNotification* notification = [[UILocalNotification alloc] init];
    notification.fireDate = futureDate;
    notification.timeZone = [NSTimeZone systemTimeZone];
    notification.alertBody = nil;
    notification.soundName = nil;
    notification.applicationIconBadgeNumber = components.day;

    //NSLog(@"futureDate: %@", [NSDateFormatter localizedStringFromDate:futureDate dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle]);
    //NSLog(@"notification: %@", notification);        

    [[UIApplication sharedApplication] scheduleLocalNotification:notification];
    [notification release];
}

[calendar release];

Что здесь происходит:

  • Мы принимаем сегодня дату с [NSDate date], а затем разбиваем на компоненты, которые хотим сохранить (год, месяц, день), а затем устанавливаем компоненты времени (час, минута, секунда) на полночь. Это дает нам midnightToday.
  • Мы пробиваем 64 раза, каждый раз создавая новую дату, которая будет от 1 до 64 дней в будущем, принимая midnightToday и добавляя количество секунд в день, умноженное на сколько дней в будущем мы хотим дата будет. Мы используем эту дату для планирования локального уведомления.
  • Нам также нужно определить день месяца для номера значка. Поэтому мы снова используем NSDateComponents, чтобы разбить будущую дату на интересующие нас компоненты, которые в этом случае являются только днем, поэтому мы указываем NSDayCalendarUnit. Затем мы можем установить applicationIconBadgeNumber как components.day
  • Каждое из 64 уведомлений запланировано с помощью UIApplication, которое будет отправлено от 1 до 64 дней в будущем.

Обратите внимание, что это, вероятно, будет работать только для пользователей, которые используют календарь григорианского (западного стиля) - в зависимости от вашего рынка вам может потребоваться рассмотреть другие типы календарей, которые используются во всем мире, и поддерживать их также.

Ответ 2

Вы должны иметь возможность сделать это с помощью UILocalNotification

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

http://developer.apple.com/library/IOs/#documentation/iPhone/Reference/UILocalNotification_Class/Reference/Reference.html

Ответ 3

Как и где вы вызываете этот метод? Если вы установите таймер для запуска этого кода каждые x секунд, он будет обновляться при следующем срабатывании таймера.