Възможно ли е да има условна `firedate` за UILocalNotification?

Опитвам се да имам условно време за пожар за моите локални известия, но когато опитах тези два начина, не се провали, но пак не работи. И така, чудех се дали мога да направя такова нещо?

Забележка: startTime и endTime са времена от инструменти за избор на дата.

-(void) TEST {

NSCalendar *calendar = [NSCalendar currentCalendar];
calendar.timeZone = [NSTimeZone timeZoneWithName:@"GMT"];

NSDateComponents *components = [calendar components:NSHourCalendarUnit fromDate:[NSDate date]];
components.hour   = 3;
components.minute = (components.minute + 1) % 60;
components.second = 57;

NSDate *fire = [calendar dateFromComponents:components];
UILocalNotification *notif = [[UILocalNotification alloc]  init] ;
if (notif == nil)
    return;

if (fire < startTime.date) {


notif.fireDate =fire ;
    notif.repeatInterval= NSMinuteCalendarUnit ;
    notif.alertBody = [NSString stringWithFormat: @"You are missed!"] ;
    [[UIApplication sharedApplication] scheduleLocalNotification:notif] ;


    }

if (fire > endTime.date) {


    notif.fireDate =fire ;
    notif.repeatInterval= NSMinuteCalendarUnit ;
    notif.alertBody = [NSString stringWithFormat: @"You are missed!"] ;
    [[UIApplication sharedApplication] scheduleLocalNotification:notif] ;


}}

ИЛИ

-(void) TEST {

NSCalendar *calendar = [NSCalendar currentCalendar];
calendar.timeZone = [NSTimeZone timeZoneWithName:@"GMT"];

NSDateComponents *components = [calendar components:NSHourCalendarUnit fromDate:[NSDate date]];
components.hour   = 3;
components.minute = (components.minute + 1) % 60;
components.second = 57;

NSDate *fire = [calendar dateFromComponents:components];
UILocalNotification *notif = [[UILocalNotification alloc]  init] ;
if (notif == nil)
    return;

if (fire > startTime.date & fire < endTime.date) {

    [[UIApplication sharedApplication] cancelAllLocalNotifications] ;
}

else {
    notif.fireDate =fire ;
    notif.repeatInterval= NSMinuteCalendarUnit ;
    notif.alertBody = [NSString stringWithFormat: @"You are missed!"] ;
    [[UIApplication sharedApplication] scheduleLocalNotification:notif] ;


}}

Благодаря

Ако не, какъв би бил най-лесният начин да направите такова условие?


person user1949873    schedule 05.05.2013    source източник
comment
Записахте ли датата на пожара? Ако използвате минутата от компонента, трябва да заредите минутата, когато получавате компонента от календара + дата (NSMinuteCalendarUnit).   -  person Wain    schedule 05.05.2013
comment
Да, регистрирах го и никога не влиза в условието if   -  person user1949873    schedule 05.05.2013
comment
Опитайте if ([fire timeIntervalSinceDate:startTime.date] >= 0) // fire is before start.   -  person    schedule 07.05.2013
comment
@relikd Благодаря, но все още не работи! :/   -  person user1949873    schedule 08.05.2013
comment
@Bonnie нито един от отговорите ви не проработи и предполагам, че няма решения за такова нещо, тъй като така или иначе не можах да намеря за извършване на анулиране на известия в определено време, докато е във фонов режим. Въпреки това, вие заслужавате 100 точки за вашата упорита работа. Благодаря ви.   -  person user1949873    schedule 13.05.2013
comment
благодаря, приятелю, удоволствие е, но ако някога намериш нещо, публикувай го тук.   -  person Bonnie    schedule 13.05.2013


Отговори (2)


използвайте метода NSDate Compare: вместо if(fire > startTime.date)

if([fire compare: startTime.date] == NSOrderedDescending) // if start is later in time than end
{
    // do something
}

От препратката към класа:

If:
The receiver and anotherDate are exactly equal to each other, NSOrderedSame.
The receiver is later in time than anotherDate, NSOrderedDescending.
The receiver is earlier in time than anotherDate, NSOrderedAscending.

така че за вашето състояние

if (fire > startTime.date & fire < endTime.date) {

    [[UIApplication sharedApplication] cancelAllLocalNotifications] ;
}

можеш да използваш

if([fire compare: startTime.date] == NSOrderedDescending && [fire compare: endTime.date]== NSOrderedAescending)
{
   [[UIApplication sharedApplication] cancelAllLocalNotifications] ;
}

