This commit is contained in:
2025-12-02 20:33:17 +08:00
parent c56655c728
commit 2f55e7bfa1
12 changed files with 83 additions and 133 deletions

View File

@@ -27,7 +27,7 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network";
_enabled = NO; // _enabled = NO; //
_timeout = 10.0; _timeout = 10.0;
// Accept + 使 Accept-Language // Accept + 使 Accept-Language
NSString *lang = [KBLocalizationManager shared].currentLanguageCode ?: @"en"; NSString *lang = [KBLocalizationManager shared].currentLanguageCode ?: KBLanguageCodeEnglish;
_defaultHeaders = @{ _defaultHeaders = @{
@"Accept": @"*/*", @"Accept": @"*/*",
@"Accept-Language": lang @"Accept-Language": lang

View File

@@ -11,6 +11,16 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
/// 语言码类型(集中管理,避免在各处散落写 @"en"/@"zh-Hans"
typedef NSString *KBLanguageCode NS_EXTENSIBLE_STRING_ENUM;
/// 项目内统一使用的语言常量
FOUNDATION_EXPORT KBLanguageCode const KBLanguageCodeEnglish; // @"en"
FOUNDATION_EXPORT KBLanguageCode const KBLanguageCodeSimplifiedChinese; // @"zh-Hans"
/// 默认支持的语言列表(目前为 @[KBLanguageCodeEnglish, KBLanguageCodeSimplifiedChinese]
FOUNDATION_EXPORT NSArray<KBLanguageCode> *KBDefaultSupportedLanguageCodes(void);
/// 当前语言变更通知(不附带 userInfo /// 当前语言变更通知(不附带 userInfo
extern NSString * const KBLocalizationDidChangeNotification; extern NSString * const KBLocalizationDidChangeNotification;
@@ -20,18 +30,18 @@ extern NSString * const KBLocalizationDidChangeNotification;
/// 单例 /// 单例
+ (instancetype)shared; + (instancetype)shared;
/// 当前语言代码(如:"en"、"zh-Hans"、"ja")。 /// 当前语言代码(如:KBLanguageCodeEnglish、KBLanguageCodeSimplifiedChinese)。
/// 默认会在受支持语言中,按系统首选语言择优匹配。 /// 默认会在受支持语言中,按系统首选语言择优匹配。
@property (nonatomic, copy, readonly) NSString *currentLanguageCode; @property (nonatomic, copy, readonly) KBLanguageCode currentLanguageCode;
/// 支持的语言代码列表。默认 @[@"en", @"zh-Hans"] /// 支持的语言代码列表。默认 `KBDefaultSupportedLanguageCodes()`
/// 建议在启动早期设置;或设置后再调用 `-setCurrentLanguageCode:persist:` 以刷新。 /// 建议在启动早期设置;或设置后再调用 `-setCurrentLanguageCode:persist:` 以刷新。
@property (nonatomic, copy) NSArray<NSString *> *supportedLanguageCodes; @property (nonatomic, copy) NSArray<KBLanguageCode> *supportedLanguageCodes;
/// 设置当前语言。 /// 设置当前语言。
/// @param code 语言代码 /// @param code 语言代码
/// @param persist 是否持久化到共享钥匙串(以便 App 与扩展共享该选择) /// @param persist 是否持久化到共享钥匙串(以便 App 与扩展共享该选择)
- (void)setCurrentLanguageCode:(NSString *)code persist:(BOOL)persist; - (void)setCurrentLanguageCode:(KBLanguageCode)code persist:(BOOL)persist;
/// 清除用户选择,恢复为系统最佳匹配。 /// 清除用户选择,恢复为系统最佳匹配。
- (void)resetToSystemLanguage; - (void)resetToSystemLanguage;
@@ -45,7 +55,7 @@ extern NSString * const KBLocalizationDidChangeNotification;
value:(nullable NSString *)value; value:(nullable NSString *)value;
/// 基于一组“偏好语言”计算最佳支持语言。 /// 基于一组“偏好语言”计算最佳支持语言。
- (NSString *)bestSupportedLanguageForPreferred:(NSArray<NSString *> *)preferred; - (KBLanguageCode)bestSupportedLanguageForPreferred:(NSArray<NSString *> *)preferred;
- (void)reloadFromSharedStorageIfNeeded; - (void)reloadFromSharedStorageIfNeeded;

View File

@@ -7,6 +7,20 @@
#import <Security/Security.h> #import <Security/Security.h>
#import "KBConfig.h" #import "KBConfig.h"
///
KBLanguageCode const KBLanguageCodeEnglish = @"en";
KBLanguageCode const KBLanguageCodeSimplifiedChinese = @"zh-Hans";
///
NSArray<KBLanguageCode> *KBDefaultSupportedLanguageCodes(void) {
static NSArray<KBLanguageCode> *codes;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
codes = @[KBLanguageCodeEnglish, KBLanguageCodeSimplifiedChinese];
});
return codes;
}
/// ///
NSString * const KBLocalizationDidChangeNotification = @"KBLocalizationDidChangeNotification"; NSString * const KBLocalizationDidChangeNotification = @"KBLocalizationDidChangeNotification";
@@ -15,7 +29,7 @@ static NSString * const kKBLocService = @"com.loveKey.nyx.loc";
static NSString * const kKBLocAccount = @"lang"; // UTF8 static NSString * const kKBLocAccount = @"lang"; // UTF8
@interface KBLocalizationManager () @interface KBLocalizationManager ()
@property (nonatomic, copy, readwrite) NSString *currentLanguageCode; // @property (nonatomic, copy, readwrite) KBLanguageCode currentLanguageCode; //
@property (nonatomic, strong) NSBundle *langBundle; // .lproj @property (nonatomic, strong) NSBundle *langBundle; // .lproj
@end @end
@@ -37,11 +51,11 @@ static inline NSMutableDictionary *KBLocBaseKCQuery(void) {
static KBLocalizationManager *m; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ static KBLocalizationManager *m; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{
m = [KBLocalizationManager new]; m = [KBLocalizationManager new];
// //
m.supportedLanguageCodes = @[ @"en", @"zh-Hans" ]; m.supportedLanguageCodes = KBDefaultSupportedLanguageCodes();
// 退 // 退
NSString *saved = [[self class] kc_read]; NSString *saved = [[self class] kc_read];
if (saved.length == 0) { if (saved.length == 0) {
saved = [m bestSupportedLanguageForPreferred:[NSLocale preferredLanguages]] ?: @"en"; saved = [m bestSupportedLanguageForPreferred:[NSLocale preferredLanguages]] ?: KBLanguageCodeEnglish;
} }
[m applyLanguage:saved]; [m applyLanguage:saved];
}); });
@@ -56,7 +70,7 @@ static inline NSMutableDictionary *KBLocBaseKCQuery(void) {
for (NSString *c in supportedLanguageCodes) { for (NSString *c in supportedLanguageCodes) {
if (c.length) { [set addObject:c]; } if (c.length) { [set addObject:c]; }
} }
_supportedLanguageCodes = set.array.count ? set.array : @[ @"en" ]; _supportedLanguageCodes = set.array.count ? (NSArray<KBLanguageCode> *)set.array : @[ KBLanguageCodeEnglish ];
// 广 // 广
if (self.currentLanguageCode.length && ![set containsObject:self.currentLanguageCode]) { if (self.currentLanguageCode.length && ![set containsObject:self.currentLanguageCode]) {
NSString *best = [self bestSupportedLanguageForPreferred:@[self.currentLanguageCode]]; NSString *best = [self bestSupportedLanguageForPreferred:@[self.currentLanguageCode]];
@@ -74,7 +88,7 @@ static inline NSMutableDictionary *KBLocBaseKCQuery(void) {
} }
- (void)resetToSystemLanguage { - (void)resetToSystemLanguage {
NSString *best = [self bestSupportedLanguageForPreferred:[NSLocale preferredLanguages]] ?: @"en"; NSString *best = [self bestSupportedLanguageForPreferred:[NSLocale preferredLanguages]] ?: KBLanguageCodeEnglish;
[self setCurrentLanguageCode:best persist:NO]; [self setCurrentLanguageCode:best persist:NO];
} }
@@ -92,7 +106,7 @@ static inline NSMutableDictionary *KBLocBaseKCQuery(void) {
} }
- (NSString *)bestSupportedLanguageForPreferred:(NSArray<NSString *> *)preferred { - (NSString *)bestSupportedLanguageForPreferred:(NSArray<NSString *> *)preferred {
if (self.supportedLanguageCodes.count == 0) return @"en"; if (self.supportedLanguageCodes.count == 0) return KBLanguageCodeEnglish;
// 1) // 1)
for (NSString *p in preferred) { for (NSString *p in preferred) {
NSString *pLC = p.lowercaseString; NSString *pLC = p.lowercaseString;
@@ -129,7 +143,7 @@ static inline NSMutableDictionary *KBLocBaseKCQuery(void) {
} }
} }
// 4) // 4)
return self.supportedLanguageCodes.firstObject ?: @"en"; return self.supportedLanguageCodes.firstObject ?: KBLanguageCodeEnglish;
} }
#pragma mark - #pragma mark -

