Is it possible to evaluate a var/let with Swift? - swift

Based upon this question: << Is the a ScriptEngine or eval()-like function in Swift? >> I'm assuming the following would not work in Swift:
private let BROWN_COLOUR: UIColor = UIColor.brownColor()
...
var colourName: String = "BROWN"
var colour = self[ colourName + "_COLOUR" ] as UIColor!
Correct or not?
Thank you for reading.

No, you cannot do that out of the box. You can, however, use keyed subscription to solve this. Or even easier: use a dictionary to store your values and query that.
But if the object derives from NSObject and the instance variables are marked with #objc, you can query these instance variables with valueForKey.

Related

Swift String variable

//First way
var myVar: String = " Hello"
print(myVar)
//Second way
var str = "Hello"
print(str)
I get the same output no matter which of the two I use. What's the difference between them?
These two are basically the same.
When you use var myVar: String = "Hello", you directly tell the swift compiler that your variable is type String.
When you use var myVar = "Hello", you do not specify the type of your variable, so the swift compiler has do do that for you.
Usually, you can get away without declaring your variable type and just have swift do it for you. However, in some cases, namely computed properties and custom classes/structures, you must manually declare your variable to be a specific type.
In your case, either way is fine. The end result is the same, just be aware of the difference for the future.
These two variable are same but with different names :
var myVar
var str
in swift Type doesn't matter that defined because, swift based on value it recognizes what type it is.

swift how to append UIColor in array

my code is:
public var color = [UIColor]()
color.append(String(UIColor(dragInViews[i]!.backgroundColor)))
this code has an error:
Argument labels '(_:)' do not match any available overloads.
I'm trying to resolve problem but I don't know. What is the problem
how to resolve my problem?
You don't need the String() part (nor the UIColor() initializer), it's already a UIColor and the array is defined as an array of UIColor, so just appending it is more than enough.
public var color = [UIColor]()
color.append(dragInViews[i]!.backgroundColor)
Note that the backgroundColor property of a UIView is already a color, so there's no point in instantiating it again.
That particular error you're seeing is because you were trying to instantiate a color with its initializer in this way UIColor(something), but the initializer that exists is UIColor(white:, alpha:) between others. Check out the documentation here.
You need to create new array of UIColor type and in which you need to append color value not string type directly color
var arrColor = [UIColor]()
arrColor.append(UIColor(dragInViews[i]?.backgroundColor ?? UIColor()))

Can I make a Swift data type infix operator?

So, I want to make an operator ('or') which will allow me to declare a variable like this:
var someNum: Int or Double
This bring an example. I want to actually use it on some custom made data types. But is it possible to make an operator for variable declarations that will allow for said variable to be one of two types depending on what its being assigned? I know what data types are possible of being entered, but unfortunately I would currently either assign it a type of 'Any' with a bunch of failsafe code implemented or change the original data types created. So I was just wondering if this is possible or might even exist.
I used this article as a reference, but from what I read I'm not sure if I can or how I would implement it for my needs.
Custom Operators in Swift
Thanks for any and all the help in advance.
You can't do this in the way you're asking. It's not possible syntactically to use a operator in a declaration like that.
What you can do is use an enum to distinguish the kinds:
enum NumericInput {
case integral(Int)
case fractional(Double)
}
and take that as the type of your variable:
var value: NumericInput
Then you say
value = .integral(someInteger)
You could do this with generics:
struct MyStruct<T>
{
var someNum: T
}
You can then explicitly state the dataType you wish to use by specifying the type on creation: let a = MyStruct<Int>(someNum: 4).
One thing Swift does that makes this all absolutely beautiful is derive the data type from the constructor, so you can also just do this:
let intStruct = MyStruct(someNum: 4)
let floatStruct = MyStruct(someNum: 5.0)
You can just declare the value with type Any.
For example,
var myVar: Any = shouldAssignDouble ? Double(20) : Float(20)
Later when you want to know if the actual type is a Float or Double, you can check it with
myVar is Double //returns true

Syntax to create Dictionary in Swift

As far as I know there are two ways to create an empty dictionary in swift
var randomDict = [Int:Int]()
or
var randomDict = Dictionary<Int, Int>()
Is there any difference between these? Both versions seems to work just the same.
No, both are same.
From Apple's Book on Swift:
The type of a Swift dictionary is written in full as Dictionary<Key, Value>
You can also write the type of a dictionary in shorthand form as [Key: Value]. Although the two forms are functionally identical, the shorthand form is preferred.
So
var randomDict = [Int:Int]()
and
var randomDict = Dictionary<Int, Int>()
both calls the initializer which creates an empty dictionary and are basically the same in different form.
A third way you could do it is:
var randomDict:[Int:Int] = [:]
They're all equivalent as far as the code goes. I prefer one of the shorthand versions.

How to create a global variable?

I have a global variable that needs to be shared among my ViewControllers.
In Objective-C, I can define a static variable, but I can't find a way to define a global variable in Swift.
Do you know of a way to do it?
From the official Swift programming guide:
Global variables are variables that are defined outside of any
function, method, closure, or type context. Global constants and
variables are always computed lazily.
You can define it in any file and can access it in current module anywhere.
So you can define it somewhere in the file outside of any scope. There is no need for static and all global variables are computed lazily.
var yourVariable = "someString"
You can access this from anywhere in the current module.
However you should avoid this as Global variables are not good for application state and mainly reason of bugs.
As shown in this answer, in Swift you can encapsulate them in struct and can access anywhere.
You can define static variables or constant in Swift also. Encapsulate in struct
struct MyVariables {
static var yourVariable = "someString"
}
You can use this variable in any class or anywhere
let string = MyVariables.yourVariable
println("Global variable:\(string)")
//Changing value of it
MyVariables.yourVariable = "anotherString"
Global variables that are defined outside of any method or closure can be scope restricted by using the private keyword.
import UIKit
// MARK: Local Constants
private let changeSegueId = "MasterToChange"
private let bookSegueId = "MasterToBook"
if you want to use it in all of your classes you can use:
public var yourVariable = "something"
if you want to use just in one class you can use :
var yourVariable = "something"
If you don't actually want a global variable, but instead want to save values that persist even when the app closes you can do this:
If you don't actually want to pass data between view controllers but rather simply want to store a global variable you can do this:
This gives a great explanation for how to do this in Swift 5: https://www.hackingwithswift.com/example-code/system/how-to-save-user-settings-using-userdefaults
Summary:
To set a value:
let defaults = UserDefaults.standard
defaults.set("value", forKey: "key")
To get a String value:
let key = defaults.object(forKey: "StringKey") as? [String] ?? [String]()
To get integer value:
let key = defaults.integer(forKey: "IntegerKey")