LoginSignup
1
4

More than 1 year has passed since last update.

【Swift】Swiftでカスタムデレゲートを作成する方法

Posted at

Swiftでプロトコルを定義し、Delegateを作成することで、Delegateパターンの使用方法を学びます。

Delegate パターンは、Delegation とも呼ばれ、Swift コードや Apple ライブラリで頻繁に見られるアーキテクチャパターンです。この記事では、Delegation の概要と、Swift でカスタム delegate を作成する例を紹介します。

  1. Swift の Delegate パターン
  2. デリゲートプロトコルの作成
  3. デリゲートプロトコルを拡張する
  4. カスタムデレゲートの実装
  5. カスタムデレゲートを使用する方法
  6. オプションのデリゲートメソッドを作成する

1. Swift の Delegate パターン

Delegateという名前は、制御を委譲する(他の何かに制御を与える)という概念に由来しています。Swiftでは、デリゲートは、別のオブジェクトの動作を制御または修正するために使用できる、定義されたインターフェイスを持つコントローラオブジェクトです。

1つの例は、iOSアプリの UIApplicaitonDelegate です。iOS システムは、UIApplicaitonDelegate を使用して、プッシュ通知の受信、 URL を開く、アプリケーションを起動するなどの iOS の動作を変更します。

2. デリゲートプロトコルの作成

カスタムデリゲートを作成するための最初のステップは、デリゲートプロトコルを作成することです。プロトコルは、カスタムデリゲートが実装しなければならないインターフェース、変数と関数のセットです。

// ViewActionDelegateというカスタムプロトコルを定義する
protocol ViewActionDelegate {
    // 期待されるデリゲート変数を定義する
    var state: ViewState { get }
    var userID: String? { get set }

    // 期待されるデリゲートブロックの定義
    var errorHandler: ((Error) -> Void)? { get set }

    // 期待されるデリゲート関数の定義
    func handle(action: ViewAction)
}

ViewActionDelegateの定義、および以下のコード例では、ViewStateViewActionの列挙を使用しています。

enum ViewState {
    case `default`
    case loading
}

enum ViewAction {
    case save
    case cancel
}

3. デリゲートプロトコルを拡張する

デリゲートは、他の Swift の型と同様に、計算変数と関数を追加するために拡張することができます。

// ViewActionDelegate を拡張する
extension ViewActionDelegate {
    // 計算変数の定義
    var isReadyForNextAction: Bool {
        return state != .loading
    }
}

4. カスタムデレゲートの実装

次のステップは、カスタムデリゲートViewActionDelegateに準拠したクラスまたは構造体を作成することです。まず、classstruct を定義し、そのclassstruct を拡張してデリゲートに対応させるというのがきれいなやり方です。

// ActionController クラスの定義
class ActionController {
    // デリゲートプロトコル定義に合致する変数を定義する
    var state: ViewState = .default
    var userID: String?
    var errorHandler: ((Error) -> Void)?
}
// ActionControllerを拡張し、デリゲートに準拠させる。
extension ActionController: ViewActionDelegate {
    // デリゲートプロトコル定義で要求される機能を実装する。
    func handle(action: ViewAction) {
        switch action {
        case .save:
            break
        case .cancel:
            break
        }
    }
}

5. カスタムデレゲートを使用する方法

最後に、カスタムデリゲートを使用します。この例では、ActionViewという UIView を作成し、ViewActionDelegateを使用して動作を変更します。

以下の例では、ActionViewのオプションのデリゲート参照を使用していますが、オプションの参照は(メモリ管理の点から) weak です。

class ActionView: UIView {
    // デリゲートへの参照を保持するためのオプション変数を作成します。
    var delegate: ViewActionDelegate?

    // デリゲートのhandle(action:)の実装に基づいて、saveの動作を変更する。
    @IBAction func save() {
        guard let delegate = delegate else { return }
        guard delegate.isReadyForNextAction else { return }

        delegate.handle(action: .save)
    }

    // デリゲートの errorHandler に基づいて handle(error:) の動作を変更する。
    func handle(error: Error) {
        delegate?.errorHandler?(error)
    }
}

ActionViewdelegateプロパティを使って動作を変更することで、カスタムデリゲートの実装は完了します。ここでは、ActionControllerをカスタマイズして、ActionViewdelegateプロパティに割り当てている。

class ActionViewController: UIViewController {
    var actionView = ActionView()
    var actionController = ActionController()

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        // actionController の設定
        actionController.userID = "@robert"
        actionController.errorHandler = { (error) in
            // ハンドルエラー
        }

        // actionViewのデリゲートとしてactionControllerをアサインします。
        actionView.delegate = actionController
    }
}

6. オプションのデリゲートメソッドを作成する

Objective-C のデリゲートは、オプションのメソッドを持つことができます。Swift では、@objc 修飾子を使用して、プロトコルを Objective-C のプロトコルとしてマークすることができます。プロトコルを @objc としてマークした後、特定のプロトコル関数を @objc でマークすることができ、マークした関数上でoptional修飾子を使用することができます。

// Swiftで@objcデリゲートを定義する
@objc protocol ViewActionDelegate {
    // オプションのデリゲート関数を作成する
    @objc optional func ignoreActions() -> Bool
}

オプションのデリゲートメソッドを実装し、アプリケーションで呼び出すことができます。

if delegate.ignoreActions?() == true {
    // ハンドルケース
}

Swiftでカスタムデリゲートを実装する

以上です。デリゲーションを使用し、Swift でカスタムデリゲートを作成することで、オブジェクトの動作をカスタマイズし、アプリの複雑さをよりよく管理することができます。

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4