View File

@@ -38,8 +38,8 @@
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 1. // 1.
[[FGIAPManager shared] setConfigureWith:[IAPVerifyTransactionObj new]]; [[FGIAPManager shared] setConfigureWith:[IAPVerifyTransactionObj new]];
/// 2 /// 2使
[KBLocalizationManager shared].supportedLanguageCodes = @[ @"en", @"zh-Hans"]; [KBLocalizationManager shared].supportedLanguageCodes = KBDefaultSupportedLanguageCodes();
/// 3 : token /// 3 : token
// [[KBUserSessionManager shared] bootstrapIfNeeded]; // [[KBUserSessionManager shared] bootstrapIfNeeded];

View File

@@ -71,7 +71,10 @@
if (!self) return; if (!self) return;
KBLocalizationManager *mgr = [KBLocalizationManager shared]; KBLocalizationManager *mgr = [KBLocalizationManager shared];
NSString *next = [mgr.currentLanguageCode.lowercaseString hasPrefix:@"zh"] ? @"en" : @"zh-Hans"; //
NSString *next = [mgr.currentLanguageCode.lowercaseString hasPrefix:@"zh"]
? KBLanguageCodeEnglish
: KBLanguageCodeSimplifiedChinese;
[mgr setCurrentLanguageCode:next persist:YES]; [mgr setCurrentLanguageCode:next persist:YES];
// //

