2014-09-06 18 views
9

Sto lavorando a un'applicazione di preghiere che consente agli utenti di impostare un allarme (notifica locale) per i tempi di preghiera, ovvero l'utente imposta l'applicazione per notificarlo alla preghiera del Fajr ogni giorno , il problema è che il tempo per ogni preghiera cambia ogni giorno, quindi il tempo che l'app notificherà all'utente per la fiera di giovedì sarà diverso da quello di venerdì, ho bisogno di ripetere la notifica locale ogni giorno ma secondo il tempo di preghiera giornaliero, per favore, qualcuno potrebbe darmi un'idea?Come ripetere le notifiche locali ogni giorno in momenti diversi

+0

Hai mai questo numero? Ho finito per calcolare le preghiere per i prossimi 10 giorni e ho programmato le notifiche in questo modo. L'unica cosa è che c'è un limite di 50 notifiche, quindi devo impostare un'altra notifica affinché l'utente possa aprire la mia app in modo che i prossimi 10 giorni possano essere programmati. Non mi piace, ma solo il modo in cui potrei pensare. – TruMan1

+0

http://stackoverflow.com/questions/9862261/local-notification-repetation-at-different-times – TruMan1

+0

@ TruMan1: vuoi che l'utente imposti l'ora, o vuoi che l'app imposti il ​​tempo per utente? E quanto tempo dovrebbe essere aggiunto al tempo? Mi piacerebbe fornire qualche implementazione, ma ho bisogno di maggiori informazioni. :) – Sheamus

risposta

2

Quindi il problema appare è necessario impostare questa notifica locale di tanto in tanto, ma non può essere una notifica ripetibile. Presumo che l'utente imposta il tempo di preghiera e vuole essere avvisato. Ti suggerisco di impostarne alcuni, dato che sai dalla lista. Quindi imposta il recupero dello sfondo per consentire di dire ogni 5 ore e, all'avvio dell'applicazione in background, controlla solo quali notifiche locali sono ancora impostate e aggiorna l'elenco in base alla data corrente. Il recupero dello sfondo non riattiva la tua app esattamente ogni 5 ore in questo caso, ma farà del suo meglio. Sono sicuro che la tua app si sveglierà almeno due volte al giorno. Puoi modificare il tempo in base alle tue esigenze.

Recupero piccole quantità di contenuto opportunisticamente applicazioni che hanno bisogno di verificare la presenza di nuovi contenuti periodicamente può chiedere al sistema di svegliarli in modo che possano avviare un'operazione di recupero per tale contenuto. Per supportare questa modalità, attiva l'opzione Recupera sfondo dalla sezione Modalità sfondo della scheda Capacità del progetto Xcode. (Puoi anche abilitare questo supporto includendo la chiave UIBackgroundModes con il valore di recupero nel file Info.plist della tua app.) Abilitare questa modalità non è una garanzia che il sistema fornirà la tua app in qualsiasi momento per eseguire recuperi di background. Il sistema deve bilanciare l'esigenza dell'app di recuperare il contenuto con le esigenze di altre app e del sistema stesso. Dopo aver valutato tali informazioni, il sistema dà il tempo alle app quando ci sono buone opportunità per farlo. Quando si presenta una buona opportunità, il sistema riattiva o avvia la tua app in background e chiama l'applicazione del delegato dell'app: performFetchWithCompletionHandler: method. Utilizzare questo metodo per verificare la presenza di nuovi contenuti e avviare un'operazione di download se il contenuto è disponibile. Non appena hai finito di scaricare il nuovo contenuto, devi eseguire il blocco di completamento del completamento fornito, passando un risultato che indica se il contenuto era disponibile. L'esecuzione di questo blocco dice al sistema che può riportare la tua app allo stato sospeso e valutare il suo consumo energetico. Le app che scaricano rapidamente piccole quantità di contenuti e riflettono con precisione quando hanno a disposizione contenuti da scaricare, hanno più probabilità di ricevere tempi di esecuzione in futuro rispetto alle app che impiegano molto tempo per scaricare i loro contenuti o che il contenuto delle attestazioni è disponibile ma poi eseguono non scaricare nulla.

Per ulteriori informazioni si riferisce alla documentazione di Apple su esecuzione in background:

https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

+0

Interessante, buona idea di registrare un recupero in background solo per calcolare e programmare future notifiche. – TruMan1

