Swift 4.2に移行した後、複数のエラーが発生しています。そのうちの1つは奇妙です。 Xcode 1のバグのようですが、回避策はありますか?
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playAndRecord, with: options)
} catch {
NSLog("Could not set audio session category")
}
**** 'setCategory(_:with :)'はSwiftでは使用できません
ターゲティングしている場合iOS 10 +、新しいAPIに移行して使用するだけです:
_try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [])
_
古い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ヘルパーを作成する場合、Objective-Cにまだ公開されているため、古いAPIにアクセスできます。
エラー処理なしで迅速なインライン修正が必要な場合は、.perform()
メソッドを使用してObj.-C APIを呼び出すことができます。
_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)
}
_
エラーをさらに制御したい場合、今すぐそれを行う方法の手順を次に示します
Objective-C
_という新しい_AudioSessionHelper.m
_ファイルを作成します。ブリッジングヘッダーファイルを作成するかどうかを確認するメッセージが表示されたら、Yesをクリックします(プロジェクトにまだない場合)Header
ファイルを作成します_AudioSessionHelper.h
__#ifndef AudioSessionHelper_h
#define AudioSessionHelper_h
#import <AVFoundation/AVFoundation.h>
@interface AudioSessionHelper: NSObject
+ (BOOL) setAudioSessionWithError:(NSError **) error;
@end
#endif /* AudioSessionHelper_h */
_
_#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
_
_#import "AudioSessionHelper.h"
_
_if #available(iOS 10.0, *) {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [])
} else {
try AudioSessionHelper.setAudioSession()
}
_
これは美しくなく、プロジェクトに多くの不必要なコードとファイルを追加するので、すぐにXcode 10.1でSwift 4.2を使用したい場合に使用します。他のすべての場合は、 Xcode 10.2を使用したほうが良いでしょう。
これは、Xcode 10のSDKのAVFoundationの問題です。古いAPIは引き続きObjective-Cで使用できるため、古いAPIを呼び出すObjective-C関数を記述することで回避できます。ただし、iOS 10以降のみをターゲットにしている場合は、Swiftで記述できます
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
私がすることは、setCategory(_:mode:options:)
を呼び出すことです。 options:
パラメーターは省略できます。モードがない場合は、.default
のモードを使用できます。
この問題はXcode 10.2で解決されました。
IOS 9(およびそれ以前)を搭載したXcode 10.1の場合、提案されている他の唯一のソリューションはBennoからであり、Objective-Cまたはperform(NSSelectorFromString("setCategory:error:"))
に依存することです。残念ながら、指定されたコードではエラーをうまく処理できないため、Xcode 10.1を使用する場合に別のフレームワークでSwift 4.1に単純にフォールバックすることに依存するソリューションを導入したいと思います。プロジェクトでSwift 4.2)を使用している場合でも機能します。
トリックは単に、古いバージョンのSwift(4.1など)を使用してsetCategory(_:)
への呼び出しをラップするために、別のフレームワーク(またはlib)を構築することです。このフレームワークでは、持つ必要がある:
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)
のように簡単に使用できます。 、 多分:
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)")
}