View File

@@ -11,22 +11,16 @@ NS_ASSUME_NONNULL_BEGIN
// 标识 // 标识
@property (nonatomic, copy, nullable) NSString *userId; // id/user_id/uid @property (nonatomic, copy, nullable) NSString *userId; // id/user_id/uid
@property (nonatomic, copy, nullable) NSString *appleUserId; // 用 Apple 登录返回的 userID可选
// 基本信息 // 基本信息
@property (nonatomic, copy, nullable) NSString *nickname; @property (nonatomic, copy, nullable) NSString *nickName;
@property (nonatomic, copy, nullable) NSString *avatar; // 头像 URL @property (nonatomic, copy, nullable) NSString *avatarUrl; // 头像 URL
@property (nonatomic, copy, nullable) NSString *gender; // 性别(后端可能返回 string/int统一转字符串存 @property (nonatomic, copy, nullable) NSString *gender; // 性别(后端可能返回 string/int统一转字符串存
@property (nonatomic, copy, nullable) NSString *mobile;
@property (nonatomic, copy, nullable) NSString *email; @property (nonatomic, copy, nullable) NSString *email;
/// 邮箱是否验证
@property (nonatomic, assign) BOOL emailVerified;
// 会话信息 // 会话信息
@property (nonatomic, copy, nullable) NSString *token; // token/access_token/accessToken @property (nonatomic, copy, nullable) NSString *token; // token/access_token/accessToken
@property (nonatomic, copy, nullable) NSString *refreshToken; // refresh_token/refreshToken
@property (nonatomic, strong, nullable) NSDate *expiryDate; // 若后端返回过期时间,转为日期
/// 从后端返回(可能顶层或 data/user 嵌套)中解析用户模型。内部使用 MJExtension。
+ (instancetype)userFromResponseObject:(id)jsonObject;
@end @end

