任何一個App都有用戶管理和存儲用戶的個人信息類 礁叔,例如User中所一般包含的的信息user_id锈锤、user_name等 一般會有一個User類存儲這些信息
User.h文件中
@interface User : NSObject
@property (nonatomic, copy, readonly) NSString *user_id;// id
@property (nonatomic, copy, readonly) NSString *user_name;//用戶名
@property (nonatomic, copy, readonly) NSString *login_token;// token
@property (nonatomic, copy, readonly) NSString *nickname;//昵稱
@property (nonatomic, copy, readonly) NSString *avatar;//頭像
@end
這些是基礎(chǔ)的用戶信息,需要走注意的是 這些信息暴露在 User.h 中 但是不允許 其它類修改 需要 加上 readonly 關(guān)鍵字 但是在User.m文件中 定義同樣名字的屬性 但是去掉 readonly 關(guān)鍵字 這樣就保證 只在User類中編輯這些屬性
User.m文件中
@interface User : NSObject
@property (nonatomic, copy) NSString *user_id;// id
@property (nonatomic, copy) NSString *user_name;//用戶名
@property (nonatomic, copy) NSString *login_token;// token
@property (nonatomic, copy) NSString *nickname;//昵稱
@property (nonatomic, copy) NSString *avatar;//頭像
@end
一般配合 User的添加一個UserManager類 用來管理User類
#import "User.h"
typedef void(^LoginFinishedBlock)(BOOL isSuccess, NSString *errorContent);
typedef void (^RegistFinishedBlock)(BOOL isSuccess, NSString *errorContent);
@interface UserManager : NSObject
@property (nonatomic, assign, readonly) BOOL isAlreadyLogin;
@property (nonatomic, copy) LoginFinishedBlock loginBlock;
@property (nonatomic, copy) RegistFinishedBlock registBlock;
+ (instancetype)shareInstance;
- (User *)getUserInfo;
- (void)removeUserInfo;
- (void)userLoginWithInfo:(NSDictionary *)info
onFinised:(LoginFinishedBlock)finished;
- (void)userRegisterWithInfo:(NSDictionary *)info
onFinished:(RegistFinishedBlock)finished;
@end
對于User類的管理 UserManager 最好以單例形式 一般獲取用戶信息都在登錄和注冊的時候獲取用戶的信息 所以在 UserManager 類中 添加 登錄與注冊的網(wǎng)絡(luò)請求 滤蝠。一般請求結(jié)束 數(shù)據(jù)以json 形式返回 通過UserManager類 將json 數(shù)據(jù)轉(zhuǎn)化為 User 類中信息到千,然后在使用的時候 獲取 User類來進(jìn)行各種用戶信息的獲取和使用
以登錄 來講述
- (void)userLoginWithInfo:(NSDictionary *)info onFinised:(LoginFinishedBlock)finished {
NSMutableDictionary *paramsDic = [NSMutableDictionary dictionary];
weakSelf(weakSelf)
[[LLNetwork shareInstance] postWithURL:@"loginAPI"
token:nil
params:paramsDic
isLoading:YES
success:^(id response) {
//添加模擬的數(shù)據(jù) 實際操作中 是回傳的
response = [self mockResponse1];
response = [UserManager dictionaryWithJSON:response];
BOOL isSuccess = [response[@"is_success"] boolValue];
if (!isSuccess) {
NSString *errorMessage = response[@"error_msg"];
finished (NO, errorMessage);
return;
}
//登錄成功
User *user = [[User alloc] initWithDicionary:response];
[weakSelf saveUserInfo:user];
finished (YES, nil);
} failure:^(NSError *error) {
finished (NO, nil);
}];
}
登錄成功后將 response 信息轉(zhuǎn)化為 User類 中各個屬性的值 需要注意的是 User 類一般需要本地化存儲 因為在登錄成功之后 好多地方需要 User的信息 本地化存儲之后 可以方便的獲取User信息 包晰。User信息存儲方法有很多 簡單的可以使用 NSUserDefaults的方式 也可以文件形式 就是writeToFile 尝艘。對于存儲 User類 需要先進(jìn)行 歸檔 將User類信息轉(zhuǎn)化為 NSData 然后 寫入到文件中去如下
// 歸檔
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.user_id forKey:@"user_id"];
[aCoder encodeObject:self.user_name forKey:@"user_name"];
[aCoder encodeObject:self.login_token forKey:@"login_token"];
[aCoder encodeObject:self.nickname forKey:@"nickname"];
[aCoder encodeObject:self.avatar forKey:@"avatar"];
}
// 反歸檔
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
self.user_id = [aDecoder decodeObjectForKey:@"user_id"];
self.user_name = [aDecoder decodeObjectForKey:@"user_name"];
self.login_token = [aDecoder decodeObjectForKey:@"login_token"];
self.nickname = [aDecoder decodeObjectForKey:@"nickname"];
self.avatar = [aDecoder decodeObjectForKey:@"avatar"];
}
return self;
}
登錄成功之后將User信息存儲
- (void)saveUserInfo:(User *)user {
//userDefaults bug 暫時拋棄了
// NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
// [userDefaults setObject:[NSKeyedArchiver archivedDataWithRootObject:user] forKey:kMSuserInfo];
// [userDefaults synchronize];
NSData *userData = [NSKeyedArchiver archivedDataWithRootObject:user];
NSString *path = [self getDataFilePath];
BOOL isWriteSuccess = [userData writeToFile:path atomically:YES];
if (isWriteSuccess) {
DebugLog(@"write success");
} else {
DebugLog(@"write failure");
}
}
開始筆者也是使用 NSUserDefaults的方式存儲User信息 但是 偶爾會出現(xiàn) 存儲的User信息丟失的現(xiàn)象 所以改用 writeToFile的方式 有知道的大神請給解答一二演侯。
獲取User信息也是 通過UserManger 單例獲取的
- (User *)getUserInfo {
NSString *path = [self getDataFilePath];
NSData *userData = [[NSData alloc] initWithContentsOfFile:path];
// NSData *userData = [[NSUserDefaults standardUserDefaults] objectForKey:kMSuserInfo];
if (!userData) {
return nil;
}
User *user = (User *)[NSKeyedUnarchiver unarchiveObjectWithData:userData];
return user;
}
退出登錄的時候 需要將User信息給清除掉,但是 一般App都有清除緩存的功能 ,注意清除緩存的時候需要將 User文件的地址給過濾掉
- (void)removeUserInfo {
NSString *path = [self getDataFilePath];
[self deleteFileWithName:path];
}
- (NSString * )getDataFilePath {
// 注意清理緩存的時候 要過濾掉User 文件
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *userPath = [NSString stringWithFormat:@"%@/MS_USER_INFO",docPath];
[[NSFileManager defaultManager] createDirectoryAtPath:userPath withIntermediateDirectories:YES attributes:nil error:nil];
NSString *filePath = [userPath stringByAppendingPathComponent:@"user.data"];
DebugLog(@"++++ user存儲地址 +++ %@", filePath);
return filePath;
}
- (void)deleteFileWithName:(NSString *)pathName {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *path = [self getDataFilePath];
BOOL deleteSuccess = [fileManager removeItemAtPath:path error:nil];
if (deleteSuccess) {
DebugLog(@"delete success");
} else {
DebugLog(@"delete failure");
}
}
一般App好多頁面都會根據(jù)用戶是否登錄顯示不同的頁面 或者進(jìn)行不同的邏輯操作
所以一般 會添加 用戶是否登錄的屬性
@property (nonatomic, assign, readonly) BOOL isAlreadyLogin;
注意屬性 必須是 readonly 防止被代碼不規(guī)范的小伙伴在其它地方修改
- (BOOL)isAlreadyLogin {
User *user = [self getUserInfo];
if (user.login_token.length > 0 && user.user_name.length > 0) {
return YES;
}
return NO;
}
此處只是簡單的判斷是否登錄邏輯 背亥,如果需要可以做其它更加嚴(yán)謹(jǐn)?shù)呐袛?br> 使用的時候 直接獲取 通過 UserManager 獲取 User類即可
- (void)getUserInfoButtonAction {
User *user = [[UserManager shareInstance] getUserInfo];
BOOL isAlreadyLogin = [UserManager shareInstance].isAlreadyLogin;
NSString *user_id = user.user_id;
NSString *user_name = user.user_name;
NSString *login_token = user.login_token;
NSString *nickname = user.nickname;
NSString *avatar = user.avatar;
self.label.text = [NSString stringWithFormat:@"isAlreadyLogin = %ld user_id = %@\n user_name = %@\n login_token = %@\n nickname = %@\n avatar = %@\n",isAlreadyLogin, user_id, user_name, login_token, nickname, avatar];
}
這就是基礎(chǔ)User類與UserManager類的大部分邏輯 歡迎各位批評指正 簡單的的demo代碼地址如下
https://coding.net/u/liwb/p/UserProject/git/tree/master/UserProduct?public=true