Is there a way to convert an integer to an enum based on its value range? For the sake of elegance, I prefer to implement it into an enum or auxiliary type rather than as a separate function. Ideally, it would be great if I could perform the conversion using a cast like so:
let readPosition = Position(controller.readVal())
or
let readPosition = (Position) controller.readVal()
Below is my feeble attempt at it:
// Should be sealed, yet extensible, c# has sealed, but not Swift
public enum Position: Int {
case Both = 0, Bottom = 1, Top = 2
}
// Position should not be changed to preserve compatibility.
// Different converters will be implemented by different apps
// overtime.
extension Position {
static func convert(val: Int64?) -> Position {
switch val {
case .some(1), .some(..<8):
return Position.Top
case .some(2), .some(8...):
return Position.Bottom
default:
return Position.Both
}
}
}
You already have all you need, you can now define an initializer:
extension Position {
init(_ val: Int64) {
self = Self.convert(val)
}
}
Then you can use your requested:
let readPosition = Position(controller.readVal())
I have a protocol named TableViewItem. This protocol enforces that conforming objects implement a type property, which has the protocol TableViewCellIdentifiable as its type. TableViewCellIdentifiable is used to group three nested enums together, as shown below:
internal protocol TableViewCellIdentifiable: Equatable { }
internal enum TableViewCellType {
internal enum PortfolioSelection: String, TableViewCellIdentifiable {
case portfolio = "portfolioTableViewCell"
case enterPortfolioDetails = "enterPortfolioDetailsTableViewCell"
case addPortfolio = "actionTableViewCell"
}
internal enum EditPortfolio: String, TableViewCellIdentifiable {
case editPortfolioName = "editPortfolioNameTableViewCell"
case deletePortfolio = "deletePortfolioTableViewCell"
}
internal enum Portfolio: String, TableViewCellIdentifiable {
case portfolioAsset = "portfolioAssetTableViewCell"
case addAsset = "actionTableViewCell"
}
}
Here is an example of how this is being used:
internal final class EditPortfolioNameTableViewItem: TableViewItem {
// MARK: - Internal Properties
internal let type: TableViewCellIdentifiable = TableViewCellType.EditPortfolio.editPortfolioName
internal let viewModel: TableViewCellModel
// MARK: - Initialization
internal init(viewModel: EditPortfolioNameTableViewCellModel) {
self.viewModel = viewModel
}
}
Unfortunately, on the line that I am declaring the type property, I receive the following error:
Protocol 'TableViewCellIdentifiable' can only be used as a generic constraint because it has Self or associated type requirements
I have read through other questions/answers from others who have encountered this error but I can't quite understand why this particular implementation is problematic, and what the solution would be. I know that Equatable is the source of the problem, however this is crucial to the functionality, as the enums serve two purposes:
To provide reuse identifiers for the table view cells (the raw values).
To allow types to be compared - i.e:
self.tableViewItems.contains(where: { $0.type == item.type })
Any suggestions would be much appreciated, even if it means taking an alternative approach.
In your head, should the following code compile?
var x : Equatable
It shouldn't. Why?
Because if you had:
var x : Equatable
var y : Equatable
Then the compiler can't ensure that x & y are of the same type. x can be "John", because "John"/Strings are Equatable...all while y can be 10, because 10/integers are equatable.
and the compiler would suspect that a few lines below you might want to do
if x == y { print ("equal" }
which it can't process. So it just stops you from ever doing it in the beginning.
The following line of your code will trigger the same error because of the reason above.
internal let type: TableViewCellIdentifiable = TableViewCellType.EditPortfolio.editPortfolioName
As explained by Honey's answer, TableViewCellIdentifiable doesn't provide enough type information for the compiler to work with. You could potentially adopt a different approach which changes the structure a bit (and is potentially overkill), but provides the functionality you're looking for:
internal protocol ValueAssociated { }
internal extension ValueAssociated {
fileprivate var association: (label: String, value: Any?)? {
get {
let mirror = Mirror(reflecting: self)
if let association = mirror.children.first, let label = association.label {
return (label, association.value)
}
return nil
}
}
}
internal protocol CellIdentifiable {
var rawValue: String { get }
}
internal enum CellType: Equatable, ValueAssociated {
case portfolio(PortfolioIdentifier)
case portfolioSelection(PortfolioSelectionIdentifier)
case editPortfolio(EditPortfolioIdentifier)
internal var identifier: String? {
return (self.association?.value as? CellIdentifiable)?.rawValue
}
internal enum PortfolioIdentifier: String, Equatable, CellIdentifiable {
case portfolioAsset = "portfolioAssetTableViewCell"
case addAsset = "actionTableViewCell"
}
internal enum PortfolioSelectionIdentifier: String, Equatable, CellIdentifiable {
case portfolio = "portfolioTableViewCell"
case enterPortfolioDetails = "enterPortfolioDetailsTableViewCell"
case addPortfolio = "actionTableViewCell"
}
internal enum EditPortfolioIdentifier: String, Equatable, CellIdentifiable {
case editPortfolioName = "editPortfolioNameTableViewCell"
case deletePortfolio = "deletePortfolioTableViewCell"
}
}
This can be used as follows:
internal let cellType: CellType = .portfolio(.portfolioAsset)
print(cellType.identifier!) // Prints "portfolioAssetTableViewCell"
Hope this helps.
I just found another way to make a great use of protocols and protocol extensions in Swift by extending the Optional protocol to add a function so I can provide default values.
I wrote a blog post about this here: https://janthielemann.de/random-stuff/providing-default-values-optional-string-empty-optional-string-swift-3-1/
The gist of the post is that I needed a clean and easy way to provide default values for optional String which are nil or empty. To do this, I created a Emptyable protocol end extended the Optional protocol like so:
protocol Emptyable {
var isEmpty: Bool { get }
}
extension Optional where Wrapped: Emptyable {
func orWhenNilOrEmpty<T: Emptyable>(_ defaultValue: T) -> T {
switch(self) {
case .none:
return defaultValue
case .some(let value) where value.isEmpty:
return defaultValue
case .some(let value):
return value as! T
}
}
}
extension String: Emptyable {}
Now the question is: Is there a way I can get rid of the Emptyable protocol and instead have a conditional check whether or not a property or function is implemented by the generic type so that I automatically get orWhenNilOrEmpty() for each and every type which has isEmpty?
UPDATE
As suggested by Paulo, the T generic is actually not needed and I created a operator for even quicker access and more convenient usage (at least I think so. Feel free to correct me, I'm always happy to learn new things and improve myself).
I call it the "not empty nil coalescing" operator (who can come up with a better names? I feel like I suck at naming things :/ ). Hopefully some day it helps somebody:
protocol Emptyable {
var isEmpty: Bool { get }
}
infix operator ???: NilCoalescingPrecedence
extension Optional where Wrapped: Emptyable {
func orWhenNilOrEmpty(_ defaultValue: Wrapped) -> Wrapped {
switch(self) {
case .none:
return defaultValue
case .some(let value) where value.isEmpty:
return defaultValue
case .some(let value):
return value
}
}
static func ???(left: Wrapped?, right: Wrapped) -> Wrapped {
return left.orWhenNilOrEmpty(right)
}
}
extension String: Emptyable {}
extension Array: Emptyable {}
extension MyStruct: Emptyable {
let text: String
let number: Int
var isEmpty: Bool { return text.isEmpty && number == 0 }
init(text: String, number: Int) {
self.text = text
self.number = number
}
}
let mandatoryNotEmptyString = optionalOrEmptyString ??? "Default Value"
let mandatoryNotEmptyStruct = optionalOrEmptyStruct ??? MyStruct(name: "Hello World", number: 1)
No, you cannot query if an object or value has a certain property as a constraint on an extension without using a protocol. That would require reflection in a way that is currently not implemented in Swift. Also, an isEmpty property could have different meanings for different types, so testing for the existence of a method or property instead of a protocol could lead to unexpected behaviour.
You could just write
if let unwrappedString = optionalString, !unwrappedString.isEmpty {
// Do stuff
} else {
// Use default value
}
No protocol or extension required and very readable.
In Swift 4, which is coming out this fall, String will conform to BidirectionalCollection, which inherits from Collection. The Collection protocol provides an isEmpty property, so your extension could be
extension Optional where Wrapped: Collection {
// ...
}
But even then you should consider to set empty strings to nil when storing them in the first place, because you now have two states (nil and empty) which seem to represent the exact same thing.
I want to associate two raw values to an enum instance (imagine an enum representing error types, I want Error.Teapot to have an Int type property code with value 418, and a String property set to I'm a teapot.)
Note the difference between raw values and associated values here—I want all Teapot instances to have a code of 418, I don't want a unique associated value for each Teapot instance.
Is there a better way than adding computed properties to the enum that switched on self to look up the appropriate value?
You have a couple options. But neither of them involve raw values. Raw values are just not the right tool for the task.
Option 1 (so-so): Associated Values
I personally highly recommend against there being more than one associated value per enum case. Associated values should be dead obvious (since they don't have arguments/names), and having more than one heavily muddies the water.
That said, it's something the language lets you do. This allows you to have each case defined differently as well, if that was something you needed. Example:
enum ErrorType {
case teapot(String, Int)
case skillet(UInt, [CGFloat])
}
Option 2 (better): Tuples! And computed properties!
Tuples are a great feature of Swift because they give you the power of creating ad-hoc types. That means you can define it in-line. Sweet!
If each of your error types are going to have a code and a description, then you could have a computed info property (hopefully with a better name?). See below:
enum ErrorType {
case teapot
case skillet
var info: (code: Int, description: String) {
switch self {
case .teapot:
return (418, "Hear me shout!")
case .skillet:
return (326, "I'm big and heavy.")
}
}
}
Calling this would be much easier because you could use tasty, tasty dot syntax:
let errorCode = myErrorType.info.code
No, an enum cannot have multiple raw values - it has to be a single value, implementing the Equatable protocol, and be literal-convertible as described in the documentation.
I think the best approach in your case is to use the error code as raw value, and a property backed by a prepopulated static dictionary with the error code as key and the text as value.
I created a way of simulating this (No different than what Marcos Crispino suggested on his answer). Far from a perfect solution but allows us to avoid those nasty switch cases for every different property we want to get.
The trick is to use a struct as the "properties/data" holder and using it as a RawValue in the enum itself.
It has a bit of duplication but it's serving me well so far. Every time you want to add a new enum case, the compiler will remind you to fill in the extra case in the rawValue getter, which should remind you to update the init? which would remind you to create the new static property on the struct.
Gist
Code to the Gist:
enum VehicleType : RawRepresentable {
struct Vehicle : Equatable {
let name: String
let wheels: Int
static func ==(l: Vehicle, r: Vehicle) -> Bool {
return l.name == r.name && l.wheels == r.wheels
}
static var bike: Vehicle {
return Vehicle(name: "Bicycle", wheels: 2)
}
static var car: Vehicle {
return Vehicle(name: "Automobile", wheels: 4)
}
static var bus: Vehicle {
return Vehicle(name: "Autobus", wheels: 8)
}
}
typealias RawValue = Vehicle
case car
case bus
case bike
var rawValue: RawValue {
switch self {
case .car:
return Vehicle.car
case .bike:
return Vehicle.bike
case .bus:
return Vehicle.bus
}
}
init?(rawValue: RawValue) {
switch rawValue {
case Vehicle.bike:
self = .bike
case Vehicle.car:
self = .car
case Vehicle.bus:
self = .bus
default: return nil
}
}
}
VehicleType.bike.rawValue.name
VehicleType.bike.rawValue.wheels
VehicleType.car.rawValue.wheels
VehicleType(rawValue: .bike)?.rawValue.name => "Bicycle"
VehicleType(rawValue: .bike)?.rawValue.wheels => 2
VehicleType(rawValue: .car)?.rawValue.name => "Automobile"
VehicleType(rawValue: .car)?.rawValue.wheels => 4
VehicleType(rawValue: .bus)?.rawValue.name => "Autobus"
VehicleType(rawValue: .bus)?.rawValue.wheels => 8
No, you cannot have multiple raw values associated with an enum.
In your case, you could have the raw value to be equal to the code, and have an associated value with the description. But I think the computed properties approach is the best option here.
One workaround if you wanted to have many static properties for a YourError could be to import a property list; you could set the root object to a dictionary, with your enum raw value as the key for each object, allowing you to easily retrieve static structured data for the object.
This has an example of importing and using a plist: http://www.spritekitlessons.com/parsing-a-property-list-using-swift/
That might be overkill for simply an error description, for which you could just use a hardcoded static function with a switch statement for your enum values, that returns the error string you need. Simply place the static function in the same .swift file as your enum.
For instance,
static func codeForError(error : YourErrorType) -> Int {
switch(error) {
case .Teapot:
return "I'm a Teapot"
case .Teacup:
return "I'm a Teacup"
...
default:
return "Unknown Teaware Error"
}
}
This has the benefit (compared to the .plist solution) of better accomodating localization. However, a .plist could just contain a key used for retrieving the proper localization, instead of a error string, for this purpose.
For beginning, assuming you want to store a code and a message, you can use a struct for RawValue
struct ErrorInfo {
let code: Int
let message: String
}
Next step is to define the enum as being RawRepresentable, and use ErrorInfo as the raw value:
enum MyError: RawRepresentable {
typealias RawValue = ErrorInfo
case teapot
What remains is to map between instances of MyError and ErrorInfo:
static private let mappings: [(ErrorInfo, MyError)] = [
(ErrorInfo(code: 418, message: "I'm a teapot"), .teapot)
]
With the above, let's build the full definition of the enum:
enum MyError: RawRepresentable {
static private let mappings: [(ErrorInfo, MyError)] = [
(ErrorInfo(code: 418, message: "I'm a teapot"), .teapot)
]
case teapot
init?(rawValue: ErrorInfo) {
guard let match = MyError.mappings.first(where: { $0.0.code == rawValue.code && $0.0.message == rawValue.message}) else {
return nil
}
self = match.1
}
var rawValue: ErrorInfo {
return MyError.mappings.first(where: { $0.1 == self })!.0
}
}
Some notes:
you could use only the error code for matching, however this might result in inconsistent raw values if the messages differ
the amount of boilerplate code required to have raw values of some custom type might not outcome the benefits of using associated values.
Possible work around may to associate custom functions with enum
enum ToolbarType : String{
case Case = "Case", View="View", Information="Information"
static let allValues = [Case, View, Information]
func ordinal() -> Int{
return ToolbarType.allValues.index(of: self)!
}
}
Can be used as
for item in ToolbarType.allValues {
print("\(item.rawValue): \(item.ordinal())")
}
Output
Case: 0
View: 1
Information: 2
Possibly you can have additional functions to associate enum type to different values
This doesn't particularly answer your question, which was asking to find a better way than switching through self to look up the appropriate value but this answer may still be useful for someone looking in the future that needs a simple way to get a string from an enum which is defined as an integer type.
enum Error: UInt {
case Teapot = 418
case Kettle = 419
static func errorMessage(code: UInt) -> String {
guard let error = Error(rawValue: code) else {
return "Unknown Error Code"
}
switch error {
case .Teapot:
return "I'm a teapot!"
case .Kettle:
return "I'm a kettle!"
}
}
}
This way, we can get the errorMessage two ways:
With an integer (eg. that was returned as an error code from a server)
With an enum value (the rawValue we define for the enum)
Option 1:
let option1 = Error.errorMessage(code: 418)
print(option1) //prints "I'm a teapot!"
Option 2:
let option2 = Error.errorMessage(code: Error.Teapot.rawValue)
print(option2) //prints "I'm a teapot!"
In modern versions of Swift it's possible to get the string value of an enum case label, even without that enum being declared with a : String rawValue.
How to get the name of enumeration value in Swift?
So there is no longer a need to define and maintain a convenience function that switches on each case to return a string literal. In addition, this works automatically for any enum, even if no raw-value type is specified.
This, at least, allows you to have "multiple raw values" by having both a real : Int rawValue as well as the string used as the case label.
I think it just tricky, and I have create my own idea like below:
enum Gender:NSNumber
{
case male = 1
case female = 0
init?(strValue: String?) {
switch strValue {
case Message.male.value:
self = .male
case Message.female.value:
self = .female
default: return nil
}
}
var strValue: String {
switch self {
case .male:
return Message.male.value
case .female:
return Message.female.value
}
}
}
First of all, enums should only have one raw value. However if you want to have something that can use multiple raw values... there is a way to 'hack' this, but you have to make it codable and hashable yourself, implement custom init's etc.
enum MyCustomEnum: Codable, Hashable {
// duplicate every case with associated value of Codable.Type
case myFirstCase, _myFirstCase(Codable.Type)
case mySecondCase, _mySecondCase(Codable.Type)
case myThirdCase, _myThirdCase(Codable.Type)
case unknown(Any), _unknown(Codable.Type, Any) // handles unknown values
// define an allCases value to determine the only values your app 'sees'.
static var allCases: [Self] {
return [
.myFirstCase,
.mySecondCase,
.myThirdCase
// unknown(String) // you can add unknown as well, but this is too mask any unknown values.
]
}
static func == (lhs: MyCustomEnum, rhs: MyCustomEnum) -> Bool {
return lhs.stringValue == rhs.stringValue // can be either one of your custom raw values.
}
// add this per raw value. In this case one for Int and one for String
init(rawValue: Int) {
guard let value = Self.allCases.first(where:{ $0.intValue == rawValue }) else {
self = ._unknown(Int.self, rawValue)
return
}
switch value {
case .myFirstCase: self = ._myFirstCase(Int.self)
case .mySecondCase: self = ._mySecondCase(Int.self)
case .myThirdCase: self = ._myThirdCase(Int.self)
default: self = ._unknown(Int.self, rawValue)
}
}
init(rawValue: String) {
guard let value = Self.allCases.first(where:{ $0.stringValue == rawValue }) else {
self = ._unknown(String.self, rawValue)
return
}
switch value {
case .myFirstCase: self = ._myFirstCase(String.self)
case .mySecondCase: self = ._mySecondCase(String.self)
case .myThirdCase: self = ._myThirdCase(String.self)
default: self = ._unknown(Int.self, rawValue)
}
}
// add this per raw value. In this case one for Int and one for String
var intValue: Int {
switch self {
case .myFirstCase, ._myFirstCase(_): return 1
case .mySecondCase, ._mySecondCase(_): return 2
case .myThirdCase, ._myThirdCase(_): return 3
case .unknown(let value), ._unknown(_, let value): return value as? Int ?? -1 // you can also choose to let intValue return optional Int.
}
}
var stringValue: String {
switch self {
case .myFirstCase, ._myFirstCase(_): return "my first case"
case .mySecondCase, ._mySecondCase(_): return "my second case"
case .myThirdCase, ._myThirdCase(_): return "my third case"
case .unknown(let value), ._unknown(_, let value): return value as? String ?? "not a String" // you can also choose to let stringValue return optional String.
}
}
// determine the codable type using Mirror
private func getCodableType() -> Codable.Type? {
let mirrorOfModuleType = Mirror.init(reflecting: self)
guard let childOfModuleType = mirrorOfModuleType.children.first else { // no children, means no associated values.
return nil
}
let value = childOfModuleType.value // can be either Codable.Type, String or (Codable.Type & String)
if let rawValue = value as? Codable.Type {
return rawValue
} else {
guard let rawValue = value as? (Codable.Type, String) else {
// unknown(String), we don't know the rawValue as given, but try in this part of the code to guess what type fits best.
if self.stringValue != "\(self.intValue)" { // e.g. "1" might match 1 but "1.0" and 1 don't match
return String.self
} else {
return Int.self // return either a default value, or nil. It's your choice.
}
}
return rawValue.0
}
}
// confine to hashable using getCodableType
func hash(into hasher: inout Hasher) {
if self.getCodableType() is String.Type {
hasher.combine(self.stringValue)
} else { // if you don't call hasher.combine at all, you can expect strange issues. If you do not know the type, choose one that is most common.
hasher.combine(self.intValue)
}
}
// confine to Decodable
init(from decoder: Decoder) throws {
if let rawValue = try? Int.init(from: decoder) {
self.init(rawValue: rawValue)
} else if let rawValue = try? String.init(from: decoder) {
self.init(rawValue: rawValue)
} else {
throw DecodingError.valueNotFound(Self.self, DecodingError.Context(codingPath: [], debugDescription: "no matching value was found"))
}
}
// confine to Encodable using getCodableType
func encode(to encoder: Encoder) throws {
let rawValue = self.getCodableType()
if rawValue is String.Type {
try self.stringValue.encode(to: encoder)
} else if rawValue is Int.Type {
try self.intValue.encode(to: encoder)
} else {
// getCodableType returns nil if it does not know what value it is. (e.g. myFirstCase without associated value) If you want to support this as well, you can encode using one of your rawValues to the encoder.
throw EncodingError.invalidValue(Self.self, EncodingError.Context.init(codingPath: [], debugDescription: "this enum does not have a correct value", underlyingError: nil))
}
}
}
this code is scalable to any number of raw value as long as they are Codable
I'm trying to port the Matrix example from Swift book to be generic.
Here's what I got so far:
struct Matrix<T> {
let rows: Int, columns: Int
var grid: T[]
init(rows: Int, columns: Int, repeatedValue: T) {
self.rows = rows
self.columns = columns
grid = Array(count: rows * columns, repeatedValue: repeatedValue)
}
func indexIsValidForRow(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
subscript(row: Int, column: Int) -> T {
get {
assert(indexIsValidForRow(row, column: column), "Index out of range")
return grid[(row * columns) + column]
}
set {
assert(indexIsValidForRow(row, column: column), "Index out of range")
grid[(row * columns) + column] = newValue
}
}
}
Note that I had to pass repeatedValue: T to the constructor.
In C#, I would have just used default(T) which would be 0 for numbers, false for booleans and null for reference types. I understand that Swift doesn't allow nil on non-optional types but I'm still curious if passing an explicit parameter is the only way, or if I there is some equivalent of default(T) there.
There isn't. Swift forces you to specify the default value, just like then you handle variables and fields. The only case where Swift has a concept of default value is for optional types, where it's nil (Optional.None).
An iffy 'YES'. You can use protocol constraints to specify the requirement that your generic class or function will only work with types that implement the default init function (parameter-less). The ramifications of this will most likely be bad (it doesn't work the way you think it does), but it is the closest thing to what you were asking for, probably closer than the 'NO' answer.
For me I found this personally to be helpful during development of a new generic class, and then eventually I remove the constraint and fix the remaining issues. Requiring only types that can take on a default value will limit the usefulness of your generic data type.
public protocol Defaultable
{
init()
}
struct Matrix<Type: Defaultable>
{
let rows: Int
let columns: Int
var grid: [Type]
init(rows: Int, columns: Int)
{
self.rows = rows
self.columns = columns
grid = Array(count: rows * columns, repeatedValue: Type() )
}
}
There is a way to get the equivalent of default(T) in swift, but it's not free and it has an associated hazard:
public func defaultValue<T>() -> T {
let ptr = UnsafeMutablePointer<T>.alloc(1)
let retval = ptr.memory
ptr.dealloc(1)
return retval;
}
Now this is clearly a hack because we don't know if alloc() initializes to something knowable. Is it all 0's? Stuff left over in the heap? Who knows? Furthermore, what it is today could be something different tomorrow.
In fact, using the return value for anything other than a placeholder is dangerous. Let's say that you have code like this:
public class Foo { /* implementation */
public struct Bar { public var x:Foo }
var t = defaultValue<Bar>();
t = someFactoryThatReturnsBar(); // here's our problem
At the problem line, Swift thinks that t has been initialized because that's what Swift's semantics say: you cannot have a variable of a value type that is uninitialized. Except that it is because default<T> breaks those semantics. When you do the assignment, Swift emits a call into the value witness table to destroy the existing type. This will include code that will call release on the field x, because Swift semantics say that instances of objects are never nil. And then you get a runtime crash.
However, I had cause to interoperate with Swift from another language and I had to pass in an optional type. Unfortunately, Swift doesn't provide me with a way to construct an optional at runtime because of reasons (at least I haven't found a way), and I can't easily mock one because optionals are implemented in terms of a generic enum and enums use a poorly documented 5 strategy implementation to pack the payload of an enum.
I worked around this by passing a tuple that I'm going to call a Medusa tuple just for grins: (value: T, present: Bool) which has the contract that if present is true, then value is guaranteed to be valid, invalid otherwise. I can use this safely now to interop:
public func toOptional<T>(optTuple: (value:T, present:Bool)) -> T?
{
if optTuple.present { return optTuple.value }
else { return nil }
}
public func fromOptional<T>(opt: T?) -> (T, Bool)
{
if opt != nil { return (opt!, true) }
else {
return (defaultValue(), false)
}
}
In this way, my calling code passes in a tuple instead of an optional and the receiving code and turn it into an optional (and the reverse).
In fact, generic types can have optional values.
You can do it with protocols
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let someType = SomeType<String>()
let someTypeWithDefaultGeneric = SomeType()
}
}
protocol Default {
init()
}
extension Default where Self: SomeType<Void> {
init() {
self.init()
}
}
class SomeType<T>: Default {
required init() {}
}