Jouer du son dans la notification didreceiveremoteno, tandis que dans le backgorund, en utilisant le texte à la fonctionnalité de la parole

alors ce que j'essaie actuellement c'est de lire un message quand app reçoit une notification à distance en arrière-plan (ou probablement réveillé d'un état suspendu).

le son ne joue pas du tout après que l'application est réveillée d'un mode suspendu.

Lorsque l'application est au premier plan, un son est joué immédiatement après didReceiveRemoteNotification: méthode est appelée.

quelle serait une façon appropriée d'avoir des sons joués immédiatement quand didReceiveRemoteNotification: méthode est appelée pendant que app se réveille d'un mode suspendu ?

Voici le code (discours manager class):

-(void)textToSpeechWithMessage:(NSString*)message andLanguageCode:(NSString*)languageCode{

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *error = nil;
DLog(@"Activating audio session");
if (![audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionMixWithOthers error:&error]) {
    DLog(@"Unable to set audio session category: %@", error);
}
BOOL result = [audioSession setActive:YES error:&error];
if (!result) {
    DLog(@"Error activating audio session: %@", error);

}else{
    AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:message];

    [utterance setRate:0.5f];

    [utterance setVolume:0.8f];

    utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:languageCode];

    [self.synthesizer speakUtterance:utterance];
}

}

-(void)textToSpeechWithMessage:(NSString*)message{

[self textToSpeechWithMessage:message andLanguageCode:[[NSLocale preferredLanguages] objectAtIndex:0]];

}

Et ensuite AppDelegate:

[[MCSpeechManager sharedInstance] textToSpeechWithMessage:messageText];

j'ai activé Audio,vidéo AirPlay et image dans l'Image option dans la section Capabilities - > Background Modes.

EDIT:

peut-être que je devrais commencer une tâche de fond et lancer le gestionnaire d'expiration si nécessaire? Je suppose que ça pourrait marcher, mais aussi je voudrais j'aime entendre la façon commune de résoudre ce genre de situations.

aussi avec ce code j'obtiens la prochaine erreur quand je reçois une notification en arrière-plan:

erreur activation de la session audio: Error Domain=NSOSStatusErrorDomain Code=561015905 " (null)"

le Code 561015905 s'applique à:

AVAudioSessionErrorCodeCannotStartplaying ='!pla', / * 0x21706C61, 561015905

Et il est décrit comme:

ce type d'erreur peut se produire si la liste de propriétés de L'information de l'application ne ne permet pas l'utilisation audio, ou si l'application est à l'arrière-plan et en utilisant un catégorie qui ne permet pas de fond sonore.

mais j'obtiens la même erreur avec les autres catégories (AVAudioSessionCategoryAmbient et AVAudioSessionCategorySoloAmbient)

16
demandé sur Whirlwind 2016-11-23 19:28:53

2 réponses

comme je ne peux pas reproduire l'erreur que vous décrivez, permettez-moi d'offrir quelques pointeurs, et un peu de code.

  • construisez-vous/testez-vous/courez-vous contre le dernier SDK? Des changements importants ont été apportés au mécanisme de notification dans iOS X
  • je dois supposer que l'invocation d' didReceiveRemoteNotification doit se produire en réponse à une action de l'utilisateur de ladite notification, comme l'écoute du message de notification par exemple.
  • Il n'est pas nécessaire de définir d' les modes de fond sauvent l'application télécharge du contenu en réponse aux notifications push.

si tous les énoncés ci-dessus sont vrais, la présente réponse se concentrera sur ce qui se passe lorsqu'une notification arrive.

  1. L'appareil reçoit la notification

    Remote
  2. l'utilisateur tape sur le message
  3. App se lance
  4. didReceiveRemoteNotification est appelée

à l'étape 4, textToSpeechWithMessage fonctionne comme prévu:

func application(_ application: UIApplication,
                 didReceiveRemoteNotification
                 userInfo: [AnyHashable : Any],
                 fetchCompletionHandler completionHandler:
                 @escaping (UIBackgroundFetchResult) -> Void) {
    textToSpeechWithMessage(message: "Speak up", "en-US")
}

pour simplifier, j'utilise OneSignal pour raccorder les notifications:

import OneSignal
...
_ = OneSignal.init(launchOptions: launchOptions,
                   appId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
// or
_ = OneSignal.init(launchOptions: launchOptions,
                   appId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
                   {
                       (s:String?, t:[AnyHashable : Any]?, u:Bool) in
                       self.textToSpeechWithMessage(message: "OneDignal", "en-US")
                   }

textToSpeechWithMessage est quasi intacte, elle est ici Swift 3 complet:

import AVFoundation
...
let synthesizer = AVSpeechSynthesizer()
func textToSpeechWithMessage(message:String, _ languageCode:String)
{
    let audioSession = AVAudioSession.sharedInstance()

    print("Activating audio session")
    do {
        try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord,
                                     with: [AVAudioSessionCategoryOptions.defaultToSpeaker,
                                            AVAudioSessionCategoryOptions.mixWithOthers]
        )
        try audioSession.setActive(true)

        let utterance = AVSpeechUtterance(string:message)
        utterance.rate = 0.5
        utterance.volume = 0.8
        utterance.voice = AVSpeechSynthesisVoice(language: languageCode)
        self.synthesizer.speak(utterance)

    } catch {
        print("Unable to set audio session category: %@", error);
    }
}
5
répondu SwiftArchitect 2017-01-04 02:07:04

Veuillez mettre en œuvre

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler; 

méthode. Vous recevrez un appel en arrière-plan pour lire l'audio.

0
répondu Laxman Sahni 2017-01-18 09:40:42