AVAudioSession setCategory Swift 4.2 iOS 12 - 静音播放
AVAudioSession setCategory Swift 4.2 iOS 12 - Play Sound on Silent
即使在静音模式下也能播放声音,我使用以下方法。但是它怎么不工作。
// 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#>)`
她的 der Töne 的评论向您展示了新语法,但您还需要在 setCategory
之后激活音频会话:
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
如果您的应用与 iOS 9 或更低版本不兼容,则以上答案(由 Rhythmic Fistman 提供)是正确的。
如果您的应用与 iOS9 兼容,您将看到下一个错误:
'setCategory' is unavailable in Swift
在这种情况下,Swift 4.2 存在一个错误,这是 Xcode 10 的 SDK 中 AVFoundation 的一个问题,您可以通过编写一个 Objective-C 函数来解决它调用旧 API,因为它们在 Objective-C.
中仍然可用
在接下来的link中您可以阅读更多详细信息:
https://forums.swift.org/t/using-methods-marked-unavailable-in-swift-4-2/14949
作为解决方法,您可以使用 NSObject.performSelector:
:
调用 Objective-C AVAudioSession.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 中修复。
对于Swift4.2 in iOS12,就是:
try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [])
Xcode10.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)
}
swift4 的代码:
do {
try AKSettings.setSession(category: .playback, with: [])
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, mode: AVAudioSessionModeDefault, options: [])
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
希望对您有所帮助
将此粘贴到您的 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)
即使在静音模式下也能播放声音,我使用以下方法。但是它怎么不工作。
// 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#>)`
她的 der Töne 的评论向您展示了新语法,但您还需要在 setCategory
之后激活音频会话:
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
如果您的应用与 iOS 9 或更低版本不兼容,则以上答案(由 Rhythmic Fistman 提供)是正确的。
如果您的应用与 iOS9 兼容,您将看到下一个错误:
'setCategory' is unavailable in Swift
在这种情况下,Swift 4.2 存在一个错误,这是 Xcode 10 的 SDK 中 AVFoundation 的一个问题,您可以通过编写一个 Objective-C 函数来解决它调用旧 API,因为它们在 Objective-C.
中仍然可用在接下来的link中您可以阅读更多详细信息:
https://forums.swift.org/t/using-methods-marked-unavailable-in-swift-4-2/14949
作为解决方法,您可以使用 NSObject.performSelector:
:
AVAudioSession.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 中修复。
对于Swift4.2 in iOS12,就是:
try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [])
Xcode10.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
#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)
}
swift4 的代码:
do {
try AKSettings.setSession(category: .playback, with: [])
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, mode: AVAudioSessionModeDefault, options: [])
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
希望对您有所帮助
将此粘贴到您的 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)