ios - 如何在 GetStream iOS Activity Feed 组件中添加头像图像?
问题描述
我的配置:XCode 10.3、Swift 5、MacOS Catalina v10.15
我按照原生 iOS 活动源演示 ( https://getstream.io/ios-activity-feed/tutorial/?language=python ) 成功地将活动源添加到我的 XCode 项目。
如何为每个用户添加头像图像?这是我到目前为止所尝试的:
我将头像图像上传到我的后端存储,获取相应的 URL,并使用 json 对象使用我的后端服务器创建一个新用户,如下所示:
{
"id" : "cqtGMiITVSOLE589PJaRt",
"data" : {
"name" : "User4",
"avatarURL" : "https:\/\/firebasestorage.googleapis.com\/v0\/b\/champXXXXX.appspot.com\/o\/profileImage%2FcqtGMiITVSOLXXXXXXXX"
}
}
验证用户已成功创建,但即使提要中的活动正确显示,FlatFeedPresenter 视图控制器仍显示空白头像图像。如何使用用户的 data.avatarURL 属性正确填充头像图像?
这是 Main 故事板后面的 StreamActivity ViewController 类。
import UIKit
import GetStream
import GetStreamActivityFeed
class StreamActivityViewController: FlatFeedViewController<GetStreamActivityFeed.Activity> {
let textToolBar = TextToolBar.make()
override func viewDidLoad() {
if let feedId = FeedId(feedSlug: "timeline") {
let timelineFlatFeed = Client.shared.flatFeed(feedId)
presenter = FlatFeedPresenter<GetStreamActivityFeed.Activity>(flatFeed: timelineFlatFeed, reactionTypes: [.likes, .comments])
}
super.viewDidLoad()
setupTextToolBar()
subscribeForUpdates()
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let detailViewController = DetailViewController<GetStreamActivityFeed.Activity>()
detailViewController.activityPresenter = activityPresenter(in: indexPath.section)
detailViewController.sections = [.activity, .comments]
present(UINavigationController(rootViewController: detailViewController), animated: true)
}
func setupTextToolBar() {
textToolBar.addToSuperview(view, placeholderText: "Share something...")
// Enable image picker
textToolBar.enableImagePicking(with: self)
// Enable URL unfurling
textToolBar.linksDetectorEnabled = true
textToolBar.sendButton.addTarget(self,
action: #selector(save(_:)),
for: .touchUpInside)
textToolBar.updatePlaceholder()
}
@objc func save(_ sender: UIButton) {
// Hide the keyboard.
view.endEditing(true)
if textToolBar.isValidContent, let presenter = presenter {
// print("Message validated!")
textToolBar.addActivity(to: presenter.flatFeed) { result in
// print("From textToolBar: \(result)")
}
}
}
}
更新:
我按照以下答案中的建议更新了 AppDelegate,但即使提要的其余部分正确加载,头像图像仍然没有更新。在以下行设置断点,发现即使 streamUser.avatarURL 设置正确,createdUser 的 avatarURL 属性也是 nil。
print("createdUser: \(createdUser)")
更新了 AppDelegate 代码(必须注释掉
initialViewController?.reloadData()
以解决“'UIViewController' 类型的值没有成员'reloadData'”错误——不确定是否导致头像问题。)
import UIKit
import Firebase
import GetStream
import GetStreamActivityFeed
import GoogleSignIn
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
GIDSignIn.sharedInstance()?.clientID = FirebaseApp.app()?.options.clientID
Database.database().isPersistenceEnabled = true
configureInitialRootViewController(for: window)
return true
}
}
extension AppDelegate {
func configureInitialRootViewController(for window: UIWindow?) {
let defaults = UserDefaults.standard
let initialViewController: UIViewController
if let _ = Auth.auth().currentUser, let userData = defaults.object(forKey: Constants.UserDefaults.currentUser) as? Data, let user = try? JSONDecoder().decode(AppUser.self, from: userData) {
initialViewController = UIStoryboard.initialViewController(for: .main)
AppUser.setCurrent(user)
Client.config = .init(apiKey: Constants.Stream.apiKey, appId: Constants.Stream.appId, token: AppUser.current.userToken)
let streamUser = GetStreamActivityFeed.User(name: user.name, id: user.id)
let avatarURL = URL(string: user.profileImageURL)
streamUser.avatarURL = avatarURL
Client.shared.create(user: streamUser) { [weak initialViewController] result in
if let createdUser = try? result.get() {
print("createdUser: \(createdUser)")
// Refresh from here your view controller.
// Reload data in your timeline feed:
// initialViewController?.reloadData()
}
}
} else {
initialViewController = UIStoryboard.initialViewController(for: .login)
}
window?.rootViewController = initialViewController
window?.makeKeyAndVisible()
}
}
解决方案
推荐的方法是确保用户存在于AppDelegate
.
extension AppDelegate {
func configureInitialRootViewController(for window: UIWindow?) {
let defaults = UserDefaults.standard
let initialViewController: UIViewController
if let _ = Auth.auth().currentUser, let userData = defaults.object(forKey: Constants.UserDefaults.currentUser) as? Data, let user = try? JSONDecoder().decode(AppUser.self, from: userData) {
initialViewController = UIStoryboard.initialViewController(for: .main)
AppUser.setCurrent(user)
Client.config = .init(apiKey: Constants.Stream.apiKey,
appId: Constants.Stream.appId,
token: AppUser.current.userToken,
logsEnabled: true)
let streamUser = GetStreamActivityFeed.User(name: user.name, id: user.id)
streamUser.avatarURL = user.avatarURL
// ensures that the user exists on Stream (if not it will create it)
Client.shared.create(user: streamUser) { [weak initialViewController] result in
if let createdUser = try? result.get() {
Client.shared.currentUser = createdUser
// Refresh from here your view controller.
// Reload data in your timeline feed:
// flatFeedViewController?.reloadData()
}
}
} else {
initialViewController = UIStoryboard.initialViewController(for: .login)
}
window?.rootViewController = initialViewController
window?.makeKeyAndVisible()
}
}
推荐阅读
- java - hibernate为不带括号的数组生成代码
- mysql - Mysql 基于行的二进制日志记录在某些版本的 mysql 中表现不同(行分组)
- scala - Flink-1.4.2 出现错误:对象 contrib 不是包 org.apache.flink 的成员
- c - 嵌入式应用程序中的最佳任务调度策略
- python - 变量赋值中“and”的用例
- objective-c - 无法将多个对象添加到 NSArray
- python - Pandas:删除 col[A] 中的重复项,根据 col[B] 上的条件保持行
- javascript - 获取 JSON 对象内元素的路径
- node.js - 在 express 模板引擎 ejs 中使用智能表?
- c++ - 不能使用指针作为默认模板参数