How to place a dictionary variable in a separate swift file? - swift

The project needs a big Dictionary, so I place it in anohher swift file that makes the codes look clean. But I got a "Expected declaration" error.
class AA{
var a:Dictionary<String,Array<String>> = [:]
a["a"] = ["aa", "aaa"] // error: Expected declaration
...
...
}
and I want to get it like this:
let aa = AA.a
By now, I have to add it in a func to get it.
class AA{
func getVar()->Dictionary<String,Array<String>>{
var a:Dictionary<String,Array<String>> = [:]
a["a"] = ["aa", "aaa"]
a["b"] = ["bb", "bbb"]
return a
}
}
Any simple way to solve this?
#dasblinkenlight your suggestion is get variable from another viewController, it's a little difference from mine.

The problem is not that you have a dictionary in another file, but that you have assignments outside of a method.
Replacing assignments with a declaration will fix this problem:
class AA {
static let a = [
"a" : ["aa", "aaa"]
, "b" : ["bb", "bbb", "bbbb"]
, "c" : ["cc"]
]
}
Now you can use AA.a in other classes.

As per my understanding , You can't access local variables from another class, You can access it in only of that class method only.
Accessing var from another class,
var someVariable: Type = xValue
Now create object of that class where you have declared variable & access it like,
var getThatValue = yourViewControllerObject.someVariable
Access var with in the same class,
self.yourVar
Or,
static let yourProperty = 0
ClassName.yourProperty // & for swift 3 it would be type(of: self).yourProperty
This interesting topic is discussed nicely in the following links,
Access variable in different class - Swift
Access static variables within class in Swift
In your case i think you have to declare var as a static out of method scope

Related

initializing static variable in different ways with swift

// Type 1:
class A {
static let b = ["m":1, "n":2]
}
// Type 2:
class A {
static let b: [String:Int] = {
let result = ["m":1, "n":2]
return result
}()
}
when we access this static variable like A.b["m"], would it be any difference behind the initialization logic? what situation that we need to use type 1 instead of type 2?
There is no difference between the 2 , static variable will take it's assigned value once then the accessing will be same
Type 1 : is preferred for single line configuration
Type 2 : is used when you need to configure the returned object in a long way e.x : tableView delegate/dataSource/backgroundView where many properties need to be configured

Swift - Declare nested variable names using dot

I'll keep it short. I'm trying to accomplish the following:
class Media {
var likes.count : Int? = 0
}
Obviously the complier throws me an error:
Consecutive declarations on a line must be separated by ';'
Is there a way to work around this? I know that i can eventually do some kind of String Replace using Mirror(reflecting:object) but i'd like to keep it efficient. Would love any help. Thanks.
UPDATE:
I wasn't clear enough, sorry. The issue is that the complier won't let me use . inside the variable declaration name.
The issue is that the complier won't let me use . inside the variable declaration name.
Exactly, a property name in Swift cannot contain the . character.
A possible approach
Now, if you want to be able to write something like this
let media = Media()
media.likes.count = 1
then you need to define your class like shown below
class Media {
class Likes {
var count = 0
}
var likes = Likes()
}
or
class Likes {
var count = 0
}
class Media {
var likes = Likes()
}
A few suggestions
PLEASE don't use implicitly unwrapped optionals like this one
var likes.count : Int! = 0
They are like a gun ready to fire and crash your entire app!
And finally the class keyword begins with a lowercase character: class not Class.
I recommend using a Struct. A Struct is basically the same as a class that is referenced by value. So you can have as many Structs as you want with their own nested variables and functions, just like a class! And the best part is, you never have to use the Struct as a functional piece of code, just as something to namespace your variables in. I do this frequently with a Constants swift file.
struct Constants {
struct MainMenu {
static var height:CGFloat = 420
static var width:CGFloat = 240
static var backgroundColor:UIColor = .red
}
struct MainViewController {
static var toolBarHeight:CGFloat = 49
static var backgroundColor:UIColor = .blue
}
}
Usage:
func getRemainingHeight() ->CGFloat {
let viewHeight = self.view.bounds.size.height
let menuHeight = Constants.MainMenu.height
let toolBarHeight = Constants.MainViewController.toolBarHeight
return viewHeight - (menuHeight + toolBarHeight)
}

Using a string parameter to describe class property

I want to write a function that takes a string and then prints the value of the class property with that name. In practice, there would be more than one property to choose form. For example...
class Apple{
var juiciness : Int = 0
init(juiciness: Int){
self.juiciness = juiciness
}
}
var myApple(juiciness : 10)
func printValue(property : String){
print(Apple.property) // <-- I want to use the string to choose a property
}
Obviously, I can't do this code but I know there has to be a better solution than just I series of if statements.
Apple has done this for you. It is known as key-value observing(KVO).
Try the following code in the playground:
let label = UILabel()
print(label.value(forKey: "font"))
Your own class can support KVO by inheriting from NSObject:
class YourClass: NSObject{ ... }

What is the use of "static" keyword if "let" keyword used to define constants/immutables in swift?

