【Swift】handlerとcompletionを変数/関数で作る

どうも、ねこきち(@nekokichi1_yos2)です。

 

Swiftには、コールバック、が存在します。

(例:handler, completion)

 

メリットは、

  • まとまった処理をブロックで持つ
  • コールバック元の処理が完了後に実行される
  • 非同期処理を順番に処理できる

の特性を持っていることです。

 

今回は、コールバックを変数や関数の形で作る方法、を備忘録として書きます。

 

解説

 

変数で定義

 

let presentHandler:() -> Void = {
    print("present")
}

 

 

let handler2 = { (value1:Int) -> Void in
    print(value1)
}

 

関数で定義

 

func alertAction(action: UIAlertAction) {
    label.isHidden = false
}
let alertController = UIAlertController(title: "アラート", message: "メッセージ", preferredStyle: .alert) alertController.addAction(UIAlertAction(title: "アクション", style: .default, handler: alertAction(action:))) present(alertController, animated: true, completion: nil)

UIAlertController > UIAlertAction > handler、を関数で定義。

 

ただし、関数側と代入する側で型(今回の場合、action:UIAlertAction)が同じである必要がある。

 

func handler3(value2:Int) -> Void {
    print(value2)
}

 

func executeHandler(completion: (Int)->Void) {
    completion(5)
}

引数にInt型を持ち、返り値がないコールバックを引数に指定。

 

completion内に記述した数字が、引数に指定したコールバックに渡され、コールバック内の処理が行われる

 

@IBAction func handler2Button(_ sender: Any) {
    //5を出力
    executeHandler(completion: handler2)
    executeHandler(completion: handler3)
}

handler2とhandler3は、Int型の引数value1,value2をprintで出力する処理を持ち、executeHandlerで5が渡されるので、5が出力される。

 

ソースコード

 

import UIKit

class handlerViewController: UIViewController {
    
    @IBOutlet weak var label: UILabel!
    
    //アラート
    @IBAction func alertButton(_ sender: Any) {
        let alertController = UIAlertController(title: "アラート", message: "メッセージ", preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "アクション", style: .default, handler: alertAction(action:)))
        present(alertController, animated: true, completion: nil)
    }
    
    //アラートのハンドラー
    func alertAction(action: UIAlertAction) {
//labelを非表示 label.isHidden = false } //進む @IBAction func presentButton(_ sender: Any) { let sb = UIStoryboard(name: "Main", bundle: Bundle.main) let vc = sb.instantiateViewController(withIdentifier: "handler2") as! handler2ViewController //presentのハンドラー let presentHandler:() -> Void = {
//"present"を出力 print("present") } present(vc, animated: true, completion: presentHandler) } }

 

import UIKit

class handler2ViewController: UIViewController {
let handler2 = { (value1:Int) -> Void in print(value1) } func handler3(value2:Int) -> Void { print(value2) }
//引数のハンドラーを実行 func executeHandler(completion: (Int)->Void) { completion(5) } @IBAction func handler2Button(_ sender: Any) { //5を出力 executeHandler(completion: handler2) executeHandler(completion: handler3) } //dismissのハンドラー func dismissHandler() -> Void { print("dismiss") } //戻る @IBAction func dismissButton(_ sender: Any) { dismiss(animated: true, completion: dismissHandler) } }

 

参考

 

qiita.com

qiita.com