58 votes

AVAudioSession setCategory Swift 4.2 iOS 12 - Lecture du son en mode silencieux

Pour lire le son même en mode silencieux, j'utilise la méthode ci-dessous. Mais comment ça ne marche pas.

 // Works on Swift 3  
do {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
} catch {
    print(error)
}
 

Comment le faire fonctionner dans 4.2 / iOS 12?

Dans une version plus récente, nous devons définir le mode et les options.

 try AVAudioSession.sharedInstance().setCategory(
    <#T##category:AVAudioSession.Category##AVAudioSession.Category#>,
    mode: <#T##AVAudioSession.Mode#>, 
    options: <#T##AVAudioSession.CategoryOptions#>)`
 

74voto

Rhythmic Fistman Points 7612

Le commentaire de Her der Töne vous montre la nouvelle syntaxe, mais vous devez également activer la session audio après setCategory :

 do {
    try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
    try AVAudioSession.sharedInstance().setActive(true)
} catch {
    print(error)
}
 

41voto

ricardopereira Points 3249

Pour contourner ce problème, vous pouvez appeler la méthode Objective-C AVAudioSession.setCategory: avec la méthode NSObject.performSelector: :

 if #available(iOS 10.0, *) {
    try! AVAudioSession.sharedInstance().setCategory(.playback, mode: .moviePlayback)
}
else {
    // Workaround until https://forums.swift.org/t/using-methods-marked-unavailable-in-swift-4-2/14949 isn't fixed
    AVAudioSession.sharedInstance().perform(NSSelectorFromString("setCategory:error:"), with: AVAudioSession.Category.playback)
}
 

Si vous souhaitez définir la catégorie et les options pour iOS 9 et versions antérieures, utilisez:

 AVAudioSession.sharedInstance().perform(NSSelectorFromString("setCategory:withOptions:error:"), with: AVAudioSession.Category.playback, with:  [AVAudioSession.CategoryOptions.duckOthers])
 

MISE À JOUR:

Le problème est résolu dans Xcode 10.2.

20voto

VagueExplanation Points 747

Pour Swift 4.2 dans iOS 12, c'est simplement:

 try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [])
 

15voto

Galvin Points 181

Mise à jour pour Xcode 10.2:

 Apple finally fix this issue in Xcode 10.2. 
So no need to add these workaround code anymore if you use Xcode 10.2 or newer version.

But you also could refer this code for any problem like this.
 

Vous pouvez utiliser une catégorie objective-c pour aider à résoudre ce problème.

Créez un AVAudioSession+Swift.h :

 @import AVFoundation;

NS_ASSUME_NONNULL_BEGIN

@interface AVAudioSession (Swift)

- (BOOL)swift_setCategory:(AVAudioSessionCategory)category error:(NSError **)outError NS_SWIFT_NAME(setCategory(_:));
- (BOOL)swift_setCategory:(AVAudioSessionCategory)category withOptions:(AVAudioSessionCategoryOptions)options error:(NSError **)outError NS_SWIFT_NAME(setCategory(_:options:));

@end

NS_ASSUME_NONNULL_END
 

Avec un AVAudioSession+Swift.m :

 #import "AVAudioSession+Swift.h"

@implementation AVAudioSession (Swift)

- (BOOL)swift_setCategory:(AVAudioSessionCategory)category error:(NSError **)outError {
    return [self setCategory:category error:outError];
}
- (BOOL)swift_setCategory:(AVAudioSessionCategory)category withOptions:(AVAudioSessionCategoryOptions)options error:(NSError **)outError {
    return [self setCategory:category withOptions:options error:outError];
}

@end
 

Importez ensuite le "AVAudioSession + Swift.h" dans votre <#target_name#>-Bridging-Header.h

 #import "AVAudioSession+Swift.h"
 

Le résultat est que vous pouvez appeler la méthode en swift comme précédemment.

 do {
    try AVAudioSession.sharedInstance().setCategory(.playback)
    try AVAudioSession.sharedInstance().setCategory(.playback, options: [.mixWithOthers])
    try AVAudioSession.sharedInstance().setActive(true)
} catch {
    print(error)
}
 

7voto

JMGM Points 225

La réponse ci-dessus (par Rythmique Fistman) est correct si votre application n'est pas compatible avec iOS 9 ou ci-dessous.

Si votre application est compatible avec iOS 9, vous verrez l'erreur suivante:

'setCategory' est pas disponible dans Swift

Dans ce cas, il y a un bug avec Swift 4.2, c'est un problème de AVFoundation dans Xcode 10 Sdk, vous pouvez contourner le problème en écrivant un Objectif-C fonction des appels par le biais de l'ancienne API, car ils sont toujours disponibles en Objective-C.

Dans le lien suivant vous pouvez lire plus de détails:

https://forums.swift.org/t/using-methods-marked-unavailable-in-swift-4-2/14949

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X