6

Ci sono alcune soluzioni possibili per questo. Potrebbe essere più sicuro utilizzare un approccio in cui è previsto un numero limitato di notifiche alla volta, poiché iOS mantiene solo le 64 notifiche più recenti:

Un'app può avere solo un numero limitato di notifiche programmate; il sistema mantiene le notifiche a 64 attivazioni più brevi (con notifiche riprogrammate automaticamente contando come un'unica notifica) e scarta il resto.

Fonte: riferimento classe UILocalNotification

Inoltre non è una buona idea fare affidamento sull'uso del UILocalNotification passato in application:didFinishLaunchingWithOptions:, dal momento che è passato solo quando l'utente swipes la notifica:

Consulta il dizionario delle opzioni di avvio per determinare il motivo per cui è stata lanciata la tua app. L'applicazione: willFinishLaunchingWithOptions: e application: didFinishLaunchingWithOptions: i metodi forniscono un dizionario con le chiavi che indicano il motivo dell'avvio della tua app.

Il valore della chiave per il lancio in risposta ad una notifica locale è: UIApplicationLaunchOptionsLocalNotificationKey

Fonte: UIApplicationDelegate classe di riferimento

Opzione 1: programma di un giorno alla volta (codice per questo è fornito di seguito)

Un modo per gestire la pianificazione delle notifiche è presentare un programma all'utente, mentre le notifiche del giorno sono pianificate al momento dell'apertura iniziale dell'app.

Utilizzare una classe CustomNotificationManager per gestire le notifiche i cui orari sono variabili (codice fornito di seguito). In AppDelegate, è possibile delegare a questa classe la gestione delle notifiche locali, che programmano le notifiche del giorno corrente e la notifica del giorno successivo o rispondono a una notifica di preghiera.

Se l'utente apre l'app in risposta a una notifica di preghiera, l'app può indirizzare l'utente a una parte appropriata dell'app. Se l'utente apre l'app in risposta alla notifica a tempo fisso, l'app programmerà le notifiche locali del giorno in base alla data e all'ubicazione dell'utente.

Opzione 2 (approccio un po 'più sottile, ma che fornisce meno per l'utente)

Un altro approccio è quello di utilizzare semplicemente il lancio app di una notifica di preghiera per programmare quella che segue immediatamente. Tuttavia, questo è meno affidabile e non offre la possibilità di visualizzare in anteprima una pianificazione delle notifiche.

file di intestazione Gestione notifiche

@interface CustomNotificationManager : NSObject 

- (void) handleLocalNotification:(UILocalNotification *localNotification); 

@end 

Notifica file di implementazione Direttore

#import "CustomNotificationManager.h" 

#define CustomNotificationManager_FirstNotification @"firstNotification" 

@implementation CustomNotificationManager 

- (instancetype) init 
{ 
    self = [super init]; 

    if (self) { 

    } 

    return self; 
} 

- (void) handleLocalNotification:(UILocalNotification *)localNotification 
{ 
    //Determine if this is the notification received at a fixed time, 
    // used to trigger the scheculing of today's notifications 
    NSDictionary *notificationDict = [localNotification userInfo]; 
    if (notificationDict[CustomNotificationManager_FirstNotification]) { 
     //TODO: use custom algorithm to create notification times, using today's date and location 
     //Replace this line with use of algorithm 
     NSArray *notificationTimes = [NSArray new]; 

     [self scheduleLocalNotifications:notificationTimes]; 
    } else { 
     //Handle a prayer notification 
    } 

} 

