iOS Swift:查询完成后将数据传递给其他 VC 的最佳方式

Posted

技术标签:

【中文标题】iOS Swift:查询完成后将数据传递给其他 VC 的最佳方式【英文标题】:iOS Swift: best way to pass data to other VCs after query is completed 【发布时间】:2016-11-20 11:36:06 【问题描述】:

上下文: ios 应用采用 Swift 3 编写,由 Firebase 3.0 提供支持

挑战:在我的应用中,用户的 currentScore 存储在 Firebase 上。该用户可以从多个 ViewController 完成/取消完成任务(这将增加/减少其 currentScore)。

应用架构概览:

ProfileVC - 我从 Firebase 获取 currentUser 的数据并显示 currentScore。

⎿ 容器视图

  ⎿ CollectionViewController - users can update their score from here

     ⎿ DetailsVC - (when users tap on a collectionView cell) - again users can update their score from here.

问题:我需要将 currentScore 传递给可以更新分数的 VC。我考虑过在级联中使用 prepare(forSegue) 但这不起作用,因为它在 ProfileVC 上的查询完成之前通过了“nil”。

我想避免使用全局变量,因为有人告诉我这是不好的做法。

任何想法将不胜感激。

【问题讨论】:

如果使用得当且谨慎使用,全局变量是不错的做法。 Apple 在开发者文档中介绍了它们的使用。在您的情况下,如果应用程序范围内需要数据,它可能是合适的。你提到prepareForSegue ..这是一个传递变量的好地方,不清楚为什么它会传递零。每次更改视图时,您是否都在进行 Firebase 查询?如果是这样,那会增加很多不必要的开销。如果需要,请在 Firebase 从查询返回后,在闭包内启动 segue。 【参考方案1】:

为什么不创建一个函数,在你做任何其他事情之前先提取所有数据。

所以在 ViewDidLoad 调用中...

pullFirebaseDataASYNC()

函数如下所示...

typealias CompletionHandler = (_ success: Bool) -> Void

func pullFirebaseDataASYNC() 

    self.pullFirebaseDataFunction()  (success) -> Void in
        if success 

            // Perform all other functions and carry on as normal...

Firebase 函数可能看起来像...

    func pullFirebaseDataFunction(completionHandler: @escaping CompletionHandler) 

    let refUserData = DBProvider.instance.userDataRef
    refUserData.observeSingleEvent(of: .value, with:  snapshot in
        if let dictionary = snapshot.value as? [String: AnyObject] 
            self.userCurrentScore = dictionary["UserScore"] as! Int
            completionHandler(true)
        
    )

然后,当您将信息转移到... 在 ProfileVC 中 创建 2 个属性

var containerVC: ContainerVC!
var userCurrentScore = Int()

在 ProfileVC 中包含以下函数...

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    if segue.identifier == "ProfileToContainerSegue" 
        let destination = segue.destination as! ContainerVC
        containerVC = destination

        containerVC.userCurrentScore = userCurrentScore
      
    

在 ContainerVC 中创建一个属性

    var userCurrentScore = Int()

改进的方法可能是一条错误消息,以确保在用户可以继续之前从 Firebase 提取所有信息... 然后可以通过与上述相同的方式来分隔信息。

【讨论】:

【参考方案2】:

尝试实例化,首先将导航控制器嵌入到您的第一个故事板中,然后将 storyboardID 提供给您要展示的 VC。

 let feedVCScene = self.navigationController?.storyboard?.instantiateViewController(withIdentifier: "ViewControllerVC_ID") as! ViewController

 feedVCScene.scoreToChange = current_Score //  scoreToChange is your local variable in the class

                                           //  current_Score is the current score of the user.

 self.navigationController?.pushViewController(feedVCScene, animated: true)

PS:- 实例化比 模态 segue 故事板传输更健康的原因,它几乎消除了您在来回导航时的内存泄漏,也避免VC的堆叠。

【讨论】:

嘿德拉威人,感谢您的回答。我已经为这个特定部分添加了我的故事板的屏幕截图。我使用第三方库创建了一个可滑动的页面菜单来过滤我的 collectionView。所以基本上一旦用户加载其profileScreen。 profile 元素和 collectionView 同时加载,这就是 segue 过早触发的原因(与我的查询相比)。我不确定我是否理解实例化的含义。这仍然与我添加的其他详细信息相关吗?提前致谢。 是的,它仍然相关。

以上是关于iOS Swift:查询完成后将数据传递给其他 VC 的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

如何快速将数据传递给其他 UIViewcontroller

Swift:将数据传递给 segue

pentaho - 将数据传递给报表查询

Swift segue 不会将数据传递给旧的 ViewController

Swift:如何将数据传递给嵌入在 ContainerView 中的 PageViewController?

将数据传递给另一个组件[重复]