View File

@@ -9,89 +9,10 @@
+ (NSDictionary *)mj_replacedKeyFromPropertyName { + (NSDictionary *)mj_replacedKeyFromPropertyName {
return @{ return @{
@"userId": @[@"id", @"user_id", @"uid"], @"userId": @[@"uid"],
@"appleUserId": @[@"appleUserId", @"apple_user_id", @"apple_userid", @"appleUserID"],
@"nickname": @[@"nickname", @"nick", @"name"],
@"avatar": @[@"avatar", @"avatar_url", @"head", @"headimg"],
@"gender": @[@"gender", @"sex"], @"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 @end

View File

@@ -117,9 +117,9 @@
// terms/privacy // terms/privacy
[self.contentContainerView addSubview:self.agreementTextView]; [self.contentContainerView addSubview:self.agreementTextView];
[self.agreementTextView mas_makeConstraints:^(MASConstraintMaker *make) { [self.agreementTextView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.contentContainerView); // 30 textAlignmentCenter
make.left.greaterThanOrEqualTo(self.contentContainerView).offset(30); make.left.equalTo(self.contentContainerView).offset(30);
make.right.lessThanOrEqualTo(self.contentContainerView).offset(-30); make.right.equalTo(self.contentContainerView).offset(-30);
make.bottom.equalTo(self.contentContainerView).offset(-KB_SAFE_BOTTOM - 84); make.bottom.equalTo(self.contentContainerView).offset(-KB_SAFE_BOTTOM - 84);
}]; }];
@@ -128,14 +128,14 @@
[self.contentContainerView addSubview:forgot]; [self.contentContainerView addSubview:forgot];
[forgot mas_makeConstraints:^(MASConstraintMaker *make) { [forgot mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.contentContainerView); make.centerX.equalTo(self.contentContainerView);
make.bottom.equalTo(self.contentContainerView).offset(-KB_SAFE_BOTTOM - 24); make.bottom.equalTo(self.contentContainerView).offset(-KB_SAFE_BOTTOM - 10);
}]; }];
UIView *accountLine = [UIView new]; UIView *accountLine = [UIView new];
[self.contentContainerView addSubview:accountLine]; [self.contentContainerView addSubview:accountLine];
[accountLine mas_makeConstraints:^(MASConstraintMaker *make) { [accountLine mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.contentContainerView); make.centerX.equalTo(self.contentContainerView);
make.bottom.equalTo(forgot.mas_top).offset(-8); make.bottom.equalTo(forgot.mas_top).offset(-2);
}]; }];
[accountLine addSubview:self.noAccountLabel]; [accountLine addSubview:self.noAccountLabel];
@@ -246,7 +246,7 @@
_emailLoginButton = [UIButton buttonWithType:UIButtonTypeCustom]; _emailLoginButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_emailLoginButton setTitle:KBLocalized(@"Continue Via Email") forState:UIControlStateNormal]; [_emailLoginButton setTitle:KBLocalized(@"Continue Via Email") forState:UIControlStateNormal];
[_emailLoginButton setTitleColor:[UIColor colorWithHex:KBBlackValue] forState:UIControlStateNormal]; [_emailLoginButton setTitleColor:[UIColor colorWithHex:KBBlackValue] forState:UIControlStateNormal];
_emailLoginButton.titleLabel.font = [KBFont medium:16]; _emailLoginButton.titleLabel.font = [KBFont medium:19];
// _emailLoginButton.backgroundColor = [UIColor colorWithHex:0xF7F7F7]; // _emailLoginButton.backgroundColor = [UIColor colorWithHex:0xF7F7F7];
_emailLoginButton.layer.cornerRadius = 10.0; _emailLoginButton.layer.cornerRadius = 10.0;
_emailLoginButton.layer.masksToBounds = YES; _emailLoginButton.layer.masksToBounds = YES;
@@ -291,10 +291,14 @@
NSString *termsText = @"terms of service"; NSString *termsText = @"terms of service";
NSString *privacyText = @"privacy policy"; NSString *privacyText = @"privacy policy";
NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.alignment = NSTextAlignmentCenter; //
NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:fullText NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:fullText
attributes:@{ attributes:@{
NSFontAttributeName : [KBFont regular:12], NSFontAttributeName : [KBFont regular:10],
NSForegroundColorAttributeName : [UIColor colorWithHex:0x717171] NSForegroundColorAttributeName : [UIColor colorWithHex:0x717171],
NSParagraphStyleAttributeName : paragraph
}]; }];
NSString *lowerFull = fullText.lowercaseString; NSString *lowerFull = fullText.lowercaseString;
@@ -332,8 +336,8 @@
if (!_noAccountLabel) { if (!_noAccountLabel) {
_noAccountLabel = [UILabel new]; _noAccountLabel = [UILabel new];
_noAccountLabel.text = KBLocalized(@"Don't Have An Account?"); _noAccountLabel.text = KBLocalized(@"Don't Have An Account?");
_noAccountLabel.font = [KBFont regular:13]; _noAccountLabel.font = [KBFont regular:10];
_noAccountLabel.textColor = [UIColor colorWithWhite:0.45 alpha:1.0]; _noAccountLabel.textColor = [UIColor colorWithHex:KBBlackValue];
} }
return _noAccountLabel; return _noAccountLabel;
} }
@@ -343,7 +347,7 @@
_signUpButton = [UIButton buttonWithType:UIButtonTypeCustom]; _signUpButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_signUpButton setTitle:KBLocalized(@"Sign Up") forState:UIControlStateNormal]; [_signUpButton setTitle:KBLocalized(@"Sign Up") forState:UIControlStateNormal];
[_signUpButton setTitleColor:[UIColor colorWithHex:KBColorValue] forState:UIControlStateNormal]; [_signUpButton setTitleColor:[UIColor colorWithHex:KBColorValue] forState:UIControlStateNormal];
_signUpButton.titleLabel.font = [KBFont medium:13]; _signUpButton.titleLabel.font = [KBFont medium:10];
[_signUpButton addTarget:self action:@selector(onTapSignUp) forControlEvents:UIControlEventTouchUpInside]; [_signUpButton addTarget:self action:@selector(onTapSignUp) forControlEvents:UIControlEventTouchUpInside];
} }
return _signUpButton; return _signUpButton;
@@ -354,7 +358,7 @@
_forgotPasswordButton = [UIButton buttonWithType:UIButtonTypeCustom]; _forgotPasswordButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_forgotPasswordButton setTitle:KBLocalized(@"Forgot Password?") forState:UIControlStateNormal]; [_forgotPasswordButton setTitle:KBLocalized(@"Forgot Password?") forState:UIControlStateNormal];
[_forgotPasswordButton setTitleColor:[UIColor colorWithHex:KBColorValue] forState:UIControlStateNormal]; [_forgotPasswordButton setTitleColor:[UIColor colorWithHex:KBColorValue] forState:UIControlStateNormal];
_forgotPasswordButton.titleLabel.font = [KBFont regular:13]; _forgotPasswordButton.titleLabel.font = [KBFont regular:10];
[_forgotPasswordButton addTarget:self action:@selector(onTapForgotPassword) forControlEvents:UIControlEventTouchUpInside]; [_forgotPasswordButton addTarget:self action:@selector(onTapForgotPassword) forControlEvents:UIControlEventTouchUpInside];
} }
return _forgotPasswordButton; return _forgotPasswordButton;