това ще отмени всички локални известия, ако пожарът е между избраната начална и крайна дата

else {
// Fire the notifications
}

също така погледнете връзката, това е подобно на това, от което се нуждаете връзка

person Bonnie    schedule 07.05.2013
comment
за съжаление, известието все още се задейства и не е отменено!! Чух, че не можете да имате ограничения върху UILocalNotification вярно ли е? - person user1949873; 08.05.2013
comment
моля, кажете какво точно трябва да направите и какво не работи, моето предположение: startTime и EndTime е времето, между което u известията няма да се задействат.? нали.?? според този код, ако fireDate е между началния и крайния час, известието няма да бъде създадено, така че няма възможност то да се задейства. Искате ли просто да анулирате всички вече създадени известия, които попадат във времевата рамка на DoNotDisturb.?? или просто не искате потребителят да разреши създаването на нова UILocalnotication между времевата рамка на DoNotDisturb - person Bonnie; 08.05.2013
comment
Вашите предположения са правилни. Искам да отменя известията между началния и крайния час. И така, този код ще може ли да отмени AllLocalNotifications във фонов режим, когато вече е планиран? Защото пробвах и не се получи! - person user1949873; 08.05.2013
comment
Ето сценария, имам локално известие, което е планирано за повтарящ се интервал на всеки час. Искам, когато потребителят избере startTime и endTime, тези известия да спрат автоматично през нощта и да се насрочат отново, без да е необходимо да отваряте приложението. Как мога да направя това? Възможно ли е с този код? - person user1949873; 08.05.2013
comment
няма директен начин да направите това, но погледнете това stackoverflow.com/questions/15773544/ точно това, от което се нуждаете - person Bonnie; 08.05.2013
comment
Това всъщност беше въпросът ми, но когато се опитах, не можах да го накарам да работи, защото имам повтарящо се известие с 24-часов интервал и той ме моли да го направя ежедневен интервал за повторение. Ако няма прав път, тогава как да го направите? Имайки предвид, че трябва да пускам известие на всеки 5 минути. - person user1949873; 08.05.2013

това, което ще се опитам да направя, е, когато времето за заспиване започне, да извикам метод, напр.: goingToSleep:, можете да използвате dispatch_later или performSelector:withObject:afterDelay: за това,

in goingToSleep:

NSArray* localNotifications = [[UIApplication sharedApplication] 
                                              scheduledLocalNotifications];
for (UILocalNotification *notification in localNotifications)
{
    if([fire compare: startTime.date] == NSOrderedDescending &&
       [fire compare: endTime.date]== NSOrderedAescending)
    {

Това е важната част

  • вземете всички свойства на известието
  • създайте NSDictionary на тези свойства
  • Добавете NSDictionary към масив
  • и запазете този масив в plist.(Запазване на масив в Plist)

  • и след това отменете това известие с помощта на

    [[UIApplication sharedApplication] cancelLocalNotification:notification];
    }
    

}

след това, след като SleepTime приключи, отново извикайте метод, напр.: wakingUp:

след това в wakingUp:

  • прочетете масива от NSDictionary, който запазихме.
  • отново Създайте UILocalnotifications, като използвате същите тези свойства.

по този начин никакви UILocalNotifications няма да се задействат по време на заспиване. един проблем може да бъде изпълнението на тези методи, ако приложението не е памет.

РЕДАКТИРАНЕ За да имате дълго работещи приложения.

person Bonnie    schedule 10.05.2013
comment
Благодаря ви много, кодът проработи частично. Опитах свойството за забавяне и то работи, докато приложението работи. Все още обаче се опитвам да разбера Plist, NSDictionary и масивите, за да мога да го накарам да работи на заден план. Имам 2 въпроса: имате ли връзки към урок, който обяснява вашия отговор? Или можете да ме насочите към подробни отговори? - person user1949873; 11.05.2013
comment

Имам формуляр с избор на състояние. Ако е избран определен статус и формулярът е изпратен, той трябва да се презареди и да изисква допълнително поле.

Прочетох Динамично генериране за изпратени формуляри и почти всяка друга публикация в интернет и по тази тема и опитах различни комбинации от събития (и получих различни грешки), но все още се боря да накарам това да работи правилно.

Ето какво имам досега:

FormType

private function addProcessAfterField(FormInterface $form)
{
    $form->add('processAfterDate', 'date', array('required' => true));
}


