Swift Generics and Protocols not working on UIKit [possible bug]
That's correct behavior from the documentation point of view, because:
Method in a generic class cannot be represented in Objective-C
Reply to @Bell App Lab comment:
Open this page and scroll down to Lightweight Generics. Here's note:
Aside from than these Foundation collection classes, Objective-C
lightweight generics are ignored by Swift. Any other types using
lightweight generics are imported into Swift as if they were
unparameterized.
It basically says that generics (ObjC -> Swift) are imported only for Foundation collection classes and rest is ignored - IOW imported as if they are unparameterized.
Maybe we can expect some improvement in this area in the future, but I doubt it.
Swift Generics and Protocol Extensions
That's an interesting problem. Your code seems like it should work; you might want to file an enhancement request.
Here's a workaround that seems to work correctly:
class SomeGenericClass<CellType: Cell> {
func someFunction() {
let reuseIdentifier = (CellType.self as Reusable.Type).reuseId()
}
}
EXC_BAD_ACCESS when creating an object with Generics, Protocols and Inheritance in Swift
Update Swift 1.2 XCode 6.3 Beta 2 (Beta 1 will not work):
Your code now runs without any problems and the expected result:
var b = creation(x: B.self); //{__lldb_expr_9.SecondBase}
var a = creation(x: A.self); //{__lldb_expr_11.FirstBase}
They conflict because FirstBase has no init but EmptyInit a required init.
This way it will work:
protocol EmptyInit {
init();
}
class FirstBase {
required init(){
}
}
class SecondBase : EmptyInit {
required init(){
}
}
class A : FirstBase, EmptyInit{
required init(){
}
}
class B : SecondBase, EmptyInit {
required init() {
}
}
A();
B();
func creation<T: EmptyInit>(x a:T.Type) -> T{
var object = T()
return object;
}
var b = creation(x: B.self); // SecondBase
var a = creation(x: A.self); // FirstBase
Is it possible to pass generic protocols into a constructor for proper Dependency Injection in Swift 3?
The answer to your question is yes it is definitely possible, just that it currently requires some PAT-related "magic". With Swift3 and Xcode 8.0 beta 4, you should be able to run the following in a playground:
protocol Persistable {
var id: Int { get set }
}
protocol RepositoryProtocol: class {
associatedtype Object: Persistable
func insert(_ object: Object) -> Void
func deleteAll()
}
protocol ZombieServiceProtocol {
associatedtype RepositoryType: RepositoryProtocol
var zombieRepository: RepositoryType { get set }
func fetchZombies()
}
public struct Zombie: Persistable {
var id: Int
let name: String?
}
// Mocks
class RepositoryMock<Object: Persistable>: RepositoryProtocol {
func insert(_ object: Object) { print("look, there's another one!")}
func deleteAll() { print("it's safe out there, all zombies have been deleted") }
}
struct ZombieServiceMock<RepositoryType: RepositoryProtocol
where RepositoryType.Object == Zombie>: ZombieServiceProtocol {
var zombieRepository: RepositoryType
init(zombieRepository: RepositoryType) {
self.zombieRepository = zombieRepository
}
func fetchZombies() {
self.zombieRepository.deleteAll()
self.createMockZombies()
}
private func createMockZombies() {
for index in 1...5 {
let zombie = Zombie(id: index, name: "Zombie \(index)")
self.zombieRepository.insert(zombie)
}
}
}
// Tests
class ZombieServiceTests<RepositoryType: RepositoryProtocol,
ServiceType: ZombieServiceProtocol
where ServiceType.RepositoryType == RepositoryType> {
private var zombieRepository: RepositoryType
private var zombieService: ServiceType
init(repository: RepositoryType, service: ServiceType) {
zombieRepository = repository
zombieService = service
}
func testExample() {
self.zombieService.fetchZombies()
}
}
let repositoryMock = RepositoryMock<Zombie>()
let repositoryService = ZombieServiceMock(zombieRepository: repositoryMock)
let zombieTest = ZombieServiceTests(repository: repositoryMock, service: repositoryService)
zombieTest.testExample()
// Prints:
// it's safe out there, all zombies have been deleted
// look, there's another one!
// look, there's another one!
// look, there's another one!
// look, there's another one!
// look, there's another one!
Related Topics
Error While Using Property 'Cgrectgetwidth', It Says It Was Replaced with 'Cgrect.Width'
Bulk Fix Hundreds of "#Selector Not Exposed to Objective-C" Errors in Xcode 9 or 9.1
Error: Argument Type Double/String etc. Does Not Conform to Expected Type "Anyobject"
Xcode 7.1 Beta: Content of File Error
How to Perform Conditional Segue
What Is a Good or Common Way to Structure a Cli Appliction in Swift
Generate Labels and Align in Middle
How to Change Uitextfield Keyboard Type to Email in Swift
How to Call Swiftui Navigationlink Conditionally
Why Does the Compiler Not See the Default Code in a Protocol
Autoscrolling Infinite Effect in .Linear Type of Icarousel in Swift
New Value Is Only Available in Sendasynchronousrequest - Swift
Why Can't I Use 'Type' as the Name of an Enum Embedded in a Struct
How to Pass Closure as a Parameter in Perform(Selector, Withobject)
How to Use Querystartingatvalue in My Searchcontroller to Search for Users