0

so this is really frustrating. I'm trying to use a singleton to pass a string variable but it's not passing over on the 2nd UIViewController.

Singleton.swift:

class CardName {

var cardName : String = ""

class var sharedInstance : CardName {
    struct Static {
        static let instance : CardName = CardName()
    }
    return Static.instance
}

var returnedCardName : String {
    get{
        return self.cardName
    }

    set {
        self.cardName = newValue
    }
}}

View 1:

CardName.sharedInstance.returnedCardName = "Single pass test"

print("Shared instance name set: \(CardName.sharedInstance.returnedCardName)")

print() is successful at showing the string set correctly.

View 2:

let card_name_shared = CardName.sharedInstance

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())

    card_Name = card_name_shared.returnedCardName
    print("Passed Card Name: \(self.card_name_shared.returnedCardName)")

}

View 2 print() results:

Passed Card Name:

I have this setup with some other views the exact same way but i don't know why it's not working.

I use

self.performSegueWithIdentifier("segue", sender: nil)

to move to the next view. I don't know if that has anything to do with it.

I don't understand how override func prepareForSegue works or if it can help.

Matthew White
  • 199
  • 3
  • 11
  • Use simply card_Name in your print (without self. ). Static doesn't means constance. Probably your card_name_shared constance was created before the .returnedCardName was set to your string – user3441734 Jan 06 '16 at 20:56
  • Instead of using a global singleton you can just pass the data in prepareForSegue as you mentioned. Heres an example of how it works: http://stackoverflow.com/a/29360924/215400 – tskulbru Jan 06 '16 at 21:20

1 Answers1

7

Answer

Are you sure you are reading the value after writing it?

Please check it adding a breakpoint.

It this is the problem you could move the reading from viewDidLoad to viewDidAppear.

Less is more

Your Singleton is working

// from my Playground
CardName.sharedInstance.returnedCardName = "123"
CardName.sharedInstance.returnedCardName // "123"

However is does contain lots of useless and redundant code :D

This is a better version

class CardName {
    static var sharedInstance = CardName()
    private init() {}

    var cardName: String?
}

Please just use

CardName.sharedInstance.cardName = "something"

to save a value.

And

CardName.sharedInstance.cardName

to read that value.

Optional property

The new property, as you can see, is declared as Optional String. It means it can contain nil. This is a better way to represent the absence of value than the empty String you were using.

Luca Angeletti
  • 58,465
  • 13
  • 121
  • 148
  • That doesn't work. When i assign the shared instance variable to a local string variable, it makes me unwrap it using !. When running the app, it crashes. If i assign the shared instance variable straight to a label.text, it appears blank. – Matthew White Jan 06 '16 at 21:57
  • It found the value nil while unwrapping it, meaning it still passes over with no value set to it but when i print out the value once set to the shared instance on View 1, it works. – Matthew White Jan 06 '16 at 21:59
  • I'll try viewDidAppear() instead. – Matthew White Jan 06 '16 at 22:03
  • Yes, I suspect you are reading the value **before** writing it ;) – Luca Angeletti Jan 06 '16 at 22:08
  • Awesome, that worked. I'm still new to Swift, could explain how writing it means using viewDidAppear() or have a resource link i can read? – Matthew White Jan 06 '16 at 22:10
  • Great! [These answers](http://stackoverflow.com/questions/5630649/what-is-the-difference-between-viewwillappear-and-viewdidappear) will help you understand better. – Luca Angeletti Jan 06 '16 at 22:15