web-dev-qa-db-ja.com

保存されたプロパティで@availableを使用する

ローカル通知を使用し、iOS 10をサポートするアプリを持っています。iOS9のサポートを追加しようとしていますが、古い位置通知APIを使用する必要があります。 iOS 10のコードで@availableと#availableを使用しようとしていますが、中心変数をiOS 10を実行しているデバイス専用にする方法を理解できません。

ターゲットをiOS 10から9に設定すると、この変数のエラーメッセージ「UNUserNotificationCenterはiOS 10.0以降でのみ使用できます」が表示されます。これは、クラス全体に「@available(iOS 10.0、*)」を追加したくないことを示唆しています。このクラスには、iOS 9で使用されるコードがあるためです。センタープロパティをiOS 10に設定します。

class ViewController: UIViewController, UITextFieldDelegate {

  let center = UNUserNotificationCenter.current()
  ...
18
chickenparm

_@available_は、クラス全体または1つ以上の関数の周囲で使用できますが、プロパティでは使用できません。

UNUserNotificationCenterの使用法に関しては、currentは変更されないシングルトンを返すので、center定数を削除し、UNUserNotificationCenter.current()を使用するだけで、centerは中古?

3
James Chen

以下は、可能性のある解決策です( blog post に感謝します)。

タイプはAnyの格納プロパティを使用し、格納プロパティをキャストする(必要に応じてインスタンス化する)計算プロパティを作成するという考え方です。

private var _selectionFeedbackGenerator: Any? = nil
@available(iOS 10.0, *)
fileprivate var selectionFeedbackGenerator: UISelectionFeedbackGenerator {
    if _selectionFeedbackGenerator == nil {
        _selectionFeedbackGenerator = UISelectionFeedbackGenerator()
    }
    return _selectionFeedbackGenerator as! UISelectionFeedbackGenerator
}
27
kgaidis

これは古い質問であることはわかっていますが、私と同じようにGoogle経由でここに来た人のために回答を追加したいと思います。

KgaidisとCœurが述べたように、計算されたプロパティで_@available_を使用できます。ただし、lazy変数は計算されたプロパティと見なされるため、それらに対して_@available_を使用することもできます。これには、余分に保存されたプロパティと強制キャストの定型文を削除するという素晴らしい利点があります。実際、iOS 10より前のコードにはプロパティの証拠が残りません。

次のように宣言するだけです。

_@available(iOS 10.0, *)
lazy private(set) var center = UNUserNotificationCenter.current()
_

残念ながら、完全に読み取り専用にする方法はありませんが、private(set)を使用すると、クラス外では少なくとも読み取り専用になります。

18
Jayson

Kgaidisと同様のアイデアで、どのバージョンでも受け入れられるタイプの個別の保存プロパティを使用します。ただし、Anyは、たとえばweakと宣言できないため、汎用的すぎる可能性があります。そのため、状況によっては、準拠するプロトコルに置き換える必要があります。

private weak var _notificationCenterDelegate: NSObjectProtocol?
@available(iOS 10.0, *)
var notificationCenterDelegate: UNUserNotificationCenterDelegate? {
    return _notificationCenterDelegate as? UNUserNotificationCenterDelegate
}
1
Cœur

IOS 9をサポートするアプリでフィードバックジェネレーターに使用するコードは、ご覧のとおり、シンプルでフォースキャストがありません。主なアイデアは、Any?プロパティに値を格納し、計算された値を介してそれを使用することです。

private var storedFeedbackGenerator: Any? = nil
@available(iOS 10.0, *)
private var feedbackGenerator: UISelectionFeedbackGenerator {
    if let generator = storedFeedbackGenerator as? UISelectionFeedbackGenerator {
        return generator
    }

    let generator = UISelectionFeedbackGenerator()
    generator.prepare()
    storedFeedbackGenerator = generator
    return generator
}
0