// // KBUser.m // #import "KBUser.h" #import @implementation KBUser + (NSDictionary *)mj_replacedKeyFromPropertyName { return @{ @"userId": @[@"id", @"user_id", @"uid"], @"appleUserId": @[@"appleUserId", @"apple_user_id", @"apple_userid", @"appleUserID"], @"nickname": @[@"nickname", @"nick", @"name"], @"avatar": @[@"avatar", @"avatar_url", @"head", @"headimg"], @"gender": @[@"gender", @"sex"], @"mobile": @[@"mobile", @"phone"], @"email": @[@"email"], @"token": @[@"token", @"access_token", @"accessToken"], @"refreshToken": @[@"refresh_token", @"refreshToken"], @"expiryDate": @[@"expire_at", @"expireAt", @"expires_at", @"expiresAt", @"expired_at"], }; } // 将可能是字符串/时间戳(秒/毫秒)的过期时间,转为 NSDate - (void)setExpiryDate:(NSDate *)expiryDate { _expiryDate = expiryDate; } + (instancetype)userFromResponseObject:(id)jsonObject { if (!jsonObject) return nil; NSDictionary *dict = nil; if ([jsonObject isKindOfClass:NSDictionary.class]) { dict = (NSDictionary *)jsonObject; } else if ([jsonObject isKindOfClass:NSData.class]) { // JSON data -> dict id obj = [NSJSONSerialization JSONObjectWithData:(NSData *)jsonObject options:0 error:NULL]; if ([obj isKindOfClass:NSDictionary.class]) dict = obj; } if (!dict) return nil; // 兼容多种后端包装:优先 data.user,其次 data,本身就是用户 NSDictionary *candidate = nil; id data = dict[@"data"]; if ([data isKindOfClass:NSDictionary.class]) { candidate = data; } id user = [candidate objectForKey:@"user"]; if (![user isKindOfClass:NSDictionary.class]) { user = dict[@"user"]; } NSDictionary *userDict = ([user isKindOfClass:NSDictionary.class]) ? (NSDictionary *)user : (candidate ?: dict); KBUser *u = [KBUser mj_objectWithKeyValues:userDict]; // 额外兼容:若 token 不在用户对象里,尝试从上层提取到模型上 if (u.token.length == 0) { NSString *t = [self pickTokenFromDictionary:dict]; if (t.length) u.token = t; } // 过期时间字段可能是字符串或时间戳,做宽松转换 id exp = userDict[@"expire_at"] ?: userDict[@"expireAt"] ?: userDict[@"expires_at"] ?: userDict[@"expiresAt"] ?: userDict[@"expired_at"]; if ([exp isKindOfClass:NSNumber.class]) { // 兼容秒/毫秒(> 10^11 视为毫秒) NSTimeInterval ts = [(NSNumber *)exp doubleValue]; if (ts > 1e11) ts = ts / 1000.0; u.expiryDate = [NSDate dateWithTimeIntervalSince1970:ts]; } else if ([exp isKindOfClass:NSString.class]) { // 尝试 ISO8601 NSDateFormatter *fmt = [NSDateFormatter new]; fmt.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; fmt.dateFormat = @"yyyy-MM-dd'T'HH:mm:ssZ"; NSDate *d = [fmt dateFromString:(NSString *)exp]; if (!d) { // 尝试纯秒 NSTimeInterval ts = [(NSString *)exp doubleValue]; if (ts > 0) d = [NSDate dateWithTimeIntervalSince1970:ts]; } if (d) u.expiryDate = d; } return u; } + (NSString *)pickTokenFromDictionary:(NSDictionary *)dict { if (![dict isKindOfClass:NSDictionary.class]) return nil; NSString *(^pick)(NSDictionary *) = ^NSString *(NSDictionary *d) { NSArray *keys = @[ @"token", @"access_token", @"accessToken" ]; for (NSString *k in keys) { id v = d[k]; if ([v isKindOfClass:NSString.class] && ((NSString *)v).length > 0) return v; } return nil; }; NSString *t = pick(dict); if (t.length) return t; id data = dict[@"data"]; if ([data isKindOfClass:NSDictionary.class]) { t = pick(data); if (t.length) return t; } id user = dict[@"user"]; if ([user isKindOfClass:NSDictionary.class]) { t = pick(user); if (t.length) return t; } NSDictionary *d2 = dict[@"data"]; if ([d2 isKindOfClass:NSDictionary.class]) { NSDictionary *session = d2[@"session"]; if ([session isKindOfClass:NSDictionary.class]) { t = pick(session); if (t.length) return t; } } return nil; } @end