How to write generic function in Swift using a protocol associatedtype

Nik

I'm trying to write generic handler function which will receive ResourceModel instances and process them somehow:

func handleGeneric<R, M: ResourceModel>(resource: R, modelType: M.Type) {

I got stuck with Swift protocols usage though

This is the error I get:

Resource.playground:60:20: note: generic parameter 'R' of global function 'handleGeneric(resource:modelType:)' declared here
func handleGeneric<R, M: ResourceModel>(resource: R, modelType: M.Type) {

import UIKit

// Structs

struct ResourceA: Decodable {
    let id: Int
    let name: String
}

struct ResourceB: Decodable {
    let id: Int
    let number: Int
}

// Models

protocol ResourceModel {
    associatedtype R
    init(resource: R)
}

class ModelA: ResourceModel {
    var id: Int = 0
    var name: String = ""

    convenience required init(resource: ResourceA) {
        self.init()
        id = resource.id
        name = resource.name
    }
}

class ModelB: ResourceModel {
    var id: Int = 0
    var number: Int = 0

    convenience required init(resource: ResourceB) {
        self.init()
        id = resource.id
        number = resource.number
    }
}

// Save

func handleA(resource: ResourceA) {
    let m = ModelA(resource: resource)
    // save ... A ...
    print("handle A completed")
}

func handleB(resource: ResourceB) {
    let m = ModelB(resource: resource)
    // ... save B ...
    print("handle B completed")
}

// Generic handler

func handleGeneric<R, M: ResourceModel>(resource: R, modelType: M.Type) {
    let m = M.init(resource: resource)
    // ... save m ...
    print("handle generic completed")
}

// Download

func downloadA() {
    let r = ResourceA(id: 1, name: "A")
    handleA(resource: r)
}

func downloadB() {
    let r = ResourceB(id: 2, number: 10)
    handleB(resource: r)
}

downloadA()
downloadB()

The question is how can I implement the generic function I need? I.e.

handleGeneric<ResourceA, ModelA>(ResourceA(id: 1, name: "A"))
handleGeneric<ResourceB, ModelB>(ResourceB(id: 2, number: 10))
handleGeneric<ResourceC, ModelC>(ResourceC(id: 3, "foo": "bar"))
handleGeneric<ResourceD, ModelD>(ResourceD(id: 4, "egg": "spam"))

Upd

I tried

handleGeneric(resource: ResourceA(id: 1, name: "A"), modelType: ModelA.Type)
handleGeneric(resource: ResourceB(id: 2, number: 10), modelType: ModelB.Type)

But I get

Cannot convert value of type 'ResourceA' to expected argument type '_.R'

enter image description here

Lou Franco

Don't put R in the <> -- use M.R in your signature.

func handleGeneric<M: ResourceModel>(resource: M.R, modelType: M.Type) {

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to implement to a generic protocol, which has a function using the Type of associatedtype?

Using associatedtype in a delegate protocol for a generic type

Infer generic from any using protocol with associatedtype

return View in swift protocol function with associatedtype

Is there information somewhere on Swift protocol associatedtype using `=` versus `:`?

swift how to determine associatedtype in sub protocol

Swift generics: how to match associatedtype with generic parameter

Swift protocol with associatedtype error

How to make extension to protocol using associatedtype and array

How to check the concrete type of associatedtype of a protocol inside generic class?

How to write a generic Swift class function to initialize classes using a closure?

Swift protocol with associatedtype as a parameter type

how to use Void type in a closure of protocol with associatedtype in Swift

Swift using generic in protocol

Unable to use protocol as associatedtype in another protocol in Swift

How to write a generic apply() function in Swift?

Swift Generic Protocol Function Parameters

Using Generic swift enum in a protocol

Generic Decoder for Swift using a protocol

Swift protocol with associatedtype (ambiguous for type lookup)

Swift compiler crashes on associatedtype in @objc protocol

Protocol associatedType and <>

how to write a protocol that will run a function at specific time with - swift - SpriteKit

Swift Generic struct conform to protocol with associatedType got "Cannot convert return expression of type 'String' to return type 'Key'" Error

Cannot assign Generic value to protocol associatedType variable in an extension

Further constraining a generic function from a Swift Protocol

swift: How to write generic function that calls specialized ones

How do I write a generic recursive function that takes a CollectionType in Swift?

Implement delegate using generic protocol in Swift