/** 
* Schedule local notifications for each time in the notificationTimes array. 
* 
* notificationTimes must be an array of NSTimeInterval values, set as intervalas 
* since 1970. 
*/ 
- (void) scheduleLocalNotifications:(NSArray *)notificationTimes 
{ 
    for (NSNumber *notificationTime in notificationTimes) { 
     //Optional: create the user info for this notification 
     NSDictionary *userInfo = @{}; 

     //Create the local notification 
     UILocalNotification *localNotification = [self createLocalNotificationWithFireTimeInterval:notificationTime 
                         alertAction:@"View" 
                         alertBody:@"It is time for your next prayer." 
                          userInfo:userInfo]; 

     //Schedule the notification on the device 
     [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; 
    } 

    /* Schedule a notification for the following day, to come before all other notifications. 
    * 
    * This notification will trigger the app to schedule notifications, when 
    * the app is opened. 
    */ 

    //Set a flag in the user info, to set a flag to let the app know that it needs to schedule notifications 
    NSDictionary *userInfo = @{ CustomNotificationManager_FirstNotification : @1 }; 

    NSNumber *firstNotificationTimeInterval = [self firstNotificationTimeInterval]; 

    UILocalNotification *firstNotification = [self createLocalNotificationWithFireTimeInterval:firstNotificationTimeInterval 
                        alertAction:@"View" 
                        alertBody:@"View your prayer times for today." 
                         userInfo:userInfo]; 

    //Schedule the notification on the device 
    [[UIApplication sharedApplication] scheduleLocalNotification:firstNotification]; 
} 

- (UILocalNotification *) createLocalNotificationWithFireTimeInterval:(NSNumber *)fireTimeInterval 
                alertAction:(NSString *)alertAction 
                alertBody:(NSString *)alertBody 
                userInfo:(NSDictionary *)userInfo 

{ 
    UILocalNotification *localNotification = [[UILocalNotification alloc] init]; 
    if (!localNotification) { 
     NSLog(@"Could not create a local notification."); 
     return nil; 
    } 

    //Set the delivery date and time of the notification 
    long long notificationTime = [fireTimeInterval longLongValue]; 
    NSDate *notificationDate = [NSDate dateWithTimeIntervalSince1970:notificationTime]; 
    localNotification.fireDate = notificationDate; 

    //Set the slider button text 
    localNotification.alertAction = alertAction; 

    //Set the alert body of the notification 
    localNotification.alertBody = alertBody; 

    //Set any userInfo, e.g. userID etc. (Useful for app with multi-user signin) 
    //The userInfo is read in the AppDelegate, via application:didReceiveLocalNotification: 
    localNotification.userInfo = userInfo; 

    //Set the timezone, to allow for adjustment for when the user is traveling 
    localNotification.timeZone = [NSTimeZone localTimeZone]; 

    return localNotification; 
} 

/** 
* Calculate and return a number with an NSTimeInterval for the fixed daily 
* notification time. 
*/ 
- (NSNumber *) firstNotificationTimeInterval 
{ 
    //Create a Gregorian calendar 
    NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; 

    //Date components for next day 
    NSDateComponents *dateComps = [[NSDateComponents alloc] init]; 
    dateComps.day = 1; 

    //Get a date for tomorrow, same time 
    NSDate *today = [NSDate date]; 
    NSDate *tomorrow = [cal dateByAddingComponents:dateComps toDate:today options:0]; 

    //Date components for the date elements to be preserved, when we change the hour 
    NSDateComponents *preservedComps = [cal components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:tomorrow]; 
    preservedComps.hour = 5; 
    tomorrow = [cal dateFromComponents:preservedComps]; 

    NSTimeInterval notificationTimeInterval = [tomorrow timeIntervalSince1970]; 

    NSNumber *notificationTimeIntervalNum = [NSNumber numberWithLongLong:notificationTimeInterval]; 

    return notificationTimeIntervalNum; 
} 

@end 

AppDelegate didReceiveLocalNotification Attuazione

- (void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification 
{ 
    CustomNotificationManager *notificationManager = [[CustomNotificationManager alloc] init]; 
    [notificationManager handleLocalNotification:notification]; 
} 

Suggerimento per la modifica possibile: Se CustomNotificationManager deve mantenere lo stato, è possibile convertirlo in Singleton.

2

Ci sono tre modi per farlo:

  1. notifiche Usa spinta invece di notifiche locali e spostare la logica al server. Problema: l'utente non riceverà notifiche offline.

  2. Continua a utilizzare le notifiche locali. Dovrai pianificare una nuova notifica per ogni momento di preghiera. Naturalmente, il numero di notifiche locali è limitato (max 64 notifiche pianificate) ma dovrebbe essere sufficiente per una settimana di notifiche. Una notifica non è un allarme, l'utente deve aprire l'applicazione in risposta alla ricezione di una notifica. In questo modo, puoi sempre riprogrammare tutte le notifiche quando viene riaperta l'app. Inoltre, l'ultima notifica può essere simile a "non hai aperto l'app da un po ', non riceverai più notifiche".

  3. Invece di creare notifiche locali, creare allarmi/promemoria nel calendario del dispositivo (Event Kit)

Problemi correlati