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

Nit*_*esh 50 avfoundation ios avaudiosession swift

要在静音模式下播放声音我使用以下方法.但它是如何不起作用的.

// Works on Swift 3  
do {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
} catch {
    print(error)
}
Run Code Online (Sandbox Code Playgroud)

如何让它在4.2/iOS 12中运行?

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

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

Rhy*_*man 58

HerderTöne的评论显示了新语法,但您还需要在以下情况后激活音频会话setCategory:

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

  • 上述解决方案强制降低iOS与iOS 9设备的兼容性.有没有办法恢复iOS 9兼容性? (2认同)
  • @RhythmicFistman是的,你可以查看[这里](https://developer.apple.com/documentation/avfoundation/avaudiosession/1771734-setcategory),它只是iOS 10+ (2认同)
  • 似乎已经有一个开放的雷达:http://www.openradar.me/42382075 (2认同)

ric*_*ira 38

作为解决方法,您可以使用以下命令调用Objective-C AVAudioSession.setCategory:方法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)
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • @Fallstreak尝试设置类别和选项,如`AVAudioSession.sharedInstance().perform(NSSelectorFromString("setCategory:withOptions:error:"),with:AVAudioSession.Category.playback,with:[AVAudioSession.CategoryOptions.duckOthers])`.它有用吗? (3认同)
  • @Mallox当然你会:这里没有更安全的选择,是吗? (2认同)

Che*_*kie 18

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

try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [])
Run Code Online (Sandbox Code Playgroud)


Gal*_*vin 11

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

创建一个AVAudioSession+Swift.h:

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.
Run Code Online (Sandbox Code Playgroud)

AVAudioSession+Swift.m:

@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
Run Code Online (Sandbox Code Playgroud)

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

#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
Run Code Online (Sandbox Code Playgroud)

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

#import "AVAudioSession+Swift.h"
Run Code Online (Sandbox Code Playgroud)


小智 6

如果您的应用与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


小智 5

将其粘贴到您的viewDidLoad()

do {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: [])
    try AVAudioSession.sharedInstance().setActive(true)
}
catch {
    print(error)
}
Run Code Online (Sandbox Code Playgroud)