public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('status', 'entity', array(
        'class' => 'Acme\Bundle\ApplicationBundle\Entity\LeadStatusCode',
        'choices' => $this->allowedTypes
    ));

    $builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event){

        $form = $event->getForm();
        $data = $event->getData();

        if ($data->getStatus()->getId() == LeadStatusCode::INTERESTED_LATER) {
            $this->addProcessAfterField($form);
        }
    });

    $builder->get('status')->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event){
        $data = $event->getData();
        if ($data == LeadStatusCode::INTERESTED_LATER && !$event->getForm()->getParent()->getData()->getProcessAfterDate()) {
            $this->addProcessAfterField($event->getForm()->getParent());
        }
    });

    $builder->add('comment', 'textarea', array('mapped' => false));
    $builder->add('Update', 'submit');
}

грешка:

ContextErrorException: Catchable Fatal Error: Argument 1 passed to Proxies\__CG__\Acme\Bundle\ApplicationBundle\Entity\Lead::setProcessAfterDate() must be an instance of DateTime, null given, called in /var/www/application.dev/vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php on line 360 and defined in /var/www/application.dev/app/cache/dev/doctrine/orm/Proxies/__CG__AcmeBundleApplicationBundleEntityLead.php line 447

Както вече споменах, опитах различни комбинации от събития, едното почти работеше, но след това датата никога не беше запазена в обекта, така че добавих подсказката за тип \DateTime към метода setProcessAfterDate(). Не съм сигурен дали не разбирам правилно системата за събития или грешката е някъде другаде.

- person user1949873; 11.05.2013
comment
За съжаление, performSelctor:withObject:afterDelay няма да работи във фонов режим след първите 10 минути :/ - person user1949873; 11.05.2013
comment
точно... какво имах предвид, когато казах, че един проблем може да бъде изпълнението на тези методи, ако приложението не е памет. т.е. приложението се затваря от OS. намери начин да продължи да работи, публикувах връзка, погледнете другия ми отговор - person Bonnie; 13.05.2013
comment
Защо отговори два пъти? Не трябва да правите това, трябва да актуализирате първоначалния си отговор. - person Popeye; 13.05.2013
comment
Знам това, брато, но трябва да погледнеш въпроса. първият ми отговор беше свързан само с условията, които не работеха според изискванията. и вторият ми отговор беше за наградата. Ако не, какъв би бил най-лесният начин да направя такова условие?. трябваше да публикувам два отговора, защото човек, който посети въпроса по-късно, нямаше да разбере. И не е необходимо винаги да актуализирате предишния отговор, особено ако и двата са напълно различни и правилни. в противен случай Stack Overflow няма да даде възможност за добавяне на два отговора. - person Bonnie; 13.05.2013
comment
Честно казано, приятелю, изглежда, че си отговорил два пъти на въпроса и това е. Няма какво да се каже защо. Може би трябва да включите причината в отговора си. Само мое мнение, зависи от вас дали го включите. Не е много обичайно потребителите да отговарят два пъти, те обикновено актуализират оригиналния отговор и изясняват, че това е редакция и причината за редакцията. - person Popeye; 13.05.2013
comment
ако беше прочел въпроса и и двата отговора бяха правилни, щеше да имаш различно мнение, остави го приятелю, продължи напред. - person Bonnie; 13.05.2013
comment
Току-що прочетох отново въпроса и двата отговора и сега не виждам никаква причина защо това се нуждае от два отговора от вас, това определено можеше да е един отговор. Ако не друго, ще се запитам как този отговор (не първият) всъщност отговаря на въпроса. Ако нещо е било включено в причината за наградата, то трябва да бъде включено някъде, тъй като никой не знае причината за това. Сега обмислям да гласувам против и поради двете причини, посочени в коментарите. - person Popeye; 13.05.2013
comment
хахаха. Току що видях профила ти, луд ли си. дори когато казах да го оставиш и да продължиш напред, ти все още ме държиш на това, че публикувах два отговора и сега не гласувах за него поради причината, че публикувах два отговора, а не заради качеството на самия отговор, а ти за мен е смешно да назоваваш хора в профила си .хаха.. сериозно се нуждаеш от лекарства, приятел, сега разбирам какво не е наред с теб, твоето гласуване против изобщо не ме засяга, просто ще обърка другите. Излез там и направи нещо градивно, приятел, вместо да се оплакваш като бебе. Това ще е последният ми коментар, нямам повече време за хора като теб. - person Bonnie; 14.05.2013