QuickBlox 视频聊天:QBRequest.logInWithUserEmail 与 QBChat.instance().connectWithUser
Posted
技术标签:
【中文标题】QuickBlox 视频聊天:QBRequest.logInWithUserEmail 与 QBChat.instance().connectWithUser【英文标题】:QuickBlox video chat: QBRequest.logInWithUserEmail vs QBChat.instance().connectWithUser 【发布时间】:2016-05-09 22:53:35 【问题描述】:我有一个按照 ios 教程构建的简单 QuickBlox 聊天应用:
http://quickblox.com/developers/Sample-webrtc-ios#Sources
我已成功创建用户并将其登录。但是,当我尝试启动会话时遇到错误:“您必须登录才能使用聊天 API”。
let newSession: QBRTCSession = QBRTCClient.instance().createNewSessionWithOpponents(["12498970"], withConferenceType: QBRTCConferenceType.Video)
我可以通过每次打开 QBChat.instance().connectWithUser 来解决这个问题:
QBChat.instance().connectWithUser(user!) (error) in
if error != nil
print("error: \(error)")
else
print("login to chat succeeded")
但不知何故,这似乎很奇怪,因为每次打开应用程序时我都必须缓存密码或提示用户输入密码。 QBSession.currentSession().currentUser 仍然有效,但 QBChat 用户已失效,这似乎很奇怪。实现这一目标的最佳实践是什么?在所有示例中,密码都是硬编码的。这似乎不是一个很好的解决方案。
【问题讨论】:
我现在在想,我不太了解登录情况。 SDK 中的视频聊天示例仅使用 QBChat.instance().connectWithUser 而不是 QBRequest.logInWithUserLogin。仍然希望从做过的人那里得到一些见解。 【参考方案1】:我最终遵循 Q-municate 中的示例,这是 Quickblox 开发人员构建的一个应用程序,基本上展示了他们的整个软件包,并为您的聊天需求提供了一个实际的解决方案。我还有一些其他自定义的东西,不需要很多功能,所以我仍在尝试挖掘他们如何实现它的细节。 Q-municate的链接:
http://quickblox.com/developers/Q-municate#1._Get_the_source_code.
在他们的登录流程中,他们使用为 Q-municate 编写的 QMApi 模块:
[[QMApi instance] loginWithEmail:email
password:password
rememberMe:weakSelf.rememberMeSwitch.on
completion:^(BOOL success)
[SVProgressHUD dismiss];
if (success)
[[QMApi instance] setAutoLogin:weakSelf.rememberMeSwitch.on
withAccountType:QMAccountTypeEmail];
[weakSelf performSegueWithIdentifier:kTabBarSegueIdnetifier
sender:nil];
];
在 loginWithEmail 中,他们的 settingsManager 缓存了这个登录:
[weakSelf.settingsManager setLogin:email andPassword:password];
这实际上只是在SSKeyChain中缓存密码的一种方式。
[SSKeychain setPassword:password forService:kQMAuthServiceKey account:login];
稍后,当您返回应用程序时,它们会调用自动登录:
if (!self.isAuthorized)
if (self.settingsManager.accountType == QMAccountTypeEmail && self.settingsManager.password && self.settingsManager.login)
NSString *email = self.settingsManager.login;
NSString *password = self.settingsManager.password;
[self loginWithEmail:email password:password rememberMe:YES completion:completion];
else if (self.settingsManager.accountType == QMAccountTypeFacebook)
[self loginWithFacebook:completion];
else
if (completion) completion(NO);
else
if (completion) completion(YES);
self.settingsManager.password 从 SSKeychain 中提取密码:
NSString *password = [SSKeychain passwordForService:kQMAuthServiceKey account:self.login];
在加载主聊天选项卡时调用 autoLogin。这就是我们对 connectToChat 的经典调用:
[[QMApi instance] autoLogin:^(BOOL success)
if (!success)
[[QMApi instance] logoutWithCompletion:^(BOOL succeed)
//
[weakSelf performSegueWithIdentifier:@"SplashSegue" sender:nil];
];
else
// subscribe to push notifications
[[QMApi instance] subscribeToPushNotificationsForceSettings:NO complete:^(BOOL subscribeToPushNotificationsSuccess)
if (!subscribeToPushNotificationsSuccess)
[QMApi instance].settingsManager.pushNotificationsEnabled = NO;
];
[weakSelf connectToChat];
];
因此,从技术上讲,文档在每次应用打开且聊天不再连接时登录聊天是正确的做法。有一种更复杂但更安全的方式来存储该密码,因此用户无需重新输入。
TLDR:它在我的代码中(以及在 swift 中)的工作方式是:
登录时:
QBRequest.logInWithUserEmail(email, password: password, successBlock: (response, user) in
SSKeychain.setPassword(password, forService: "kMyAppLoginServiceKey", account: email)
) (errorResponse) in
print("Error: \(errorResponse)")
self.simpleAlert("Could not log in", defaultMessage: nil, error: nil)
每当聊天视图加载时:
if !QBChat.instance().isConnected()
QBRTCClient.initializeRTC()
QBRTCClient.instance().addDelegate(self)
let user = QBSession.currentSession().currentUser
let password = SSKeychain.passwordForService("kMyAppLoginServiceKey", account: user?.email!)
user!.password = password
QBChat.instance().addDelegate(self)
QBChat.instance().connectWithUser(user!) (error) in
if error != nil
print("error: \(error)")
else
print("login to chat succeeded")
【讨论】:
以上是关于QuickBlox 视频聊天:QBRequest.logInWithUserEmail 与 QBChat.instance().connectWithUser的主要内容,如果未能解决你的问题,请参考以下文章
Quickblox + Swift 3.0 iOS SDK 错误:未找到应用程序和 QBConnectionZoneTypeProduction