ios - 如何在 GetStream iOS Activity Feed 组件中添加头像图像?

标签 ios swift getstream-io avatar

我的配置:XCode 10.3、Swift 5、MacOS Catalina v10.15

我按照 native 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 View Controller 显示空白头像图像,即使提要中的事件显示正确。如何使用用户的 data.avatarURL 属性正确填充头像图像?

这是主 Storyboard后面的 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 中的 Stream 端。

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()
    }
}

关于ios - 如何在 GetStream iOS Activity Feed 组件中添加头像图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58828268/

相关文章:

ios - JSON 写入错误 - 处理自定义类时类型无效

ios - Alamofire 3->4 Response 和 Response Serializer Swift 3.0 的问题

swift - xcode9.2 中的链接器命令失败,退出代码为 1(使用 -v 查看调用)

getstream-io - 是否有用于在 getstream-io 中创建提要组的 API?

ios - 直接深度链接到特定的聊天或消息?

php - 连接到 getstream php 时出错

ios - xCode 5 中需要 iTunesArtwork png 文件吗?

ios - AVPlayer UITapGestureRecognizer 不工作

ios - AVPlayer 不从子域的 url 加载视频

swift - Sprite 节点定相