Cannot convert value of type "AProtocol".Protocol to expected argument type Protocol - swift

I'm trying to build a protocol for a NSXPCInterface and I'm facing a weird issue.
I created a protocol :
public protocol AProtocol {
//functions in here
}
and when I want to add it to the exportedInterface of NSXPCConnection,
let newConnection: NSXPCConnection
newConnection.exportedInterface = NSXPCInterface(with: AProtocol.self)
I get this strange error :
Cannot convert value of type 'AProtocol.Protocol' to expected argument type 'Protocol'

I don't know the reason but its working try this. Add #objc before protocol
#objc public protocol AProtocol {
//functions in here
}
don't forget to initialise NSXPCConnection
Edit: found reason from here
"#objc" that exposes the protocol to the objective c runtime and allows us to pass any "Protocol Type" as a parameter

The protocol you pass to an instance of NSXPCInterface has to be an Objective-C protocol as described in the documentation:
protocol: The Objective-C protocol that this interface is based on.
So all you have to do is mark AProtocol with #objc
#objc public protocol AProtocol {
}

Related

Create interface with generic types

I'm trying to create public interface for my class operating on generics.
I've created interface
public protocol StorageProtocol {
associatedtype StorageObject: Codable
func store(storeObject: StorageObject)
func get() -> StorageObject?
}
and implementation
public class Storage<T: Codable>: StorageProtocol {
public func store(storeObject: T) {}
public func get() -> T?
Now, when I try to create instance it forces me any keyword
let myStorage: any StorageProtocol = Storage<Credentials>()
and I can't call storage.store(storeObject: Credentials()) as I'm getting error:
Associated type 'StorageObject' can only be used with a concrete type or generic parameter base.
What I'm missing here?
The compiler does not know what type to require in the parameter storeObject when you constrain myStorage to be any StoreageProtocol, as the generic StorageObject could be any Codable object. A workaround could be to explicitly add a parameter for the type of the generic.
public protocol StorageProtocol<StorageObject> { // add a generic parameter
associatedtype StorageObject: Codable
func store(storeObject: StorageObject)
func get() -> StorageObject?
}
and then when you define the variable
let myStorage: any StorageProtocol<Credentials> = Storage<Credentials>()
Then the compiler will know you want to store Credentials for this variable and allow you to call store as you specialized the protocol to the correct type.

How to add a protocol which contains associatedtype as a property in another protocol? [duplicate]

I am trying to create a Dictionary (actually a HashSet) keyed on a custom protocol in Swift, but it is giving me the error in the title:
Protocol 'myProtocol' can only be used as a generic constraint because it has Self or associated type requirements
and I can't make heads nor tails of it.
protocol Observing: Hashable { }
var observers = HashSet<Observing>()
Protocol Observing inherits from protocol Hashable, which in turn inherits from protocol Equatable. Protocol Equatable has the following requirement:
func ==(lhs: Self, rhs: Self) -> Bool
And a protocol that contains Self somewhere inside it cannot be used anywhere except in a type constraint.
Here is a similar question.
To solve this you could use generics. Consider this example:
class GenericClass<T: Observing> {
var observers = HashSet<T>()
}

Generics Protocol as Type in Swift

How I can create a protocol variable. My goal is a protocol will be have a function with a generic type and I'm using associatedtype which is accessing to Class and the function will be return generic type. Example declaration below:
public protocol ComponentFactory {
associatedtype T // A class and that class can be inherit from another so I need define generic type here
func create() -> T
}
I want to declare a variable for this protocol like that:
fileprivate var mComponentFactoryMap = Dictionary<String, ComponentFactory>()
At this line I receive a error:
Protocol 'ComponentFactory' can only be used as a generic constraint because it has Self or associated type requirements
I see from Android, actually from kotlin they have a declare for interface like:
private val mComponentFactoryMap = mutableMapOf<String, ComponentFactory<*>>()
Any guys can help me, how I can declare this from Swift?
I've solved this from few months ago with descriptions below. Please check it and give me another solution if you have.
Firstly, make some change for Protocol. At associatedtype T should be change to associatedtype Component and Component is a class which will be inherited from another class (important step).
public protocol ProComponentFactory {
associatedtype Component
func create() -> Component?
}
Second, I will make a Generic Struct with inheritance from ProComponentFactory:
public struct ComponentFactory<T>: ProComponentFactory {
public typealias Component = T
public func create() -> T? { return T.self as? T }
}
Well done, for now you can define a variable as I example in my question above:
fileprivate var mComponentFactoryMap = Dictionary<String, ComponentFactory<Component>>()
As well for any class was inherit from Component and variable mComponentFactoryMap can using extension inside.

Using NSHashTable to implement Observer pattern in Swift 3

Adding multiple delegates instead of only one is a quite common task. Suppose we have protocol and a class:
protocol ObserverProtocol
{
...
}
class BroadcasterClass
{
// Error: Type 'ObserverProtocol' does not conform to protocol 'AnyObject'
private var _observers = NSHashTable<ObserverProtocol>.weakObjects()
}
If we try to force ObserverProtocol to conform AnyObject protocol, we will get another error:
Using 'ObserverProtocol' as a concrete type conforming to protocol 'AnyObject' is not supported
Is it even possible to create a set of weak delegates in Swift 3.0?
Sure, it's possible.
AnyObject is the Swift equivalent of id in Objective C. To get your code to compile, you just need to add the #objc annotation to your protocol, to tell Swift that the protocol should be compatible with Objective C.
So:
#objc protocol ObserverProtocol {
}

Swift associated types and protocol inheritance

I'm using Swift 2.2 and I declared a protocol with associated type as follow:
protocol CollectionViewModeling {
associatedtype CellType
func cellAtIndexPath(indexPath: NSIndexPath) -> CellType
}
Now I have a view model protocol conform to the above protocol :
enum MyItemCell {
case MyItemCell1, MyItemCell2
}
protocol ItemsListViewModeling: CollectionViewModeling {
associatedtype CellType = MyCell
}
Finally, somewhere else, I want to declare a var that is conform to le protocol ItemsListViewModeling :
var viewModel: ItemsListViewModeling
And I'm getting this error :
Protocol 'ItemsListViewModeling' can only be used as a generic constraint because it has Self or associated type requirements
But I can easily create a class that implements this protocol.
Is it possible to declare a var to an associated typed protocol ? As I'm giving the final type of the associated type in the protocol ItemsListViewModeling, I don't understand why am I seeing this error from the compiler.
Thanks
See there stackoverflow.com
You can't treat protocols with associated types like regular protocols
and declare them as standalone variable types.