I'm trying to access a singleton value that is accessible throughout my application apart from one function. I can get the value at either end of the function however inside the function it can't be accessed. To confirm I have set these values so they are not empty.
My singleton is declared as follows:
var customer: Customer = Customer.sharedInstance
final class Customer {
static let sharedInstance = Customer()
var name: String!
var address: String!
var zipcode: String!
var id: String!
private init() {}
}
I can access any of these values from within viewDidLoad and other methods apart from one which is below:
fileprivate func processCustomer() {
... Do logic here
print(customer.name) // Print's out nil
... perform closure method
... print(customer.name) // Print's nil
}
Any ideas as I've rewritten it twice already. I've also removed fileprivate and renaming the function. It's almost as if the function can't read the value of a singleton more than once??
Thanks
Related
I'm very new to iOS programming and swift. I am trying to create a singleton class to store my global data. My global data are a struct and an array of this struct. I want to have only one instance of this class, thus a singleton class. Global data should be accessible and editable to all ViewControllers. I have been searching around and I almost have it figured out except one last part. Here is the singleton class:
import Foundations
class Global {
struct Info {
var firstname:String!
var lastname:String!
var status:String!
init (firstname:String, lastname:String, status:String)
{
self.firstname=firstname
self.lastname=lastname
self.status=status
}
}
var testString: String="Test" //for debugging
var member:[Info]=[]
class var SharedGlobal:Global
{
struct Static
{static let instance = Global()}
return Static.instance
}
}
Now I want to access the global variables of this singleton class from some viewControllers. When I type this in xcode:
Global.SharedGlobal.
I get two options one is the array member and the other is the testString. The struct Info is not available. However, if I just type
Global.
then I see Global.Info and Global.SharedGlobal as my options.
Why is that I can't access the struct in my singleton class (i.e. Global.SharedGlobal.Info)? I am missing something? I appreciate any feedback or help. Thanks a lot in advance.
Unless there's a very specific reason to do it, you don't need to nest classes like that.
Let's simplify a bit your code for the exercise:
struct Info {
// No need for these properties to be Implicitly Unwrapped Optionals since you initialize all of them
var firstname: String
var lastname: String
var status: String
init (firstname:String, lastname:String, status:String) {
self.firstname=firstname
self.lastname=lastname
self.status=status
}
}
class Global {
// Now Global.sharedGlobal is your singleton, no need to use nested or other classes
static let sharedGlobal = Global()
var testString: String="Test" //for debugging
var member:[Info] = []
}
// Use the singleton like this
let singleton = Global.sharedGlobal
// Let's create an instance of the info struct
let infoJane = Info(firstname: "Jane", lastname: "Doe", status: "some status")
// Add the struct instance to your array in the singleton
singleton.member.append(infoJane)
Now it would make sense to me. A struct holding info about some user, and I can make any number instances of them - and a singleton class, unique, were I can store these Info instances, this singleton being usable anywhere.
Is it the kind of thing you wanted to achieve?
I have two classes using as singletons.
class Boss {
static let sharedInstance = Boss()
private init() {}
var user_id : String?
var username : String?
}
class Job {
static let sharedInstance = Job()
private init() {}
var job_id : String?
var JobType : String?
}
But after populating the Boss.sharedInstance first, Job.sharedInstance also containing Boss' class variables. But after replacing the sharedInstance with other name (for eg. job_sharedInstance and boss_sharedInstance) respectively, things are working fine. It's quite weird. Can anybody explain me the reason why it would happen like this. Thanks in advance.
Here is the breakpoint. Although Job.sharedInstance does not have user_id, username, etc..., it's showing up.
There is no problem with your code. Both Boss and Job
have a static let sharedInstance property, and these are
completely independent of each other. Different classes
can have static properties with the same name,
and these don't "overlap".
If the debugger shows properties for Job.sharedInstance
which are not even defined in the Job class then this is
a bug in the debugger view.
When in doubt, add print statements to your code.
I have a simple swift class:
class School: NSObject {
var myData: NSData
var timestamp: NSDate
var id: Int
override init() {
//ERROR: Property 'self.myData' not initialized at super.init call
super.init()
}
}
Why I get the compiler error mentioned above?
All properties must be initialized before you chain up to a super initializer. Otherwise you would end up with uninitialized memory, which is not allowed in Swift. Therefore, you must set myData, timestamp, and id or make them optional.
I have the following class:
class FeedDataManager: URLManagerdelegate {
let TAG: String = "FeedDataManager"
weak var mDelegate: KeyboardViewController?
var mModelManager: ModelManager!
var mURLManager: UrlManager!
var mGetNewsTimer: NSTimer?
var mFeedsArray: Array<News>!
var mManagedObjectContext: NSManagedObjectContext!
var mPersistentStoreCoordinator: NSPersistentStoreCoordinator!
var mManagedObjectModel: NSManagedObjectModel!
class var sharedInstance: FeedDataManager {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: FeedDataManager? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = FeedDataManager()
}
return Static.instance!
}
init (aDelegate: KeyboardViewController) {
self.mDelegate = aDelegate
}
}
The Problem: If you look at the init method you will see that it should receive as a parameter a delegate pointer that I want to store in the singleton, so basically I need to pass this parameter to this line:
Static.instance = FeedDataManager()
But I have no idea how it's done, Does any knows how this can be done?
BTW: I saw this link:
Singleton and init with parameter
But the singleton creation there is different.
We can show you how you can add parameter to declaration of singleton, but that's not really a good idea. The entire idea behind a singleton is that it doesn't matter where it is instantiated, you can use it anywhere. What does it mean if you invoked this singleton in two different places in your code, with different parameters? You have a race condition, where the behavior may change depending upon where and how the singleton was first encountered.
Unrelated, but the dispatch_once is redundant. The static variables are already employed with dispatch_once. See discussion at end of http://developer.apple.com/swift/blog/?id=7 (this is primarily geared towards globals, but as they parenthetically point out, it applies to static variables, too). Also, in Swift 1.2, we can now have static class variables, eliminating the need for the struct, too
I am working on implementing a subclass of PFObject called Event, in Swift. I followed the subclassing guide in Parse's docs, but I don't understand how and where to write the code that adds data to the ivars. Below is my what I have in my class so far, including the ivars.
#NSManaged var name:String
#NSManaged var time:NSDate
#NSManaged var favorite:Bool
#NSManaged var moderator: String
#NSManaged var speakers: [String]
#NSManaged var slides: PFFile?
#NSManaged var files: [PFFile]?
override class func initialize() {
var onceToken : dispatch_once_t = 0;
dispatch_once(&onceToken) {
self.registerSubclass()
}
}
class func parseClassName() -> String! {
return "Event"
}
Normally, I would implement an init() constructor or something similar. However, I realized that the data would already be contained in the PFObject's dictionary when it is fetched from the server. Where would I put the code to copy across and put this data in the instance vars from the PFObject's dictionary? This is presuming that I would instantiate the object via a query and fetch from the server and not locally using the object() method.
Based on the comment by deadbeef above, I realized that I can just use Swift's getters and setters for computed properties to read and write values from the PFObject's data dictionary.
For example a property that I intend to have as read-only:
var name:String
{
return self["name"] as String
}
And a property I intend to have as read-write
var favorite:Bool
{
get {
return self["favorite"] as Bool
}
set(value) {
self["favorite"] = value
}
}
You don't have to copy manually.
That's the Parse framework job. The objects will be populated with data after a fetch.