Bogdan Laukhin
Bogdan Laukhin

Reputation: 1454

How to override setter method for property object that has own properties within?

I have an abstract class AuthResult that has property - Token model class.

#import <Foundation/Foundation.h>

@class Token;

@interface AuthResult : NSObject

+ (instancetype)sharedInstance;    // designated initializer

@property (readwrite, strong, nonatomic) Token *token; 
@property (readwrite, nonatomic) BOOL isAuthorized;

@end

Token model class, in his turn, has 5 properties within:

#import <Foundation/Foundation.h>

@interface Token : NSObject

@property (readwrite, strong, nonatomic) NSString  *accessToken;
@property (readwrite, strong, nonatomic) NSDate    *expirationDate;
@property (readwrite, strong, nonatomic) NSString  *tokenType;
@property (readwrite, strong, nonatomic) NSString  *scope;
@property (readwrite, strong, nonatomic) NSString  *refreshToken;

@end

My goal is to override setter method in AuthResult class in order to handle different cases. E.g. after token refresh request it has refreshToken property empty so I do not need to erase it.

I tried this approach - setter in AuthResult class:

- (void)setToken:(Token *)token {
    _token.accessToken = token.accessToken;
    _token.expirationDate = token.expirationDate;
    _token.tokenType = token.tokenType;
    _token.scope = token.scope;

    if (token.refreshToken != nil) {
        // DO NOT OVERRIDE REFRESH_TOKEN HERE (after refresh token request it comes as null)
        _token.refreshToken = token.refreshToken;
    }
}

But it doesn't work. It makes token object in AuthResult class always empty.

As I see - I don't have an access to object properties. I do have access to instance variable - "_token" object. But I do not have access to HIS properties.

Please advice. Thank you

Upvotes: 0

Views: 1308

Answers (2)

CRD
CRD

Reputation: 53010

But it doesn't work. It makes token object in AuthResult class always empty.

Your property token has a reference type and the default value for such is nil.

In the code you have supplied you never assign any value to token itself. For example the statement:

_token.accessToken = token.accessToken;

is an instruction to assign a value to the accessToken of the object referenced by the value in _token - but as the value in _token is never changed by you from nil there is no object referenced to change the property of. Due to the rules of Objective-C you don't get an error here, which some languages would give, the action simply does nothing.

The question is what are you really trying to do?

If, and I'm guessing at your intention here, your AuthResult object should have its own Token object, the properties of which should be modified by your setter then you are almost there, you just need to allocate a Token object for your AuthResult to own. You could do this with code like:

- (void)setToken:(Token *)token
{
   if(_token == nil)
      _token = Token.new; // don't have a token yet, allocate one
   // now update the fields of our _token from token
   _token.accessToken = token.accessToken;
   _token.expirationDate = token.expirationDate;
   ...

While that solves your immediate problem it does not address the large design issue, should you be doing this? The value in _token can be read by the getter, and as it is a reference that means its properties can be changed by someone using the getter and then setting them. If the object reference by _token is meant to belong to your AuthResult instance that maybe not what you want, for example you might want the getter to return a copy.

So think about your model.

HTH

Upvotes: 1

metronic
metronic

Reputation: 455

You forgot to initialize the token object. You can do it like this:

- (void)setToken:(Token *)token {
_token = [Token new]; //initialize Token Object
_token.accessToken = token.accessToken;
_token.expirationDate = token.expirationDate;
_token.tokenType = token.tokenType;
_token.scope = token.scope;

if (token.refreshToken != nil) {
    // DO NOT OVERRIDE REFRESH_TOKEN HERE (after refresh token request it comes as null)
    _token.refreshToken = token.refreshToken;
}
}

Upvotes: 0

Related Questions