Can i pass protocol type to generic class - swift

I have a protocol A and there are multiple structs conforming to protocol A. I need to store different struct objects in a collection. But my collection type is predefined by another service, which is of type - class Storage<Value:Codable>. I can't pass in Value type as A, and it throws an error saying Protocol A does not conform to type Decodable. I just want to know if this is a right approach passing a custom protocol and can i make a custom protocol conform to Codable Protocol. Sample code snippet.
Any thoughts would be helpful
class Storage<Value: Codable>{}
protocol A {}
struct Type1: A, Codable, Equatable, Comparable {}
struct Type2: A, Codable, Equatable, Comparable {}
let storage = Storage<A>() // Throws error - Type 'A' does not conform to protocol 'Decodable'

use basic class
class Storage<Value: Codable>{}
protocol A {}
class Type: A, Codable {}
class Type1: Type, Equatable, Comparable {}
class Type2: Type, Equatable, Comparable {}
let storage = Storage<Type>()

Related

How can I use a generic-type constraint extension for a class with a `Codable` type constraint?

Say my class definition is:
class Foo<T: Codable> {
let bar: T
}
I want to extend arrays of this type:
extension Array where Element: Foo<Codable> { /* do something based on `bar` values */ }
This produces the error
Protocol 'Codable' (aka 'Decodable & Encodable') as a type cannot conform to 'Decodable'
I did read in another question that conforming T to Encodable/Decodable isn't possible if T == Encodable/Decodable since a protocol can't conform to itself, but this is only for a certain property so I'm having trouble wrapping my head around it. Is there any way to achieve this?
I think is better to use protocol instead class like this.
protocol FooProtocol {
associatedtype T : Codable
var bar: T {get set}
}
extension Array where Element: FooProtocol {
}

Multiple constraints on parameter of a generic function

Reading about generic functions in Swift, I see that it is possible to put some constraints on a parameter by requiring, that it is a subclass of a given class C, or that it implements a given protocol P.
But I wonder if there is a way to require both at the same time. I haven't found anything about that yet.
Does anyone know?
Actually You can do that.
If you have seen Codable in swift it is actually Decodable and Encodable
typealias Codable = Decodable & Encodable
So in some function if you are using generic T as Codable
struct StructOfCodable<T:Codable>: Codable {
....
}
Here is example
protocol Test {}
class TClass {
}
typealias Common = Test & TClass
func generic <T:Common>(method:T) {
}
Another way is protocol and class both can have super class. So you can create common protocol
like
protocol CommonInProtocolAndStruct { }
protocol ProtocolUsedAsConstraint:CommonInProtocolAndStruct {}
struct StructUsedAsConstraint:CommonInProtocolAndStruct {}
And any method you can use CommonInProtocolAndStruct as generic constraint
You can add any number of type constraints using a where clause. Examples:
import UIKit
func f<T>(t: T) where T: UIView, T: Encodable {}
class C<T> where T: UIView, T: Encodable {}

Swift 4 - Subclass Generic Constraint from associatedtype

I'd like to write a Swift protocol that requires a type to specify a base class and implement methods that operate on subclasses of that base class. Here's what that might look like (doesn't compile):
protocol Repository {
associatedtype BaseModel
//T must subclass BaseModel
func all<T: BaseModel>(from type: T.Type) -> [T]
}
But this generates the following compiler error:
Inheritance from non-protocol, non-class type 'Self.BaseModel'
This makes sense, because BaseModel could be specified with a struct type and subclassing wouldn't be allowed. So I tried creating an empty protocol, constrained to classes, to try to inform the compiler that this type will be a class type and allow a subclass constraint.
protocol Model: class { }
Then I constrained the BaseModel type using the Model class protocol:
associatedtype BaseModel: Model
But this generates the same compiler error from above. Is it possible to enforce a subclass constraint from an associatedtype on a protocol? I would expect the above to compile or for Swift to allow something like the following to allow subclass constraints:
associatedtype BaseModel: class
Associated Types should be used when type is unknown before the protocol is implemented. But if type is known no need to use associated type. I guess you could do this.
protocol Model: class { }
class BaseModel : Model { }
protocol Repository {
func all<T : BaseModel>(from type: T.Type) -> [T]
}

How do I specify a typealias of a scene conforming to a specific protocol?

I want to define a type which refers to only objects which are:
Members of a subclass of a given class
Conform to a specific protocol
How can I specify such a type? For instance, I'd like to be able to do something like this:
//Define a class
class MyClass {}
//Define a protocol
protocol MyProtocol {}
//Define an extension specific to this class and protocol
extension MyProtocol where Self : MyClass {}
//This works for multiple protocols, but not a class and a protocol
typealias MyAlias = MyClass & MyProtocol

Swift: type does not conform to protocol

protocol A {}
protocol B {
var a: A { get }
}
struct StructA: A {}
struct StructB {
var a: StructA
}
extension StructB: B {}
This produces the error :
Type 'StructB' does not conform to protocol 'B'
The StructA already conform to protocol A, and StructB's property a return StructA type. That seems pretty a protocol B conformed type.
But why?
Xcode version 7.3 which Swift version is 2.2
To better illustrate the problem with your current code, let's say you have a StructC : A.
Your protocol B says that you can assign StructC to a (as it conforms to A) – but StructB says you cannot assign StructC to a StructA type. Therefore StructB doesn't conform to B.
The solution is either to change the type of a from StructA to A as Rahul says, or better yet, you could use generics.
The advantage of using generics is once you create your StructB with a given a – that property's type will be inferred by Swift, giving you better type safety. For example, once you assign a StructA to it, its type will then be StructA. If you assign a StructC to it, its type will be StructC.
To do this, we just have to add an associatedtype to protocol B. This will define a 'placeholder' type that we can then implement in a type that conforms to B. We can then define the generic type T in StructB that will provide the 'implementation' of AType – making sure it conforms to A. Therefore, we are now free to assign either StructA or StructC to a, without losing type safety.
protocol A {}
protocol B {
// new associated type to hold the type of "a" which conforms to A
associatedtype AType:A
var a: AType { get }
}
struct StructA: A {}
struct StructC:A {}
// define the new generic T which conforms to A
struct StructB<T:A> {
// define the type of a as the generic T, which conforms to A (and thus conforms with the protocol)
var a : T
}
extension StructB: B {}
let s = StructB(a: StructA())
s.a // "a" is now of type StructA
let s1 = StructB(a: StructC())
s1.a // "a" is now of type StructC
Because Swift is statically typed and does not depend on dynamic dispatch. You could do something like below.
import UIKit
protocol A {}
protocol B {
var a: A { get }
}
struct StructA: A {}
struct StructB {
var a: A = StructA()
}
extension StructB: B {}
I am reworking this code from swift 3.0.
extension WallPost: PFSubclassing {
static func parseClassName() -> String {
return "WallPost"
}
}
This generates the error:
Type 'WallPost' does not conform to protocol 'PFSubclassing'
Unavailable class method 'object()' was used to satisfy a requirement of protocol 'PFSubclassing'
Any idea of why this is happening and how I can resolve it? I wanted to fix this before updating to swift 4.0 / 5.0
Thanks so much for the help!