View File

@@ -43,27 +43,29 @@
if (identityToken.length) params[@"identityToken"] = identityToken; if (identityToken.length) params[@"identityToken"] = identityToken;
if (authorizationCode.length) params[@"accessCode"] = authorizationCode; // 使 if (authorizationCode.length) params[@"accessCode"] = authorizationCode; // 使
if (cred.user.length) params[@"userID"] = cred.user; // if (cred.user.length) params[@"userID"] = cred.user; //
[KBHUD show];
// //
[[KBNetworkManager shared] POST:API_APPLE_LOGIN jsonBody:params headers:nil completion:^(id _Nullable jsonOrData, NSURLResponse * _Nullable response, NSError * _Nullable error) { [[KBNetworkManager shared] POST:API_APPLE_LOGIN jsonBody:params headers:nil completion:^(id _Nullable jsonOrData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
[KBHUD dismiss];
if (error) { if (completion) completion(NO, error); return; } if (error) { if (completion) completion(NO, error); return; }
// JSON token data/user // JSON token data/user
// 使 MJExtension // 使 MJExtension
KBUser *user = [KBUser userFromResponseObject:jsonOrData]; NSDictionary *dict = jsonOrData[@"data"];
KBUser *user = [KBUser mj_objectWithKeyValues:dict];
self.currentUser = user; self.currentUser = user;
NSString *token = user.token ?: [self.class tokenFromResponseObject:jsonOrData]; if (user.token.length == 0) {
if (token.length == 0) {
if (completion) completion(NO, [NSError errorWithDomain:@"KBLogin" code:-2 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"No token returned")}]); if (completion) completion(NO, [NSError errorWithDomain:@"KBLogin" code:-2 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"No token returned")}]);
return; return;
} }
[[KBUserSessionManager shared] handleLoginSuccessWithUser:user];
completion(true,nil);
// App // App
BOOL ok = [[KBAuthManager shared] saveAccessToken:token // BOOL ok = [[KBAuthManager shared] saveAccessToken:user.token
refreshToken:nil // refreshToken:nil
expiryDate:nil // expiryDate:nil
userIdentifier:cred.user]; // userIdentifier:cred.user];
if (completion) completion(ok, ok ? nil : [NSError errorWithDomain:@"KBLogin" code:-3 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Failed to save login state")}]); // if (completion) completion(ok, ok ? nil : [NSError errorWithDomain:@"KBLogin" code:-3 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Failed to save login state")}]);
}]; }];
}]; }];
} }

