Чтобы воспроизводить звук даже в беззвучном режиме, я использую метод ниже. Но как это не работает.
// 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#>)`
Для таких опций, как mixWithOthers, см. stackoverflow.com/a/39084300/434004, обновленный для Swift 4.2.
Этот метод был снова добавлен в Xcode 10.2.





Комментарий ее дер Тёне показывает вам новый синтаксис, но вам также необходимо активировать аудиосеанс после setCategory:
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
Вышеупомянутое решение заставляет отказаться от совместимости приложения с устройствами iOS 9. Есть ли способ вернуть совместимость с iOS 9?
Уверены ли вы? setCategory() доступен с iOS 6, а setActive() / sharedInstance() - с iOS 3.
@RhythmicFistman да, можешь проверить здесь, это только iOS 10+
Ха, это работает, если вы вызываете код с помощью Objective-C? Ой, подождите, я вижу проблему - есть setCategory:withOptions (все равно ваш режим по умолчанию) - хотя я не уверен, как он называется в быстром.
Ой, это плохо. Сделайте это в Objective-C - AVAudioSession в любом случае является отличным, малозатратным синглтоном, и его быстрые настройки не улучшат его (в данном случае - наоборот).
Спасибо, Гэлвин! Не видел вашего комментария (давно !!)
выдает ошибку Ошибка члена строки: попробуйте AVAudioSession.sharedInstance (). setCategory (.playback, mode: .default)
Большое спасибо. Предложение по автоматическому преобразованию Xcode из Swift 3 в Swift 4.2 не помогло в этом случае.
Приведенный выше ответ (от Rhythmic Fistman) верен, если ваше приложение несовместимо с iOS 9 или ниже.
Если ваше приложение совместимо с iOS 9, вы увидите следующую ошибку:
'setCategory' is unavailable in Swift
В этом случае есть ошибка Swift 4.2, это проблема с AVFoundation в SDK Xcode 10, вы можете обойти ее, написав функцию Objective-C, которая вызывает старый API, поскольку они все еще доступны в Objective -C.
По следующей ссылке вы можете прочитать более подробную информацию:
https://forums.swift.org/t/using-methods-marked-unavailable-in-swift-4-2/14949
В качестве обходного пути вы можете вызвать метод 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)
}
Если вы хотите установить категорию и параметры для iOS 9 и более ранних версий, используйте:
AVAudioSession.sharedInstance().perform(NSSelectorFromString("setCategory:withOptions:error:"), with: AVAudioSession.Category.playback, with: [AVAudioSession.CategoryOptions.duckOthers])
Проблема исправлена в Xcode 10.2.
Хорошо, а как насчет параметра 'options'? Как заменить AVAudioSession.sharedInstance (). SetCategory (.playback, mode: .default, options: [.duckOthers])?
@Fallstreak попробуйте установить категорию и параметры, например AVAudioSession.sharedInstance().perform(NSSelectorFromString("setCategory:withOptions:error:"), with: AVAudioSession.Category.playback, with: [AVAudioSession.CategoryOptions.duckOthers]). Это работает?
Да, это так. Спасибо друг.
выполнить (NSSelectorFromString ("") рискованно. Я бы не стал делать это в производственном приложении
@Mallox, конечно, вы бы: нет более безопасной альтернативы, не так ли?
@ Cœur Надеюсь, мой ответ может помочь. stackoverflow.com/a/52753594/2446684
@Galvin, использующий Objective-C, уже был предложен Хосе М. Гавиланом, и не делает его более безопасным, чем жестко запрограммированный селектор строк.
@ Cœur О, ты прав. Я не прочитал всю ветку внутри ссылки. Но я все же считаю, что это безопаснее, чем жестко запрограммированная строка. Жестко запрограммированная строка всегда небезопасна. Компилятор не может ничего проверить, если кто-нибудь его изменит.
@Galvin, если кто-то может изменить ваши исходные файлы незаметно для вас, у вас проблема посерьезнее.
@galvin Даже если вы работаете в команде, если кто-то может изменять ваши исходные файлы без вашего ведома, у вас есть более серьезная проблема.
Исправлено в Xcode 10.2: больше нет необходимости в perform(NSSelectorFromString(.
Для Swift 4.2 в iOS 12 это просто:
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
Затем импортируйте "AVAudioSession + Swift.h" на свой <#target_name#>-Bridging-Header.h.
#import "AVAudioSession+Swift.h"
В результате вы можете вызвать метод так же быстро, как и раньше.
do {
try AVAudioSession.sharedInstance().setCategory(.playback)
try AVAudioSession.sharedInstance().setCategory(.playback, options: [.mixWithOthers])
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
Это лучшее решение. Я использовал, и это работало. Теперь Apple решила исправить проблему в Xcode 10.2, поэтому в этом больше нет необходимости. На самом деле это делает вызов неоднозначным, поэтому мне пришлось его удалить. Спасибо Apple за то, что мою историю git нельзя компилировать в новейшем Xcode :)
Исправлено в Xcode 10.2: больше нет необходимости в этом обходном пути.
Я использую 10.2.1 и до сих пор не могу получить этот метод. даже после добавления файлов objC.
Код для 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)
}
надеюсь, это поможет
Вставьте это в свой viewDidLoad()
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: [])
try AVAudioSession.sharedInstance().setActive(true)
}
catch {
print(error)
}
вы также можете добавить этот код в файл AppDelegate.swift. ниже метод func application (_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {}
//Swift 4.2
if #available(iOS 10.0, *) {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback,
mode: AVAudioSessionModeDefault)
} else {
//Fallback on earlier versions
}
Привет, добро пожаловать в Stack Overflow. Пожалуйста, редактировать свой ответ, чтобы объяснить свой код. Заранее спасибо.
Swift 5
let audioSession = AVAudioSession.sharedInstance()
_ = try? audioSession.setCategory(.playback, options: .defaultToSpeaker)
_ = try? audioSession.setActive(true)
не работает! .playback вызывает ошибку Error Domain=NSOSStatusErrorDomain Code=-50 "(null)". Переход на .playAndRecord действительно помогает.
Насколько я могу судить из документации, я думаю, что это должно работать так:
AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [])