I want to create enum in my struct. I tried:
struct ProfileTextfieldItem {
var txtfPlaceholder: String
var bottomTxt: String
var modelType : Int
enum modelType {
case phone
case skype
}
}
Then i did:
let tesEnum = ProfileTextfieldItem(txtfPlaceholder: "o.ivanova", bottomTxt: "Логин Skype", enumType: phone)
However compiler didn't let me run, it says - Use of unresolved identifier - phone.
Instead of this, here's what you should do:
struct ProfileTextfieldItem {
var txtfPlaceholder: String
var bottomTxt: String
var modelType: ModelType
enum ModelType {
case phone
case skype
}
}
In Swift, enums are Types, they can be used just like classes and structs. To make an instance of this, do:
let tesEnum = ProfileTextfieldItem(txtfPlaceholder: "o.ivanova", bottomTxt: "Логин Skype", modelType: .phone)
Note the third parameter has a . in front of it and is called modelType, not enumType.
You should define the struct like this:
struct ProfileTextfieldItem {
var txtfPlaceholder: String
var bottomTxt: String
var modelType : ModelType
enum ModelType {
case phone
case skype
}
}
and initial the var tesEnum like this:
let tesEnum = ProfileTextfieldItem(txtfPlaceholder: "o.ivanova", bottomTxt: "Логин Skype", modelType: .phone)
Related
I have a struct which confirm codable protocol.
public struct FlightDTO {
public var flightName: String = ""
public var PilotName: String = ""
public var copilotName: String = ""
public var totalCrewMem: Int = 0
}
extension FlightDTO: Codable {
enum CodingKeys: String, CodingKey {
case flightName
case PilotName
case copilotName
case totalCrewMem
}
}
when I create object of struct it give me this initialiser.
This struct is in swift package and I am initialising it from the app.
var flightData = FlightDTO(from: <#Decoder#>)
I am not sure what to pass in decoder.
The init that is suggested is used by the JSONDecoder when decoding JSON but to create objects manually in code you need to create your own public init because the synthesised one is internal.
So either
public init() {} // use default values
or
public init FlightDTO(flightName: String, PilotName: String, copilotName: String, totalCrewMem: Int) {
self.flightName = flightName
self.PilotName = PilotName
self.copilotName = copilotName
self.totalCrewMem = totalCrewMem
}
I like to separate soms function and var from a enum and thought this was a way. (Just sample code)
This results in a compile error "Type 'Self' has no member 'allCases'"
public protocol EnumFunctions: Hashable {
static var numOfCases: Self { get }
}
public extension EnumFunctions {
static var numOfCases: Self {
return self.allCases.count
}
}
my Enum Cooking Timer
public struct Cook_Time {
// struct naming for the dump command like
// dump(Cook_Time(), name: Cook_Time().structname)
let structname : String = "Cook_Time"
let a = "a"
let allValues = PFTime.allValues
public enum PFTime : String , CaseIterable, EnumFunctions {
case t1m = "1mim"
case t3m = "3min"
case t5m = "5min"
case t10m = "10min"
....
static let allValues = PFTimer.allCases.map { $0.rawValue }
}
}
How can I fix this? what is my false mind setting about this? I do need Self instead of self, rigth?
Also if I make an extension for PFTime, in a separated file, why does I get the error "Cannot find type 'PFTime' in scope"?
In order to access allCases property of CaseIterable protocol, you need to change your EnumFunctions protocol to something like this:
public protocol EnumFunctions: Hashable, CaseIterable {
static var numOfCases: Int { get }
}
public extension EnumFunctions {
static var numOfCases: Int {
return allCases.count
}
}
Also you can create an extension to PFTime just by adding Cook_Time. as prefix because PFTime is placed inside Cook_Time struct:
extension Cook_Time.PFTime {
}
I have an array of enums witch contains associated structs like so:
struct TypeOne {
let id = UUID()
var image:UIImage
}
struct TypeTwo {
let id = UUID()
var image:UIImage
var url:URL
}
enum Types {
case one(a: TypeOne)
case two(b: TypeTwo)
}
var array:[Types] = []
Both possible structs share the variables; id and image. Is there any way to retrieve those values without doing like below?
switch array[0] {
case .one(a: let a):
print(a.id)
case .two(b: let b):
print(b.id)
}
Since the two variables are present in both structs I'm looking for a solution like this (if it exists):
print(array[0].(xxx).id)
UPDATE: My answer may miss the mark. Do you really need the enum? In my solution the need for the enum was eliminated. But if you need the enum because it carries other significant info, then my solution is no good. If you are just using the enum so you can put both types in an array, then consider using an array of Typeable instead where Typeable is the protocol of my solution.
Yes, you could use protocols for something like this to define a common set of methods or fields:
protocol Typeable {
var id:UUID {get}
var image:UIImage {get}
}
struct TypeOne:Typeable {
let id = UUID()
var image:UIImage
}
struct TypeTwo:Typeable {
let id = UUID()
var image:UIImage
var url:URL
}
var array:[Typeable] = []
let typeOne:TypeOne = //
let typeTwo:TypeTwo = //
array.append(typeOne)
array.append(typeTwo)
print(array[0].id)
// to declare a function that takes a Typeable
func myMethod<T:Typeable>(val:T) {
print(val.id)
}
Note, my protocol name is no good and doesn't match naming guidelines. Without knowing more about your use case I'm not sure what a good name would be.
Someway or another you're going to have to switch over each case to extract the associated values. However, we can make it convenient for use. I'd start with a protocol so our types have a common interface:
protocol TypeProtocol {
var id: UUID { get }
var image: UIImage { get }
}
struct TypeOne: TypeProtocol {
let id = UUID()
var image: UIImage
}
struct TypeTwo: TypeProtocol {
let id = UUID()
var image: UIImage
var url: URL
}
Your enum can largely be the same but we can extend it with some convenient properties.
enum Types {
case one(a: TypeOne)
case two(b: TypeTwo)
}
extension Types: TypeProtocol {
var id: UUID {
type.id
}
var image: UIImage {
type.image
}
var type: TypeProtocol {
switch self {
case .one(let a):
return a
case .two(let b):
return b
}
}
}
Finally, given an array of types we can use the convenience properties to access the underlying data:
var array: [Types] = []
array.forEach { print($0.id) }
array.forEach { print($0.type.id) }
I have a Single Class like this:
class Single {
static let sharedInstance: Single = Single()
...
}
But I want use Generic in this Class like this:
class Single<T: Hashable> {
static let sharedInstance: Single = Single()
var dic: [T: Any] = [:] // Here use the Generic
}
I got this result from Xcode
Static stored properties not supported in generic types
I have search this error in stackoverflow, but all the answer for this is not suit for me. Like this one(How to define static constant in a generic class in swift?)
How can I solve this?
You can declare a generic type using a static computed property as follows:
class Single<T: Hashable> {
static var sharedInstance: Single? {
if self.sharedInstance != nil {
return self.sharedInstance
} else {
return Single()
}
}
var dic: [T: Any] = [:]
}
I take it you simply want the one singleton to be able to store any hashable key in your dictionary? If so, do the following:
class Single {
static let sharedInstance: Single = Single()
var dic: [AnyHashable : Any] = [:]
}
Single.sharedInstance.dic["Grimxn"] = 1
Single.sharedInstance.dic[1] = "Grimxn"
Single.sharedInstance.dic // [1: "Grimxn", "Grimxn": 1] as required
I wonder if it's possible to obtain a Swift type dynamically. For example, say we have the following nested structs:
struct Constants {
struct BlockA {
static let kFirstConstantA = "firstConstantA"
static let kSecondConstantA = "secondConstantA"
}
struct BlockB {
static let kFirstConstantB = "firstConstantB"
static let kSecondConstantB = "secondConstantB"
}
struct BlockC {
static let kFirstConstantC = "firstConstantBC"
static let kSecondConstantC = "secondConstantC"
}
}
It's possible to get value from kSeconConstantC from a variable). Like:
let variableString = "BlockC"
let constantValue = Constants.variableString.kSecondConstantC
Something akin to NSClassFromString, maybe?
No, it's not possible yet (as a language feature, at least).
What you need is your own type registry. Even with a type registry, you wouldn't be able to get static constants unless you had a protocol for that:
var typeRegistry: [String: Any.Type] = [:]
func indexType(type: Any.Type)
{
typeRegistry[String(type)] = type
}
protocol Foo
{
static var bar: String { get set }
}
struct X: Foo
{
static var bar: String = "x-bar"
}
struct Y: Foo
{
static var bar: String = "y-bar"
}
indexType(X)
indexType(Y)
typeRegistry // ["X": X.Type, "Y": Y.Type]
(typeRegistry["X"] as! Foo.Type).bar // "x-bar"
(typeRegistry["Y"] as! Foo.Type).bar // "y-bar"
A type registry is something that registers your types using a custom Hashable type (say a String or an Int). You can then use this type registry to reference registered types using custom identifiers (a String, in this case).
Since Any.Type by itself isn't all that useful, I constructed an interface Foo through which I could access a static constant bar. Because I know that X.Type and Y.Type both conform to Foo.Type, I forced a cast and read the bar property.