AVAudioSession setКатегория доступности в Swift 4.2 - PullRequest
0 голосов
/ 19 сентября 2018

После перехода на Swift 4.2 я получаю несколько ошибок, одна из которых странная.Похоже, ошибка в Xcode 10 , но есть ли обходной путь?

do {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playAndRecord, with: options)
} catch {
    NSLog("Could not set audio session category")
}

**** 'setCategory (_: with :)' недоступен вСвифт

Ответы [ 4 ]

0 голосов
/ 19 октября 2018

Проблема была решена в Xcode 10.2.


Для Xcode 10.1 с iOS 9 (и старше) единственное другое предлагаемое решение от Benno и должно полагаться либо на Objective-C, либо наperform(NSSelectorFromString("setCategory:error:")).К сожалению, данный код не позволяет красиво обрабатывать ошибки, поэтому я хотел бы представить решение, основанное на простом использовании Swift 4.1 в отдельной среде при использовании Xcode 10.1 (и оно будет работать, даже если ваш проект используетSwift 4.2).

Хитрость заключается в том, чтобы просто создать отдельный фреймворк (или lib) для переноса вызова на setCategory(_:), используя более старую версию Swift (например, 4.1).В этом случае вам нужно иметь только:

import AVFoundation

extension AVAudioSession {
    @available (iOS 3.0, tvOS 9.0, watchOS 2.0, *)
    @objc open func setCategorySwift(_ category: String) throws {
        try setCategory(category)
    }
}

(также доступно через pod 'AVAudioSessionSetCategorySwift')

Затем вернитесь к своему проекту Swift 4.2 (иpod install в конце концов), вы можете использовать его так же просто, как и setCategorySwift(AVAudioSession.Category.playback.rawValue).Более длинный пример с try-catch может быть:

import AVAudioSessionSetCategorySwift

let session = AVAudioSession.sharedInstance()
do {
    if #available(iOS 10.0, *) {
        try session.setCategory(AVAudioSession.Category.playback, mode: .default, options: [])
    } else {
        // Swift 4.2 workaround: https://github.com/coeur/AVAudioSessionSetCategorySwift
        try session.setCategorySwift(AVAudioSession.Category.playback.rawValue)
    }
    try session.setActive(true)
} catch {
    print("AVAudioSession.setCategory error: \(error)")
}
0 голосов
/ 20 сентября 2018

Я звоню setCategory(_:mode:options:).Параметр options: может быть опущен, и если у вас нет режима, вы можете использовать режим .default.

0 голосов
/ 20 сентября 2018

iOS 10 +

Если вы нацеливаетесь на iOS 10 + , просто перейдите на новый API и используйте:

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

Старые версии iOS

Когда вы попробуете это для приложения, ориентированного на более старую версию iOS (например, iOS 9) , вы получите setCategory(_:mode:options:)' is only available on iOS 10.0 or newer Ошибка.

Это было сообщено какошибка в Apple API и исправлена ​​в Xcode 10.2.Для более старых версий Xcode (например, Xcode 10.1) есть обходной путь, который я нашел.При создании помощника Objective-C, как описано, вы все равно можете получить доступ к старому API, потому что он все еще доступен для Objective-C.

Обходной путь 1: метод .perform ()

Если требуется быстрое встроенное исправление без обработки ошибок, вы можете вызвать API Obj.-C с помощью метода .perform():

if #available(iOS 10.0, *) {
  try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [])
} else { 
  // Set category with options (iOS 9+) setCategory(_:options:)       
  AVAudioSession.sharedInstance().perform(NSSelectorFromString("setCategory:withOptions:error:"), with: AVAudioSession.Category.playback, with:  [])

  // Set category without options (<= iOS 9) setCategory(_:)
  AVAudioSession.sharedInstance().perform(NSSelectorFromString("setCategory:error:"), with: AVAudioSession.Category.playback)
}

Обходной путь 2: Метод класса помощника

Вот шаги, как сделать это прямо сейчас, если вы хотите больше контроля над ошибками

  1. Создать новый *Файл 1033 * в моем случае AudioSessionHelper.m.Когда будет предложено создать файл заголовка моста, нажмите Да (если у вас его еще нет в вашем проекте)
  2. Создайте новый Header файл AudioSessionHelper.h
  3. Вставить код
AudioSessionHelper.h
#ifndef AudioSessionHelper_h
#define AudioSessionHelper_h
#import <AVFoundation/AVFoundation.h>

@interface AudioSessionHelper: NSObject
+ (BOOL) setAudioSessionWithError:(NSError **) error;
@end

#endif /* AudioSessionHelper_h */
AudioSessionHelper.m
#import "AudioSessionHelper.h"
#import <Foundation/Foundation.h>

@implementation AudioSessionHelper: NSObject

+ (BOOL) setAudioSessionWithError:(NSError **) error {
    BOOL success = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:error];
    if (!success && error) {
        return false;
    } else {
        return true;
    }
}
@end
Вставьте ваш вспомогательный класс в файл заголовка моста [PROJECT] -Bridging-Header.h
#import "AudioSessionHelper.h"
Используйте его в своем проекте Swift
if #available(iOS 10.0, *) {
    try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [])
} else {
    try AudioSessionHelper.setAudioSession()
}

Это не красиво и добавляет много ненужного кода и файлов в ваш проект, поэтому используйте его, если вы срочно хотите или должныиспользуйте Swift 4.2 на Xcode 10.1 прямо сейчас.Во всех остальных случаях вам лучше использовать Xcode 10.2.

0 голосов
/ 20 сентября 2018

Это проблема с AVFoundation в SDK Xcode 10.Вы можете обойти это, написав функцию Objective C, которая вызывает старый API, поскольку они все еще доступны в Objective C.Но если вы ориентируетесь только на iOS 10 или более позднюю версию, вы можете написать по-быстрому

do{
    if #available(iOS 10.0, *) {
        try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: options)
    } else {
        //the following line is now "unavailable", hence there is no way to support iOS <10
        //try AVAudioSession.sharedInstance().setCategory(.playAndRecord, with: options)
    }
} catch let error {
    print("Could not set audio session category: \(error.localizedDescription)")
}

Источник: Swift Forum

...