Last active
November 2, 2020 14:55
-
-
Save mrfarukturgut/460a20acdf0a78a4314611b1a3e1705f to your computer and use it in GitHub Desktop.
Generic delegation problem
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import Foundation | |
enum Endpoint { | |
case profile | |
} | |
protocol Fetchable { | |
static var endpoint: Endpoint { get } | |
} | |
struct ProfileResponse: Decodable { | |
var name: String? | |
} | |
extension ProfileResponse: Fetchable { | |
static var endpoint: Endpoint { | |
get { | |
return .profile | |
} | |
} | |
} | |
class API { | |
class func makeRequest<T: Fetchable>(to endpoint: Endpoint, ofType type: T.Type, completion: (Result<T, Error>) -> Void) { | |
let response = ProfileResponse(name: "Faruk") | |
completion(.success(response as! T)) | |
} | |
} | |
protocol ModelDelegate { | |
func dataFetched<T: Fetchable>(data: Result<T, Error>) | |
} | |
// Diğer isteklerden gelen datalar içinde aynı yapıyı kullanabilmek bu struct generic. | |
struct Model<T: Fetchable> { | |
private var data: T? | |
var delegate: ModelDelegate? | |
func fetch() { | |
guard let data = data else { | |
API.makeRequest(to: T.endpoint, ofType: T.self) { (result) in | |
self.delegate?.dataFetched(data: result) | |
} | |
return | |
} | |
self.delegate?.dataFetched(data: .success(data)) | |
} | |
} | |
class ProfileViewController: UIViewController, ModelDelegate { | |
var profileModel = Model<ProfileResponse>() | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
profileModel.delegate = self | |
} | |
func dataFetched<T>(data: Result<T, Error>) where T : Fetchable { | |
switch data { | |
case let .success(response): | |
print(type(of: response)) // Fetchable olarak geliyo | |
default: | |
break | |
} | |
// Buradaki ana olay şu, bu methodun bana direk olarak yukarda profileModel'i tanımlarken verdiğim generic type'ı | |
// - bu örnek için "ProfileResponse" olarak geliyor olması. Zaten temeldeki amaç buydu buna başlarken. | |
// ModelDelegate içindeki metod'u generic yapmayı da, associatedType kullanmayıda denedim fakat bir türlü sonuca ulaşamadım | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment