ICRUserUtil.m 7.39 KB
Newer Older
mei's avatar
mei committed
1 2
//
//  ICRUserUtil.m
mei's avatar
mei committed
3
//  XFFruit
mei's avatar
mei committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
//
//  Created by Xummer on 3/29/15.
//  Copyright (c) 2015 Xummer. All rights reserved.
//

#import "ICRUserUtil.h"
#import "SSKeychain.h"
#import "SSKeychainQuery.h"
#import <objc/runtime.h>

#define kSchemePrefix               @"Keychain_"
#define kArchiveName                @"ICRLocalInfo"

NSString *const kSSKeychainPasswordKey = @"password";
NSString *const kSSKeychainUniqueIdentifierKey = @"uniqueIdentifier";

static ICRUserUtil *sharedInstance = nil;

@interface ICRUserUtil ()

@property (copy, nonatomic) NSString *uniqueIdentifier;

@end

@implementation ICRUserUtil

+ (instancetype)sharedInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self class] unarchive];
    });
    return sharedInstance;
}

+ (id)allocWithZone:(NSZone *)zone {
    @synchronized(self) {
        if (sharedInstance == nil) {
            sharedInstance = [super allocWithZone:zone];
            return sharedInstance;
        }
    }
    return nil;
}

+ (id)unarchive {
    NSString *filePath = [[self class] archivePath];
    
    ICRUserUtil *archive = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    if (archive == nil) {
        archive = [[[self class] alloc] init];
    }
    
    return archive;
}

- (id)init {
    if (self = [super init]) {
        self.userName = @"";
        self.password = @"";
        self.registerCode = @"";
        self.uniqueIdentifier = @"";
        self.token = @"";
mei's avatar
mei committed
67
        self.currentStoreID = @"";
mei's avatar
mei committed
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
        
        [self saveArchive];
    }
    
    return self;
}

- (BOOL)saveArchive {
    BOOL result;
    
    // get archive path to storage
    NSString *filePath = [[self class] archivePath];
    
    result = [NSKeyedArchiver archiveRootObject:self toFile:filePath];
    
    if (result) {
        // Save password in keychain
        if ([_userName length] > 0 && [_password length] > 0) {
            [self saveAuthorizeDataToKeychain];
        }
    }
    
    return result;
}

mei's avatar
mei committed
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
#pragma mark - Getter
- (NSString *)uniqueID {
    if (_uniqueID) {
        return _uniqueID;
    }
    else {
        self.uniqueID = [[[NSProcessInfo processInfo] globallyUniqueString] substringToIndex:15];
        [self saveArchive];
        
        return _uniqueID;
    }
}

- (NSString *)mobileID {
     NSString *uniqID15B = self.uniqueID;
    if(_uniqueID.length > 15)
    {
        uniqID15B = [uniqID15B substringToIndex:15];
    }
    NSString *date15B = [[NSDate date] mobileIDDateString];
    NSString *radom6B = [NSString stringWithFormat:@"%@", @( arc4random()%100000 + 100000 )];
    return [NSString stringWithFormat:@"%@%@%@", uniqID15B, date15B, radom6B];
}

mei's avatar
mei committed
117 118 119 120 121
#pragma mark - Public Method
- (BOOL)isLogin {
    return self.token.length > 0;
}

mei's avatar
mei committed
122 123 124 125 126 127 128 129 130 131 132 133 134
- (void)logout {
    if ([_userName length] > 0) {
        [self deleteAuthorizeDataInKeychain];
    }
    
    self.password = nil;
    self.token = nil;
    self.bAutoLogin = @( NO );
    self.currentStoreID = @"";
    
    [self saveArchive];
}

mei's avatar
mei committed
135 136 137 138 139 140 141 142 143 144 145 146
- (void)storageUserName:(NSString *)userName
               password:(NSString *)password
           registerCode:(NSString *)registerCode
                  token:(NSString *)token {
    self.userName = userName;
    self.password = password;
    self.registerCode = registerCode;
    self.token = token;
    
    [self saveArchive];
}

mei's avatar
mei committed
147 148 149 150 151 152 153 154 155 156 157 158 159
- (void)storageCurrentStoreID:(NSString *)currentStoreID {
    self.currentStoreID = currentStoreID;
    [self saveArchive];
}

- (void)updatePassword:(NSString *)pwd
{
    if ([self isLogin]) {
        self.password = pwd;
        
        [self saveUniqueIdentifierToKeychain];
    }
}
mei's avatar
mei committed
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
#pragma mark - Utilities

+ (NSString *)archivePath {
    NSString *archiveName = [[kArchiveName stringByDeletingPathExtension]
                             stringByAppendingPathExtension:@"archive"];
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    NSURL *baseURL = [fileManager URLForDirectory:NSApplicationSupportDirectory
                                         inDomain:NSUserDomainMask
                                appropriateForURL:nil
                                           create:YES
                                            error:NULL];
    
    return [[baseURL path] stringByAppendingPathComponent:archiveName];
}

- (NSString *)urlSchemeString {
    NSDictionary *infoDict =[[NSBundle mainBundle] infoDictionary];
    NSString *appName =[infoDict objectForKey:@"CFBundleDisplayName"];
    
    return [NSString stringWithFormat:@"%@%@_", kSchemePrefix, appName];
}

- (void)fetchAuthorizeDataFromKeychain {
    NSString *serviceName = [[self urlSchemeString] stringByAppendingString:_userName];
    
    self.password = [SSKeychain passwordForService:serviceName account:kSSKeychainPasswordKey];
}

- (void)saveAuthorizeDataToKeychain {
    NSString *serviceName = [[self urlSchemeString] stringByAppendingString:_userName];
    
    [SSKeychain setPassword:_password forService:serviceName account:kSSKeychainPasswordKey];
}

- (void)deleteAuthorizeDataInKeychain {
    NSString *serviceName = [[self urlSchemeString] stringByAppendingString:_userName];
    
    [SSKeychain deletePasswordForService:serviceName account:kSSKeychainPasswordKey];
}

- (void)fetchUniqueIdentifierFromKeychain {
    NSString *serviceName = [[self urlSchemeString] stringByAppendingString:kSSKeychainUniqueIdentifierKey];
    
    self.uniqueIdentifier = [SSKeychain passwordForService:serviceName account:kSSKeychainUniqueIdentifierKey];
}

- (void)saveUniqueIdentifierToKeychain {
    NSString *serviceName = [[self urlSchemeString] stringByAppendingString:kSSKeychainUniqueIdentifierKey];
    
    [SSKeychain setPassword:_uniqueIdentifier forService:serviceName account:kSSKeychainUniqueIdentifierKey];
}

- (void)deleteUniqueIdentifierToKeychain {
    NSString *serviceName = [[self urlSchemeString] stringByAppendingString:kSSKeychainUniqueIdentifierKey];
    
    [SSKeychain deletePasswordForService:serviceName account:kSSKeychainUniqueIdentifierKey];
}

#pragma mark - NSCoding
- (id)initWithCoder:(NSCoder *)decoder {
    self = [super init];
    if (!self) {
        return self;
    }
    unsigned int count;
    objc_property_t *properties =
    class_copyPropertyList([self class], &count); for (NSUInteger i = 0; i < count; i++) {
        objc_property_t property = properties[i];
        NSString *key = [NSString stringWithUTF8String:property_getName(property)];
        [self setValue:[decoder decodeObjectForKey:key] forKey:key];
    }
    free(properties);
    
    return self;
}

- (void)encodeWithCoder:(NSCoder *)coder {
    unsigned int count;
    objc_property_t *properties =
    class_copyPropertyList([self class], &count); for (NSUInteger i = 0; i < count; i++) {
        objc_property_t property = properties[i];
        NSString *key = [NSString stringWithUTF8String:property_getName(property)];
        [coder encodeObject:[self valueForKey:key] forKey:key];
    }
    free(properties);
}

#pragma mark - NSCopying protocol methods

- (id)copyWithZone:(NSZone *)zone {
    ICRUserUtil *copy = [[[self class] allocWithZone:zone] init];
    unsigned int count;
    objc_property_t *properties =
    class_copyPropertyList([self class], &count); for (NSUInteger i = 0; i < count; i++) {
        objc_property_t property = properties[i];
        NSString *key = [NSString stringWithUTF8String:property_getName(property)];
        [copy setValue:[self valueForKey:key] forKey:key];
    }
    free(properties);
    
    return copy;
}

@end