How to pass protocol with associated type (generic protocol) as parameter in Swift?
If you use typealias
in a protocol to make it generic-like, then you cannot use it as a variable type until the associated type is resolved. As you have probably experienced, using a protocol with associated type to define a variable (or function parameter) results in a compilation error:
Protocol 'MyProtocol' can only be used as a generic constraint because it has Self os associated type requirements
That means you cannot use it as a concrete type.
So the only 2 ways I am aware of to use a protocol with associated type as a concrete type are:
- indirectly, by creating a class that implements it. Probably not what you have planned to do
- making explicit the associated type like you did in your func
See also related answer https://stackoverflow.com/a/26271483/148357
How to pass generic protocol as function parameter
You must use Datatype
as a generic constraint:
func set<T: Datatype>(key: String, type: T ,value: T.dataType)
Note how you also need to change the type of the value
parameter to T.dataType
, for this to be type safe. That is, the value you pass in must be the same type as the dataType
of the type
parameter.
Swift: How to pass the Generic protocol as a parameter for another protocol
protocol OperationDelegate {
associatedtype T
func onOperationFinished(result:Array<T>)
func onOperationError(error: Error, errorMessage:String)
}
protocol ResultDelegate {
func findResult<OpDelegate: OperationDelegate>(query: String, odelegate: OpDelegate)
}
//Added few PlayGround works
class ResultsFinder: ResultDelegate {
func findResult<OpDelegate>(query: String, odelegate: OpDelegate) where OpDelegate : OperationDelegate {
print(#function)
// Do some operations
let s1 = Student()
s1.name = "one"
let s2 = Student()
s2.name = "two"
let addressList = [s1,s2]
odelegate.onOperationFinished(result: addressList as! [OpDelegate.T])
}
}
also
class ResultDisplay: OperationDelegate {
typealias T = Student
func onOperationFinished(result: [Student]) {
// Display address
print(#function)
}
func onOperationError(error: Error, errorMessage: String) {
// Display error
print(#function)
}
}
class Mainfunction {
let resultDisplay = ResultDisplay()
let finder = ResultsFinder()
func start() {
print(#function)
finder.findResult(query: "Sridhar", odelegate: resultDisplay)
}
}
let main = Mainfunction()
main.start()
Swift protocol with associatedtype as a parameter type
You cannot use protocols with associated type as a field.
You have to use them only as an implementation of classes. In most cases, those classes should are generic.
For instance, this code is allowed:
public struct CreateNewAccount<T, K>: UseCase {
public typealias ResponseType = T
public typealias Parameters = K
}
and so,
private let createNewAccount: CreateNewAccount<YouClass1,YouClass2>
or wrap it somehow by another protocol.
SwifT: Generic function that gets generic protocol as parameter not working
I'm not sure why you say "the protocol only demands that Element implements CustomStringConvertible." The protocol demands that echo
accept and return its Element, which may or may not be String. For example, I can implement this conforming type:
struct AnotherFoo: FooProtocol {
func echo(element: Int) -> Int { fatalError() }
}
So what should happen if I then call:
callEcho(container: AnotherFoo())
This would try to pass a string literal to a function that requires an Int.
How to implement to a generic protocol, which has a function using the Type of associatedtype?
This isn't how associated types work. get
should be generic over its response type, but the network manager itself isn't generic over some specific response type. I believe what you meant to here is this:
protocol NetworkManager {
func get<ResponseObject>(url: String,
ofType: ResponseObject.Type,
completion: (Result<ResponseObject, Error>) -> Void)
where ResponseObject: Decodable
}
class TrivialNetworkManager: NetworkManager {
func get<ResponseObject>(url: String,
ofType: ResponseObject.Type,
completion: (Result<ResponseObject, Error>) -> Void)
where ResponseObject: Decodable {
completion(.success(SomeObject(id: "1", name: "hello"))
}
}
For a more worked-out version of this specific problem you can read my protocol series, but the important concept here is that NetworkManager doesn't vary over its ResponseType, so there's no reason to make its ResponseType an associated type.
What you wrote is trying to say "some network managers will have a Codable ResponseType, and other network managers will have some other kind of ResponseType." Not "some other specific response type (like User)" but "some other protocol that its response types would have to conform to." While it's conceivable to build something like that, it's much more complex, and you'd need to explain your precise use case in order to design it. Specifically, you'd need to show several concrete implementations of your protocol in order to see what kind of shared code you're trying to extract.
Use Protocol with associatedtype as a Type
Since ViewBuilder
is a protocol, when you try make T
a concrete type, it creates a conflict whether that type T
is HeaderTitleBuilder
or HeaderButtonBuilder
. T
cannot be both at the same time.
You can instead make both have a separate generic parameter, e.g,:
struct HeaderBuilder<TitleBuilder: ViewBuilder, ButtonBuilder: ViewBuilder> where TitleBuilder.In == DataSource, TitleBuilder.Out == ViewFactory, ButtonBuilder.In == DataSource, ButtonBuilder.Out == ViewFactory {
private(set) var titleBuilder: TitleBuilder
private(set) var buttonBuilder: ButtonBuilder
}
Related Topics
iOS 13 Strange Search Controller Gap
Iaps Actually Validating the Receipt (Swift)
Swift 3 and Firebase: Retrieve Auto Id Value from Snapshot
Proper Model for Multiple Alamofire Requests for Multiple Websites
Convert or Cast Object to String
How to Prove "Copy-On-Write" on String Type in Swift
Sprite-Kit: Moving an Element in Circular Path
Resetting Zone Allocator with Allocations Still Alive
Swift, Avaudiorecorder: Error 317: Ca_Debug_String: Inpropertydata == Null
A Different Bridging Between Array and Dictionary
How to Save Cgimage to Data in Swift
Uiimage Created from Mtkview Results in Color/Opacity Differences
How to Add Auto-Complete Comment in Xcode (Swift)