Find by Protocol in Swift

Find by Protocol in Swift

I would suggest to use this if CurrentUserContex is the name of the protocol itself:

ServiceLocator.locate(CurrentUserContex.self)

If CurrentUserContex is a variable which type is a protocol use:

ServiceLocator.locate(CurrentUserContex)

I hope this solves your problem

Find out the name of all the implementers of swift protocol

so this is how I did it:

static func getClassesImplementingProtocol(_ protocolName: Protocol!) -> [AnyClass] {

var result = [AnyClass]();

let count: Int32 = objc_getClassList(nil, 0)

guard count > 0 else {
return result
}

let classes = UnsafeMutablePointer<AnyClass>.allocate(
capacity: Int(count)
)

defer {
classes.deallocate()
}

let buffer = AutoreleasingUnsafeMutablePointer<AnyClass>(classes)

for i in 0..<Int(objc_getClassList(buffer, count)) {
let someclass: AnyClass = classes[i]

if class_conformsToProtocol(someclass, protocolName) {

result.append(someclass);
}
}

return result
}

Thanks to : How to list all classes conforming to protocol in Swift?

Cannot find protocol declaration for *** in my 'MyApp-Swift.h'

First, I have to thank Rob for his tips. I wish he could get the points!

After troubleshooting with the tips provided:

  • Add StoreKit to your linked frameworks list. -> Didn't work
  • @import StoreKit; before #import <...-Swift.h> -> Showed error use of @import when modules are disabled

I also saw that "...-Swift.h" was only declared in the Build settings of my "...Topself" targets. Still quite unsure why as I would have thought the whole project still have ObjC dependencies... Still quite new to this challenge.

Furthermore, If I unfold the error I could see that there was some kind of error trying to find "...-Swift.h" file.

At this point, I remembered that I am using cocoapods (I don't like you, you don't like me relationship) and I hated to see the warning "...Overrides Enable modules (C - Objective-C)" so I set it to default for the whole project.

Turns out that that for all "...TopSelf" targets, the default value is NO.

By Overriding Enable modules (C - Objective-C) to YES, clean, and build, everything started working again.

Swift Protocols: Difference between { get } and { get set } with concrete examples?

protocol — is a requirement of some minimal interface of the type implementing it.

  • var name: Type { get } requires type to have property with at least a getter (accessible from outside of the type, not private), i.e. outside code should be able to read value of the property. In the implementing type it could be let name: Type, var name: Type, private(set) var name: Type, fileprivate(set) var name: Type, etc.

  • var name: Type { get set } requires type to have property with both accessible getter and setter, i.e. outside code should be able to read and write to the property. Here only var name: Type would be allowed.

If protocol requires for getter but you also provide a setter — it's not against protocol requirements.
But if protocol requires for both getter and setter — you must provide both, and not having any of them won't be valid implementation.


Your Person class defined both properties as var(with accessible getter and setter) therefore you can change them both. But PersonProtocol haven't required ability to set firstName.

And as @JoakimDanielson shows, if you will use just interface required by protocol you won't be to change the firstName value.

Can not find Swift Protocol declaration in Obj-C class

Define your Swift protocol like this inside your Swift file.

@objc protocol SpeechRecognizerDelegate: class{
func speechRecognitionFinished(_ transcription:String)
func speechRecognitionError(_ error:Error)
}

Create a Swift Module inside your project setting then use it. You can find here complete blog for the mix language coding.

Then use Protocol inside Objective C class,

We required to add protocol inside Objective C file -

#import "ARBot-Swift.h"

@interface ChatScreenViewController : JSQMessagesViewController <SpeechRecognizerDelegate>

Then you need to conform to the protocol methods -

- (void)viewDidLoad {
[super viewDidLoad];
SpeechRecognizer * speechRecognizer = [[SpeechRecognizer alloc] init];
speechRecognizer.delegate = self;
}


#pragma mark - Delegate Methods
-(void)speechRecognitionFinished:(NSString *) transcription{
//Do something here
}

-(void)speechRecognitionError:(NSError *) error{
//Do something here
}

In Swift, can you find all types in a module that adhere to a specific protocol?

I don't believe Swift currently has a 'native' (not dependant on the Objective-C runtime) API for doing this kind of reflection.

However, if you're on an Apple platform (and therefore have Obj-C interoperability), you could get a list of all classes registered with the Obj-C runtime, and then filter those that conform to a given protocol. This will work for Swift classes (even those that don't inherit from NSObject) because under the hood Swift classes are built on top of Obj-C classes (when there's Obj-C interop).

Because this will only work for classes (not structures or enumerations), you may want to restrict your protocol such that only classes can conform to it:

protocol Favorite : class {}

You can then do the following, using objc_copyClassList:

import Foundation

protocol Animal {}
protocol Vehicle {}
protocol Favorite : class {}

class Dog : Animal {}
class Cat : Animal, Favorite {}
class Car : Vehicle {}
class Bicycle : Vehicle, Favorite {}

/// Invokes a given closure with a buffer containing all metaclasses known to the Obj-C
/// runtime. The buffer is only valid for the duration of the closure call.
func withAllClasses<R>(
_ body: (UnsafeBufferPointer<AnyClass>) throws -> R
) rethrows -> R {

var count: UInt32 = 0
let classListPtr = objc_copyClassList(&count)
defer {
free(UnsafeMutableRawPointer(classListPtr))
}
let classListBuffer = UnsafeBufferPointer(
start: classListPtr, count: Int(count)
)

return try body(classListBuffer)
}
// .flatMap in Swift < 4.1
let classes = withAllClasses { $0.compactMap { $0 as? Favorite.Type } }
print(classes) // [Bicycle, Cat]

Here we're calling compactMap(_:) on the UnsafeBufferPointer to get back an array of metatypes that represent types conforming to Favorite (i.e those that can be cast to the existential metatype Favorite.Type).



Related Topics



Leave a reply



Submit