Ios swift class without instantiate - ios

How do you (if possible) create a class that anything that references it gets the same object?
So, if I had a LoginClass
and I dont want to create a new instance in each file but rather be able to just do
LoginClass.userID
in any file without first creating an instance of it?

It possible. Use singleton:
Stackoverflow question
Tutorial by Ray Wenderlich

You are looking for a Singleton
This is the code
class Login {
static let sharedInstance = Login()
var userID: String?
private init() {}
}
This is how you retrieve the same instance
Login.sharedInstance
And this is how you use it
Login.sharedInstance.userID = "123"
In a different point of your code...
print(Login.sharedInstance.userID) // 123

Creating one instance per application life cycle means you want to implement Singleton pattern. You can implement singleton like this
class LoginManager {
static let sharedInstance = LoginManager()
var userId:String?
var name:String?
}
And now you can use this like
LoginManager.sharedInstance.userId

Related

Recreate a singleton

I've come to the unfortunate point where I will need to recreate a singleton.
It looks like this
class Myplayer: AVPlayer {
static let sharedInstance: Myplayer = {
let instance = Myplayer()
return instance
}()
As you can see from this, the reason for this is that AVPlayer can sometimes come into a failed state (.status == .failed) and the documentation specifically mentions that the instance itself will need to be recreated in order to work any further.
I have wound up my app with this singleton pattern and have a few months of live traction with it so changing this to a non-singleton pattern would likely take too much work at this point.
So my question is, how can I recreate this singleton in a pretty way?
I use this pattern whenever I need a singleton that is resettable during (for example) unit tests:
class MyManager {
private static var _sharedInstance: MyManager? = nil
static var sharedInstance: MyManager {
if _sharedInstance == nil {
_sharedInstance = MyManager()
}
return _sharedInstance!
}
static func resetSharedInstance() {
_sharedInstance = nil
}
}
You're on the right track. The key is to create a computed property that checks whether the status of the AVPlayer is .failed, and if so, recreates the instance. A second private static let contains a reference to your singleton and gets returned after the check:
import AVKit
class MyPlayer {
private static var avPlayer = AVPlayer()
private static let _sharedInstance = MyPlayer()
public static var sharedInstance: MyPlayer {
if self.avPlayer.status == .failed {
self.avPlayer = AVPlayer()
}
return self._sharedInstance
}
private init () {}
}
There is no need to recreate the singleton.
You can have a public / internal sharedInstance as a computed property which shares the object from a private _sharedInstance. This way, you can not assign a new instance from outside the class. Also add a static function that recreates the instance by assigning the private _sharedInstance a new Myplayer object.
class Myplayer: AVPlayer {
private static var _sharedInstance = Myplayer()
static var sharedInstance: Myplayer {
return Myplayer._sharedInstance
}
static func recreateInstance() {
Myplayer._sharedInstance = Myplayer()
}
}
As posted in comment, you should never recreate a singltone!
By definition:
In software engineering, the singleton pattern is a software design
pattern that restricts the instantiation of a class to one "single"
instance
Maybe it's a bad news for you, but if AVPlayer isn't designed as a singleton, then you will never be sure, that there is only one instance of a class at the moment. So you or somebody else can create at another place another instance of AVPlayer.
Can recreation destroy a singleton pattern? If programming language does support references to the objects, then definitely YES! (At this point I have to say, that I'm not from ios/swift world ;) )
Just consider such scenario: You have a singleton object and somewhere in code there is a variable SomeVariable_A_OfTypeSingleton, let's say static, which points to the singleton object. Then at some point you do recreate a singleton, so that singleton access method does return new object, BUT the variable SomeVariable_A_OfTypeSingleton still have an old reference to the old object.
So you will have two instances of a class and it will not be a singleton anymore.
The only way I see is to reset the state of singleton(that is probably not possible in your case).

Why Can Singleton classes be used as regular classes

I was under the impression that the main reason for using singletons was to make sure that only one instance could be created in a program. I thought that the compiler wouldn't let you create instances of a singleton as if it would be a regular class.
In the following code I have a singleton where I'm creating multiple instances of it and it behaves as a regular class, but for some reason I was expecting an error.
What makes a singleton different than a regular class if it lets you create multiple instances?
// singleton class
class Car {
static let sharedCar = Car()
func run(){
print("Running")
}
}
// use
Car.sharedCar.run()
// other instances- I was expecting an error here
var jetta = Car()
jetta.run()
var cobalt = Car()
cobalt.run()
What am I missing here, can someone explain singletons?
I thought that the compiler wouldn't let you create instances of a singleton as if it would be a regular class.
There is no language feature called "singleton", it is an idiomatic pattern. If you leave your implementation of singleton open for instantiations from outside, there is nothing the compiler can do about that.
In the following code I have a singleton where I'm creating multiple instances of it and it behaves as a regular class, but for some reason I was expecting an error.
You should add a private init to make sure there are no external instantiations:
class Car {
static let sharedCar = Car()
func run(){
print("Running")
}
private init() {
}
}
Now you are the only one who can instantiate your class. Users of Car class outside of your code are forced to rely on sharedCar instance that you create for them.

iOS: Subclass singleton in swift

I have a framework where I have a singleton class, let's say Singleton. This class is used by other classes in the framework.
In the app project I want to subclass this singleton class, e.g. AppSingleton: Singleton. Is it possible? What is the right solution?
I provide a solution but it may be a little hacky.
Class A {
open class var shared: A {
return A.privateShared
}
private static let privateShared = A()
}
Class B {
open class var shared: B {
return A.privateShared
}
private static let privateShared = B()
}
I must clarify, this ways isn't perfect since it actually create 2 instance! So, it will technically not a singleton any more.
However, you can override the class B's property or method to call A.shared method or property instead. You must know what you are doing and consider use the other way to fix the problem you want to solve.

Access array from all Swift Files

I have an array stored in a class that downloads its objects from the internet. My class is set up like so:
class StockManager {
var managerStock: [Dictionary<String, String>] {
return downloadStockFromDatabase()
}
...
}
I access the managerStock from other Swift files in my project like so, but it always resorts to re-downloading the stock again no matter if I have used the variable before (ie. recalls the function downloadStockFromDatabase):
let stockManager = StockManager()
print(stockManager.managerStock)
How would I make sure the managerStock only downloads once and I could use it in any of my files?
This is a question of correct software pattern usage. I would suggest:
make StockManager a singleton, so you will always access the same instance of it
initialize it e.g. in the AppDelegate, i.e. make sure it stays alive for the whole runtime
tip: call managerStock lazily, i.e. only when you really need it and not as part of initialization
As ff10 and holex suggested, make your class a singleton. It will look like this:
class StockManager {
static let sharedInstance = StockManager ()
var managerStock: [Dictionary<String, String>] {
return downloadStockFromDatabase()
}
...
}
Then access it using the static sharedInstance property:
print(StockManager.sharedInstance.managerStock)

Make a Data Class with Swift in Watchkit Target

As simply using the sharedApplication() method is unavailable in WatchKit, utilizing the AppDelegate as a way to store data for all my interfaces/views is no longer an option in WatchKit. Is there an alternative method to do this in swift for WatchKit apps? I have tried making a singleton class like so:
import Foundation
import UIKit
class data: NSObject {
class var sharedInstance : data {
struct Example {
static let instance = data()
}
return Example.instance
}
var value:Int = 0
var increment:Int = 1
}
(This code is from another StackOverflow post, I just forgot the link.) I then try and access the Integer "value" by calling data.value in an interface controller but I get the error 'data.Type' does not have a member named 'value'. How can I fix this error? Or is there a better way to do what I am trying to achieve?
Thanks
The code data.value attempts to access a class variable or method on the class data called value. Since no such variable or method exists you get the error message.
In your definition value is defined as a property on the class data, so to use it you need a valid instance of data. Your sharedInstance method provides the instance.
Also, the convention in Swift is to capitalize class names, so I recommend using Data.

Resources