I'm little bit confused about using static keyword in swift. As we know swift introduces let keyword to declare immutable objects. Like declaring the id of a table view cell which most likely won't change during its lifetime. Now what is the use of static keyword in some declaration of struct like:
struct classConstants
{
static let test = "test"
static var totalCount = 0
}
whereas let keyword do the same.In Objective C we used static to declare some constant like
static NSString *cellIdentifier=#"cellId";
Besides which makes me more curious is the use of static keyword along with let and also var keyword. Can anybody explain me where to use this static keyword? More importantly do we really need static in swift?
I will break them down for you:
var : used to create a variable
let : used to create a constant
static : used to create type properties with either let or var. These are shared between all objects of a class.
Now you can combine to get the desired out come:
static let key = "API_KEY" : type property that is constant
static var cnt = 0 : type property that is a variable
let id = 0 : constant (can be assigned only once, but can be assigned at run time)
var price = 0 : variable
So to sum everything up var and let define mutability while static and lack of define scope. You might use static var to keep track of how many instances you have created, while you might want to use just varfor a price that is different from object to object. Hope this clears things up a bit.
Example Code:
class MyClass{
static let typeProperty = "API_KEY"
static var instancesOfMyClass = 0
var price = 9.99
let id = 5
}
let obj = MyClass()
obj.price // 9.99
obj.id // 5
MyClass.typeProperty // "API_KEY"
MyClass.instancesOfMyClass // 0
A static variable is shared through all instances of a class. Throw this example in playground:
class Vehicle {
var car = "Lexus"
static var suv = "Jeep"
}
// changing nonstatic variable
Vehicle().car // Lexus
Vehicle().car = "Mercedes"
Vehicle().car // Lexus
// changing static variable
Vehicle.suv // Jeep
Vehicle.suv = "Hummer"
Vehicle.suv // Hummer
When you change the variable for the static property, that property is now changed in all future instances.
Static Variables are belong to a type rather than to instance of class. You can access the static variable by using the full name of the type.
Code:
class IOS {
var iosStoredTypeProperty = "iOS Developer"
static var swiftStoredTypeProperty = "Swift Developer"
}
//Access the iosStoredTypeProperty by way of creating instance of IOS Class
let iOSObj = IOS()
print(iOSObj.iosStoredTypeProperty) // iOS Developer
//print(iOSObj.swiftStoredTypeProperty)
//Xcode shows the error
//"static member 'swiftStoredTypeProperty' cannot be used on instance of type IOS”
//You can access the static property by using full name of the type
print(IOS.swiftStoredTypeProperty) // Swift Developer
Hope this helps you..
to see the difference between type properties and / or methods and class properties and / or methods, please look at this self explanatory example from apple docs
class SomeClass {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 27
}
class var overrideableComputedTypeProperty: Int {
return 107
}
}
Static properties may only be declared on type, not globally. In other words static property === type property in Swift. To declare type property you have to use static keyword.
"The let keyword defines a constant" is confusing for beginners who are coming from C# background (like me). In C# terms, you can think of "let" as "readonly" variable.
(answer to How exactly does the “let” keyword work in Swift?)
Use both static and let to define constant
public static let pi = 3.1416 // swift
public const double pi = 3.1416; // C#
public static final double pi = 3.1416 // Java
Whenever I use let to define constant, it feels like I am using readonly of C#. So, I use both static and let to define constant in swift.
Let me explain it for those who need Objective-C reference.
Hope you all remember that we were using a constant file in our Objective-C project to keep all the static API keys like below.
/ In your *.m file
static NSString * const kNSStringConst = #"const value";
Here the keyword Static does not mean that the kNSStringConst is a constant, it just defines that the kNSStringConst can be accessed globally. They keyword const makes it constant.
Now let's move to Swift.
In Swift, Static let and Static var are considered as Type Properties, which means that they can be accessed by their type.
For Example:
class World {
static let largestPopulation = "China"
static var secondLargestPopulation = "India"
}
World.largestPopulation = "German" // Cannot assign to property: 'largestPopulation' is a 'let' constant
World.secondLargestPopulation = "UK"
World.secondLargestPopulation // UK
In this example, two properties have static keyword, one is constant and another one is variable.
As you can see, the constant Static let declared can be accessed by it's type, but cannot be
changed.
The Static var declared can not only be accessed by it's type but also can be modified. Consequently, all the future instances will be changed.
[Swift's property]
[var vs let]
[class vs static]
In a nutshell class and static are type property and belongs to Type in a single copy

What is behavior of private access control for swift class?

I tried this with storyboard with Xcode 7 GM Seed:
import UIKit
public class C {
let _secret = arc4random_uniform(1000)
private func secret() -> String {
return "\(_secret) is a secret"
}
}
let c1 = C()
c1.secret()
This compiled and gave me the "secret". So this upsets my understanding of access control for Swift class and object. Why is this happening?
In Swift private means accessible only within the same source file which is what you're doing. If the code in your question was contained in a file C.swift and you would try to access the secret method from another Swift file you would get a compile-time error.
You can read more about the different access modifiers in the official documentation.
Swift 4 Updated answer:
There are two different access controls: fileprivate and private.
fileprivate can be accessed from their entire files.
private can only be accessed from their single declaration and extensions.
For example:
// Declaring "A" class that has the two types of "private" and "fileprivate":
class A {
private var aPrivate: String?
fileprivate var aFileprivate: String?
func accessMySelf() {
// this works fine
self.aPrivate = ""
self.aFileprivate = ""
}
}
// Declaring "B" for checking the abiltiy of accessing "A" class:
class B {
func accessA() {
// create an instance of "A" class
let aObject = A()
// Error! this is NOT accessable...
aObject.aPrivate = "I CANNOT set a value for it!"
// this works fine
aObject.aFileprivate = "I CAN set a value for it!"
}
}
For more information, check Access Control Apple's documentation, Also you could check this answer.