LoginSignup
0
1

More than 1 year has passed since last update.

AssociatedTypeを使ってみた

Posted at

Protocolを学んでいく上で、AssociatedTypeがなんなのかわからなかったため、メモ程度にここに記述。

AssociatedTypeとは?

Swiftでよく使うGenericsと同じように、Protocol内で定義する連想型のこと!
準拠時にどんな型にするかを指定することができる。

具体例

なんらかのAPIを叩く際!

まずは、protocolから定義!

APIRepository
    protocol APIConfigure {
    associatedtype ResponseEntity: Codable
    static var path: String { get }
    static func request(completion: ((ResponseEntity) -> ())?)
}

protocolにextensionを生やす!

APIRepository
extension APIConfigure {
    static func request(completion: ((ResponseEntity) -> ())?) {
        guard let url = URL(string: Self.path) else { return }
        let task = URLSession.shared.dataTask(with: url) { data, _, _ in
            guard let data = data, let responseEntity = try? JSONDecoder().decode(ResponseEntity.self, from: data) else {
                return
            }
            completion?(responseEntity)
        }
        task.resume()
    }
}

protocolに準拠したstructを作成する(structの中身は適当に作りました。)

APIClient
public struct APIClient {
    struct UserGet: APIConfigure {
        typealias ResponseEntity = User
        static let path = "https://qiita.com/api/v2/users/anies1212"
    }

    struct ItemsGet: APIConfigure {
        typealias ResponseEntity = [Item]
        static let path = "https://qiita.com/api/v2/items"
    }
}

struct User: Codable {
    let name: String

    init(name: String) {
        self.name = name
    }
}

struct Item: Codable {
    let name: String

    init(name: String) {
        self.name = name
    }
}

ViewControllerで実際に呼び出してみる!!

ViewController
class ViewController: UIViewController {

    private let userNameLabel: UILabel = {
        let label = UILabel()
        label.textColor = .label
        label.font = .systemFont(ofSize: 12, weight: .semibold)
        label.textAlignment = .center
        return label
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(userNameLabel)
        getResponse()
        view.backgroundColor = .white
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        userNameLabel.frame = CGRect(x: 0, y: 100, width: view.bounds.width, height: 50)
    }

    private func getResponse(){
        APIClient.UserGet.request {[weak self] user in
            DispatchQueue.main.async {
                self?.userNameLabel.text = user.name
            }
        }
    }
}

思ったこと

private func getResponse(){
        APIClient.UserGet.request {[weak self] user in
            DispatchQueue.main.async {
                self?.userNameLabel.text = user.name
            }
        }
    }

ViewController内でこんだけでレスポンスを呼べるのはとても便利だなと感じた。
protocolにassociatedTypeを持たせてあげるだけで、CodableなEntityである限り、なんでも共通のメソッドでレスポンスを呼べる!!

0
1
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
0
1