2017-09-28 1 views
0

Je suis en train de mettre une alarme, mais je veux que, au lieu de jouer de la musique l'application va lire la liste de todo que j'ai créé.comment planifier une tâche dans swift?

J'utilise la classe AVSpeechSynthesizer pour exécuter les fonctionnalités de parler et il fonctionne très bien mais le problème est, j'utilise la minuterie pour la planification d'une tâche et lorsque l'application passe en arrière-plan de la minuterie cesse de fonctionner

voici mon code:

class Speaking : NSObject,AVSpeechSynthesizerDelegate { 

let speechSynthesizerObject = AVSpeechSynthesizer() 
let voice = AVSpeechSynthesisVoice(language: "en-au") 

override init() { 
    super.init() 
    speechSynthesizerObject.delegate = self 
} 

func speak(string: String) { 
    let utterance = AVSpeechUtterance(string: string) 
    utterance.rate = 0.5 
    utterance.voice = self.voice 
    speechSynthesizerObject.speak(utterance) 
} 

func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) { 
    print("all done") 

}  
} 

fonction d'alarme

func setAlaram(){ 

    var date = self.appData.Alaram 

    if(date < Date()){ 
     date = Calendar.current.date(byAdding: .day, value: 1, to: date)! 
    } 

    let calendar = Calendar(identifier: .gregorian) 

    var component = calendar.dateComponents([.year,.month,.day,.hour,.minute,.second], from: date) 
    component.second = 0 
    var modifiedDateTime = calendar.date(from: component)! 

    var snooz = Timer(fireAt: modifiedDateTime, interval: 0, target: self, selector: #selector(setSpeechRecognizeAsAlaram), userInfo: "first", repeats: false) 
    RunLoop.main.add(snooz!, forMode: RunLoopMode.commonModes) 
} 
fonction

que je veux tirer quand l'effondrement du temps

func setSpeechRecognizeAsAlaram(sender: Timer){ 
    guard let data = loadAppData() else{ return } 
    self.appData = data 

    let numberOfTodo = String(appData.ToDoList.count) 


    var items = String() 
    var counter = 1 
    for item in appData.ToDoList { 
     items += String(counter) + ", " + item + ". " 
     counter += 1 
    } 

    let date = Date() 
    let dateformat1 = DateFormatter() 
    let dateformat2 = DateFormatter() 
    dateformat1.dateStyle = .full 
    dateformat2.dateFormat = "hh:mm a" 
    var sentence = String() 

    if(appData.ToDoList.count == 0){ 
     sentence = " Good Morning! It’s" + dateformat2.string(from: date) + "!. And it’s time to wake up!. I’m disappointed in you today. You forgot to add in new “TO-DO” items to your list." 
    } 
    else{ 
     sentence = "Good Morning! Its " + dateformat2.string(from: date) + "!. And its time to wake up. Today is " + dateformat1.string(from: date) + ". You have " + numberOfTodo + " items on your to-do list for the day. " + items + " Thats all!. I hope you have a productive day! " 
    } 
    let spk = Speaking() 
    spk.speak(string: sentence) 

} 

toute aide sera appréciée

Merci de

+0

Vous ne pouvez pas exécuter du code arbitraire à une heure planifiée lorsque votre application est suspendue. – Paulw11

+0

Ce que vous cherchez est UILocalNotification (https://developer.apple.com/documentation/uikit/uilocalnotification), mais je ne suis pas sûr que vous pouvez exécuter AVSpeechSynthesizer à partir de là – mlidal

+0

Est-ce que c'est une autre façon de faire cela? . ULNotification ne permettra pas d'exécuter cette fonction. –

Répondre

1

Avez-vous lu Background Execution, des notes de pommes sur la façon d'exécuter des tâches en arrière-plan.

Il y a une section sur Obtenir l'attention de l'utilisateur en arrière-plan. Il existe un exemple de définition d'une alarme à l'aide d'une notification locale.

sur le site Web d'Apple


Listing 3-2 Planification d'une notification d'alarme

- (void)scheduleAlarmForDate:(NSDate*)theDate 
{ 
    UIApplication* app = [UIApplication sharedApplication]; 
    NSArray* oldNotifications = [app scheduledLocalNotifications]; 

    // Clear out the old notification before scheduling a new one. 
    if ([oldNotifications count] > 0) 
     [app cancelAllLocalNotifications]; 

    // Create a new notification. 
    UILocalNotification* alarm = [[UILocalNotification alloc] init]; 
    if (alarm) 
    { 
     alarm.fireDate = theDate; 
     alarm.timeZone = [NSTimeZone defaultTimeZone]; 
     alarm.repeatInterval = 0; 
     alarm.soundName = @"alarmsound.caf"; 
     alarm.alertBody = @"Time to wake up!"; 

     [app scheduleLocalNotification:alarm]; 
    } 
} 


UPDATE

Et bien sûr, UILocalNotification est obsolète. Le nouveau remplacement est UNNotificationRequest.

+0

Je veux que AVSpeechSynthesizer parle le script mais comment est-il possible d'utiliser UNNotification? Je ne pense pas que mon application se trouve dans une catégorie que Apple permet d'exécuter en arrière-plan. des hacks? –

+1

Je chercherais un moyen d'écrire le son dans un fichier alors que l'application est au premier plan. Puis en arrière-plan jouer le fichier son. –