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
).
returning swift protocol associated type in multiple methods
The solution you came up with by playing around is exactly what you need
As mentioned elsewhere, the main issue with your first protocol is that you're enforcing createSomeView()
createAnotherView()
both return the same type. While ViewA()
and ViewB()
are both candidates for V
, since they conform to View
they are still different types, and therefore cannot BOTH be V
in a given object.
By defining both V1
and V2
, you allow for each function to return a different type, or the same type, it's all acceptable. By making both V1
and V2
require View
conformance, you allow for the some View
syntax
How can I execute the same function for all objects of a collection in Swift?
You can try
observers.forEach { $0.update(message: "updated") }
Xcode 13.3 build fails: Command EmitSwiftModule failed with a nonzero exit code
Problem could be with one of your libraries/pods which needs to be updated .
You could export Failed Build Logs from Xcode Report Navigator - Export Log
These Logs could be valuable to check these type of unknown build failure issues where we are not sure of what library/file is actually impacting build process.
Usually the libraries impacting the build will be found towards end of logs. In my case I had to update an Pod for which I followed below steps.
1)Run pod deintegrate
2)Inside pod file mention updated pod version or you can simply remove any explicit version which is mentioned to get latest pod version
In my case I updated pod version as " pod 'CryptoSwift', '~> 1.4.0' "
3)Run pod install.
Everything should work well after that.
*** I have attached screenshot sample of end of logs where my impacted pod was mentioned before build failure message. Hope it helps anyone ***
How to define a Protocol with generic function and some View as return type
This is explicitly disallowed by the Associated Type Inference section of the Opaque Result Types proposal. From the proposal:
Associated type inference can only infer an opaque result type for a non-generic requirement, because the opaque type is parameterized by the function's own generic arguments. For instance, in:
protocol P {
associatedtype A: P
func foo<T: P>(x: T) -> A
}
struct Foo: P {
func foo<T: P>(x: T) -> some P {
return x
}
}there is no single underlying type to infer A to, because the return type of foo is allowed to change with T.
To make this more specific to your question, in order to conform to Test
, there must be exactly one type that can be assigned to Result
. However, your return type is generic, so it depends on the what is passed. The actual (non-opaque) return type of navigate
is:
_ConditionalContent<NavigationLink<T, Text>, EmptyView>
But T
is a type parameter and changes depending on how navigate
is called. So there is no one type that can be assigned to Result
.
You'll need something that can return a single, non-parameterized type. For the example you've given, that's probably AnyView, which is annoying.
That said, what you've written here doesn't really feel like a protocol. It looks a lot like just a function. I'd think a lot about how many different ways navigate
could be written. If everyone would implement it the same way, that's just a function. (If you give another example of a conforming type, it might help to design a better approach.)
Creating Encodable class by injecting class conforming only to Encodable protocol
You cannot encode device
because device
must be a concrete type which conforms to Encodable
. Possible solutions are an associated type of the protocol constrained to Encodable
or a generic, something like
class Body<T : Encodable> : Encodable {
let device: T
init(_ deviceInfo: T) {
self.device = deviceInfo
}
}
Importing a Swift protocol in Objective-C class
You need to add the @objc
attribute to your Swift protocol like so:
@objc protocol AnalyticProtocol {
}
Getting error `Do you want to add protocol stubs?
This error comes because you implemented protocol (ImageViewProtcol
) but you haven't add required methods of your protocol (in your case sendImageToViewController(theImage: UIImage)
). All methods of your protocol are required by default. If you want to change it, you can look here.
It's the same as when you're implementing UITableViewDataSource
, you also need to add required methods like number of items etc.
To fix this, add this method to your CardsViewController
:
func sendImageToViewController(theImage: UIImage) {
// do something with image
}
Related Topics
Swiftui MACos Commands (Menu Bar) and View
How to Retrieve All Contacts Using Cncontact.Predicateforcontacts
How Do We Implement Wait/Notify in Swift
How to I Access Argv and Argc in Swift
Uicollectionview Autosize and Dynamic Number of Rows
Is a Static Boolean a Reference Type in Swift
Replacement for _Stdlib_Getdemangledtypename() in Swift 2.2
iOS Swift: Unsafemutableaddressor Crash on iOS 8
Add Skin Tone Modifier to an Emoji Programmatically
How to Convert Text to Speech for Osx in Swift Playground
iOS Charts Remove Decimal from Yvalues
A Swiftier Way to Convert String to Unsafepointer<Xmlchar> in Swift 3 (Libxml2)
Realm: Map JSON to Realm-Objects with Alamofire
Swift Protocol with Associated Type - Type May Not Reference Itself as a Requirement
New Fuitableviewdatasource - How to Use? Swift 3
How to Rotate an Arkit 4X4 Matrix Around Y Using Apple's Simd Library