Domanda

Ho una cache programma memorizzato in una NSDictionary.

Per l'esempio riportato di seguito, ho un tempo di programma di 13 gennaio 20120 14:00 e 13 Gennaio 2012 02:05 . Come posso aggiungere entrambi questi a una coda di fuoco da soli?

Sviluppare Schedulazione cache:

-(void) buildScheduleCache
{  
    NSCalendarDate *now = [NSCalendarDate calendarDate];

    NSFileManager *manager = [[NSFileManager defaultManager] autorelease];
    path = @"/var/mobile/Library/MobileProfiles/Custom Profiles";
    theProfiles = [manager directoryContentsAtPath:path];

    myPrimaryinfo = [[NSMutableArray arrayWithCapacity:6] retain];
    keys = [NSArray arrayWithObjects:@"Profile",@"MPSYear",@"MPSMonth",@"MPSDay",@"MPSHour",@"MPSMinute",nil];

    for (NSString *profile in theProfiles) 
    {
        plistDict = [[[NSMutableDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/%@",path,profile]] autorelease];

        [myPrimaryinfo addObject:[NSDictionary dictionaryWithObjects:
                                  [NSArray arrayWithObjects:
                                   [NSString stringWithFormat:@"%@",profile], 
                                   [NSString stringWithFormat:@"%@",[plistDict objectForKey:@"MPSYear"]], 
                                   [NSString stringWithFormat:@"%@",[plistDict objectForKey:@"MPSMonth"]], 
                                   [NSString stringWithFormat:@"%@",[plistDict objectForKey:@"MPSDay"]], 
                                   [NSString stringWithFormat:@"%@",[plistDict objectForKey:@"MPSHour"]], 
                                   [NSString stringWithFormat:@"%@",[plistDict objectForKey:@"MPSMinute"]],
                                   nil]forKeys:keys]];

        profileSched =
        [NSCalendarDate dateWithYear:[plistDict objectForKey:@"MPSYear"]
                               month:[plistDict objectForKey:@"MPSMonth"]
                                 day:[plistDict objectForKey:@"MPSDay"]
                                hour:[plistDict objectForKey:@"MPSHour"]
                              minute:[plistDict objectForKey:@"MPSMinute"]
                              second:01
                            timeZone:[now timeZone]];

        [self rescheduleTimer];
    }

    NSString *testPath = @"/var/mobile/Library/MobileProfiles/Schedules.plist";
    [myPrimaryinfo writeToFile:testPath atomically:YES];
}

pianificare l'evento:

-(void) scheduleProfiles
{
    NSFileManager *manager = [[NSFileManager defaultManager] autorelease];
    path = @"/var/mobile/Library/WrightsCS/MobileProfiles/Custom Profiles";
    theProfiles = [manager contentsOfDirectoryAtPath:path error:nil];

    for (NSString *profile in theProfiles) 
    {
        NSMutableDictionary * plistDict = [[[NSMutableDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/%@",path,profile]] autorelease];

        profileSched =
        [NSCalendarDate dateWithYear:[[plistDict objectForKey:@"MPSYear"] intValue]
                               month:[[plistDict objectForKey:@"MPSMonth"] intValue]
                                 day:[[plistDict objectForKey:@"MPSDay"] intValue]
                                hour:[[plistDict objectForKey:@"MPSHour"] intValue]
                              minute:[[plistDict objectForKey:@"MPSMinute"] intValue]
                              second:01
                            timeZone:[NSTimeZone localTimeZone]];


            NSLog(@"DATE: %@      SCHEDULE: %@      PROFILE: %@",[NSDate date],profileSched,profile);
        if([NSDate date] < profileSched)
        {
            NSLog(@"IGNORING PROFILE: %@     WITH SCHEDULE: %@",profile,profileSched);
        }else{
            //Create the timer from the Cached Array
            schedTimer = [[NSTimer alloc] initWithFireDate:profileSched //[NSDate dateWithTimeIntervalSinceNow: 10]
                                                  interval:0.1f
                                                    target:self
                                                  selector:@selector(fireCustomProfile:)
                                                  userInfo:profile
                                                   repeats:NO];//[[plistDict objectForKey:@"MPSRepeat"] boolValue]];

            MLogString(@"Scheduling Profile: %@",profile);
            [[NSRunLoop currentRunLoop] addTimer:schedTimer forMode:NSDefaultRunLoopMode];
        }
    }
}

Fuoco l'evento:

-(void)fireCustomProfile:(NSTimer *)timer
{   
    if([[NSDate date] earlierDate:[schedTimer fireDate]])
    {
        NSLog(@"Ignoring Profile: %@",[schedTimer userInfo]);
        return;
    }

    notify_post("com.wrightscs.MobileProfiles.setCustomProfile");
}

Esempio evento:

<array>
    <dict>
        <key>MPSDay</key>
        <string>13</string>
        <key>MPSHour</key>
        <string>21</string>
        <key>MPSMinute</key>
        <string>15</string>
        <key>MPSMonth</key>
        <string>1</string>
        <key>MPSYear</key>
        <string>2012</string>
        <key>Profile</key>
        <string>Event 1</string>
        <key>Repeat</key>
        <true/>
    </dict>
</array>
<array>
    <dict>
        <key>MPSDay</key>
        <string>13</string>
        <key>MPSHour</key>
        <string>21</string>
        <key>MPSMinute</key>
        <string>20</string>
        <key>MPSMonth</key>
        <string>1</string>
        <key>MPSYear</key>
        <string>2012</string>
        <key>Profile</key>
        <string>Event 2</string>
        <key>Repeat</key>
        <true/>
    </dict>
</array>
È stato utile?

Soluzione

È possibile utilizzare al posto di UILocalNotification NSTimer. Le limitazioni sono che non ci sono azioni nella vostra applicazione senza la vostra interazione, ma ci viene attivato una notifica anche se l'applicazione è shutted verso il basso.

Documentazione di Apple su UILocalNotifications :

  

Le istanze di UILocalNotification rappresentano le notifiche che un   applicazione può programmare per la presentazione ai propri utenti a specifiche   date e orari. Il sistema operativo è responsabile della consegna   la notifica al momento opportuno; l'applicazione non ha bisogno di   essere in esecuzione perché questo avvenga.

     

...

     

Quando il sistema fornisce una notifica locale, diverse cose possono   accadere, a seconda dello stato di applicazione e il tipo di   notifica. Se l'applicazione non è in primo piano e visibile, la   sistema visualizza il messaggio di avviso, distintivi l'applicazione, e svolge un   sound-tutto ciò che è specificata nella notifica. Se la notifica   è un allarme e l'utente tocca il pulsante di azione (o, se il dispositivo è   bloccato, trascina il cursore aperto azione), l'applicazione viene avviata. Nel   l'applicazione: didFinishLaunchingWithOptions: Metodo di applicazione   delegato può ottenere l'oggetto UILocalNotification dal passato in   Opzioni di dizionario con la   chiave UIApplicationLaunchOptionsLocalNotificationKey. La lattina delegato   ispezionare le proprietà della notifica e, se la notifica   include dati personalizzati nel suo dizionario userInfo, si può accedere a quel   i dati ed elaborare di conseguenza. D'altra parte, se il locale   la notifica badge solo l'icona dell'applicazione, e l'utente in   lanci di risposta l'applicazione, la   applicazione: didFinishLaunchingWithOptions: metodo viene richiamato, ma non   oggetto UILocalNotification è inclusa nel dizionario opzioni.

     

Se l'applicazione è più importante e visibile quando il sistema eroga   la notifica, nessun avviso viene visualizzato, nessuna icona è targate, e nessun suono   è giocato. Tuttavia, l'applicazione: didReceiveLocalNotification: è   chiamato se il delegato applicazione implementa. Il   esempio UILocalNotification viene passato in questo metodo, e la   delegato può controllare le proprietà o accedere ai dati personalizzati dal   userInfo dizionario.

È possibile trovare un buon tutorial qui dove l'idea principale è simile a questo:

Il setup di notifica:

Class cls = NSClassFromString(@"UILocalNotification");
if (cls != nil) {
    UILocalNotification *notif = [[cls alloc] init];
    notif.fireDate = [datePicker date];
    notif.timeZone = [NSTimeZone defaultTimeZone];

    notif.alertBody = TEXT;
    notif.alertAction = LAUNCH_BUTTON;
    notif.soundName = UILocalNotificationDefaultSoundName;
    notif.applicationIconBadgeNumber = NOTIFICATIONS_REMAINING;

    NSDictionary *userDict = [NSDictionary dictionaryWithObject:CUSTOM_INFO 
                                            forKey:kRemindMeNotificationDataKey];
    notif.userInfo = userDict;

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

Cura dello nofitication quando l'applicazione non è in esecuzione (nel delegato applicaction):

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    Class cls = NSClassFromString(@"UILocalNotification");
    if (cls) {
        UILocalNotification *notification = [launchOptions objectForKey:
                        UIApplicationLaunchOptionsLocalNotificationKey];

        if (notification) {
            NSString *reminderText = [notification.userInfo 
                        objectForKey:kRemindMeNotificationDataKey];
           [viewController showReminder:reminderText];
        }
    }

    application.applicationIconBadgeNumber = NOTIFICATIONS_REMAINING_LESS_ONE;

    [window addSubview:viewController.view];
    [window makeKeyAndVisible];

    return YES;
}

Applicazione in primo piano (nel delegato applicaction):

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {

    UIApplicationState state = [application applicationState];
    if (state == UIApplicationStateInactive) {
        // Application was in the background when notification
        // was delivered.
    }
}

Altri suggerimenti

Sei sicuro un timer è quello che vuoi? Ricordate, un timer è attiva solo quando la vostra applicazione è attiva. Non funziona quando l'applicazione non è attiva. Se si sta cercando di ottenere la vostra applicazione di fare qualcosa in qualsiasi momento, in un lontano futuro, un timer non sarà davvero risolvere il problema, perché ogni volta che si esce l'applicazione, tutte le sue timer morire.

Supponendo che (1) si vuole solo per i timer impostati per gli eventi, mentre l'applicazione è attiva e (2) si ha sempre un numero imprecisato di eventi nella coda, allora il vostro problema più grande sarà smistamento come indirizzare un numero arbitrario di temporizzatori per un numero arbitrario di eventi.

Per fortuna, i timer può passare qualsiasi oggetto arbitrario nella loro proprietà userInfo così si vuole avvolgere ogni evento in un oggetto e passare l'oggetto al timer. Metodo Poi il timer sparato può estrarre l'evento e agire su di esso.

Qualcosa di simile a questo:

// assume a data model with event objects with the attributes and methods shown

- (void) setTimerForEvent:(EventClass *) anEvent{
    [NSTimer timerWithTimeInterval:[anEvent eventTimeFromNow] 
                            target:self 
                          selector:@selector(fireEvent:) 
                          userInfo:anEvent 
                           repeats:NO];

}//------------------------------------setTimerForEvent:------------------------------------

- (void)fireEvent:(NSTimer*)theTimer{
    [self handleEvent:(EventClass *)theTimer.userInfo]; 
    [theTimer invalidate];
}//------------------------------------fireEvent:------------------------------------

Il -[EventClass eventTimeFromNow] deve restituire un NSTimerInterval dei secondi rimanenti tra il momento in cui il metodo viene chiamato e ora dell'evento.

Avrete bisogno di un timer per ogni evento. Forse non assegnare il timer alla variabile timer. Si può solo creare questi timer e rilasciarli nel theFireEvent. Avrete bisogno di cambiare la situazione selettore per @selector(theFireEvent), però, e assicurarsi che il metodo ha la firma:

- (void)timerFireMethod:(NSTimer*)theTimer

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top