1

I'm making an application that has one MainUser class that should be accessible throughout the application. For example, the MainUser class has the variable fullName that contains a String with the full name of the user. I want to be able to access this variable on any other scene of the application to maybe say things like, "Welcome fullName!"

How exactly should I go about doing this? Right now, I am making an object of the MainUser class in the launch screen of the application, and I am planning to pass this object along to every following screen. It doesn't seem very efficient in my mind, so I'm wondering if there is some global method to do it (although I searched this up and found that global variables are rather unstable and unpopular.) The application will only have one user, so there will only be one object ever created for the entire extent of the app.

Any ideas?

I have a lot of experience with Object-Oriented Programming in Java but, as you can probably tell from the question, I've grown rusty because I've been pretty inactive for more than a year.

nhgrif
  • 61,578
  • 25
  • 134
  • 173
applemavs
  • 503
  • 3
  • 9
  • 22
  • possible duplicate of [How do you share data between view controllers and other objects in Swift?](http://stackoverflow.com/questions/29734954/how-do-you-share-data-between-view-controllers-and-other-objects-in-swift) – nhgrif Jun 20 '15 at 00:50

2 Answers2

0

Sounds like a perfect case for a data container singleton. Take a look at this thread, where I explain it in detail, including a sample app written in Swift:

How do you share data between view controllers and other objects in Swift?

A singleton is an object where only a single instance is ever created, and it has a class method that returns that single instance.

A data container singleton is a singleton with properties to store shared data. The example I linked includes code that saves the properties to user defaults when the app moves to the background, and loads them when the singleton is first loaded.

Community
  • 1
  • 1
Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • 1
    This is a comment and what should be a "close as duplicate vote", but not an answer. – nhgrif Jun 20 '15 at 00:48
  • This approach would still allow me to go into the global class and change certain variables, as long as they are not constants, correct? For example, if a user wanted to change his name for whatever reason, a method could be called in the global class to do just that? – applemavs Jun 20 '15 at 00:53
  • How is this not an answer? It suggests a specific solution, and provides a link to a concrete example of that solution. True that close as duplicate would have been another option. – Duncan C Jun 20 '15 at 01:07
  • What global class? You could make your mainUser object a property of the singleton. – Duncan C Jun 20 '15 at 01:09
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – rorra Jun 20 '15 at 18:14
  • @rorra, the link in question is an SO link. If that page changes, this one is just as likely to change. I added some more descriptive info in any case... – Duncan C Jun 20 '15 at 19:22
0

Am not so good in swift hence am posting the code with objective c. I think you can translate that. Here is the main user class which contains properties.

The .h file here

#import <Foundation/Foundation.h>

@interface User : NSObject

@property (nonatomic, strong) NSString *UserID;
@property (nonatomic, strong) NSString *Password;
@property (nonatomic, strong) NSString *UserName;
@property (nonatomic, strong) NSString *Email;

- (instancetype)initWithData:(NSDictionary*)dicData;

@end

The .m file here

#import "User.h"

@implementation User

@synthesize UserID;
@synthesize Password;
@synthesize UserName;
@synthesize Email;

- (instancetype)init
{
    self = [super init];
    if (self) {
        UserID = @"";
        Password = @"";
        UserName = @"";
        Email = @"";
}
    return self;
}

- (void)encodeWithCoder:(NSCoder *)encoder {
    //Encode properties, other class variables, etc

    [encoder encodeObject:self.UserID                           forKey:@"UserID"];
    [encoder encodeObject:self.Password                         forKey:@"Password"];
    [encoder encodeObject:self.UserName                         forKey:@"UserName"];
    [encoder encodeObject:self.Email                            forKey:@"Email"];
}

- (id)initWithCoder:(NSCoder *)decoder {
    if((self = [super init])) {
        //decode properties, other class vars

        self.UserID                           = [decoder decodeObjectForKey:@"UserID"];
        self.Password                         = [decoder decodeObjectForKey:@"Password"];
        self.UserName                         = [decoder decodeObjectForKey:@"UserName"];
        self.Email                            = [decoder decodeObjectForKey:@"Email"];
 }
    return self;
}

- (instancetype)initWithData:(NSDictionary*)dicData
{
    self = [super init];
    if (self) {
        UserID                          = [dicData valueForKey:@"userid"];
        Password                        = [dicData valueForKey:@"password"];
        UserName                        = [dicData valueForKey:@"username"];
        Email                           = [dicData valueForKey:@"email"];
}
    return self;
}

- (void)dealloc
{
    UserID= nil;
    Password = nil;
    UserName= nil;
    Email= nil;
}

@end

And your Singleton Class for storing this class object goes follows.

the .h file here

#import <Foundation/Foundation.h>

#import "User.h"


@interface AppDefaults : NSObject

@property (nonatomic, strong) User *currentUser;

+ (AppDefaults *)defaultInstance;

@end

and .m file here

#import AppDefaults.h

@implementation AppDefaults 

@synthesize currentUser;

static AppDefaults *staticInstance;

+ (AppDefaults *)defaultInstance{
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        staticInstance=[[self alloc] init];
    });

    return staticInstance;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        currentUser = [[User alloc]init];
    }
    return self;
}

@end

Now you need to call the class like this every time

[AppDefaults defaultInstance].currentUser.Email = @"example@something.com";

and at first when app opens you need to assign the user to the defaults class

[AppDefaults defaultInstance].currentUser = [[User alloc]init];

also if you have data for the user then you can pass them and initialize the user class and then you can assign the user object to the defaults class. This will carry value throughout the app. Only thing is to get the user data even after app killed. You need to store users decoded object in NSUserDefaults to retrieve it next time the app launches. Here the code goes

to store

User *user = [[User alloc]initWithData:yourDataDictionary];
NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:user];
[[NSUserDefaults standardUserDefaults] setObject:myEncodedObject forKey:@"loggedUser"];

and for retrieving and storing

NSData *myEncodedObject = [[NSUserDefaults standardUserDefaults] objectForKey:@"loggedUser" ];
User *obj = (User *)[NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
[AppDefaults defaultInstance].currentUser = obj;

Sorry i could not translate it in swift.

Mahesh Agrawal
  • 3,348
  • 20
  • 34