AVAudioSession setCategory Swift 4.2 iOS 12 - 在静音上播放声音



即使在静音模式下也能播放声音,我习惯使用以下方法。但是它是如何不起作用的。

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

如何让它在 4.2/iOS 12 中工作?

在较新的版本中,我们需要设置模式和选项。

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

Her der Töne 的评论向您展示了新语法,但您还需要在setCategory之后激活音频会话:

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

作为一种解决方法,您可以使用以下NSObject.performSelector:调用 Objective-CAVAudioSession.setCategory:方法:

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)
}

如果要为 iOS 9 及更早版本设置类别和选项,请使用:

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

更新:

问题已在 Xcode 10.2 中修复。

对于 iOS 12 中的 Swift 4.2,它很简单:

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

更新 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.

您可以使用 objective-c 类别来帮助解决此问题。

创建一个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

带有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

然后在您的<#target_name#>-Bridging-Header.h中导入"AVAudioSession+Swift.h"

#import "AVAudioSession+Swift.h"

结果是你可以像以前一样在 swift 中调用该方法。

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

如果您的应用程序与iOS 9或更低版本不兼容,则上述答案(由Rhythmic Fistman提供(是正确的。

如果您的应用程序与iOS 9兼容,您将看到下一个错误:

'setCategory' 在 Swift 中不可用

在这种情况下,Swift 4.2 有一个错误,这是 Xcode 10 SDK 中 AVFoundation 的问题,你可以通过编写一个调用旧 API 的 Objective-C 函数来解决它,因为它们在 Objective-C 中仍然可用。

在下一个链接中,您可以阅读更多详细信息:

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

将其粘贴到您的viewDidLoad()

do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: [])
try AVAudioSession.sharedInstance().setActive(true)
}
catch {
print(error)
}
//Swift 4.2
if #available(iOS 10.0, *) {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, 
mode: AVAudioSessionModeDefault)
} else {
//Fallback on earlier versions
}

Swift 5

let audioSession = AVAudioSession.sharedInstance()
_ = try? audioSession.setCategory(.playback, options: .defaultToSpeaker)
_ = try? audioSession.setActive(true)

swift 4 的代码:

do {
try AKSettings.setSession(category: .playback, with: [])
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, mode: AVAudioSessionModeDefault, options: [])
try AVAudioSession.sharedInstance().setActive(true)

} catch {
print(error)
}

希望有帮助

最新更新