View File

@@ -97,9 +97,9 @@ static NSString * const kKBSessionInstallFlagKey = @"KBSession.installInitialize
NSString *token = user.token; NSString *token = user.token;
if (token.length > 0) { if (token.length > 0) {
[[KBAuthManager shared] saveAccessToken:token [[KBAuthManager shared] saveAccessToken:token
refreshToken:user.refreshToken refreshToken:nil
expiryDate:user.expiryDate expiryDate:nil
userIdentifier:user.appleUserId ?: user.userId]; userIdentifier:nil];
} }
// App/使 // App/使

View File

@@ -37,7 +37,7 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network";
_enabled = NO; // _enabled = NO; //
_timeout = 10.0; _timeout = 10.0;
// Accept + 使 Accept-Language // Accept + 使 Accept-Language
NSString *lang = [KBLocalizationManager shared].currentLanguageCode ?: @"en"; NSString *lang = [KBLocalizationManager shared].currentLanguageCode ?: KBLanguageCodeEnglish;
_defaultHeaders = @{ _defaultHeaders = @{
@"Accept": @"*/*", @"Accept": @"*/*",
@"Accept-Language": lang @"Accept-Language": lang

View File

@@ -15,6 +15,8 @@
/// 三方 /// 三方
#import <Masonry/Masonry.h> #import <Masonry/Masonry.h>
#import <MJExtension/MJExtension.h>
// 公共配置 // 公共配置
#import "KBConfig.h" #import "KBConfig.h"
#import "KBAPI.h" // 接口路径宏(统一管理) #import "KBAPI.h" // 接口路径宏(统一管理)