【问题标题】:Updating label if value in singleton changes如果单例中的值更改,则更新标签
【发布时间】:2016-11-26 10:02:55
【问题描述】:

我从 Firebase 获取一些用户信息并将其存储到单例中。之后,每次值更改时,我都希望标签也更改,但直到我终止应用程序并返回时才会更改。

如果单例中的值发生变化,我应该如何更新标签?

我有标签视图。在第一个选项卡中我分配值,在第二个选项卡中我尝试将值放入标签。

这是我的单身:

class CurrentUser: NSObject
{
    var generalDetails: User = User()/// Consecutive declarations on a line must be separated by ';'

    static let sharedInstance = CurrentUser()


    fileprivate override init(){
        super.init()
    }

}

像这样我赋值:

self.databaseRef.child("users").child(user.uid).observeSingleEvent(of: .value) { (snapshot:FIRDataSnapshot) in

            guard let firebaseValue = snapshot.value as? [String:AnyObject], let userName = firebaseValue["username"] as? String, let email = firebaseValue["email"] as? String, let reputation = firebaseValue["reputation"] as? Int, let profilePicURL = firebaseValue["profileImageUrl"] as? String
                else
            {
                print("Error with FrB snapshot")//Here
                return
            }

            //Set values
            self.currentUser.generalDetails = User(userName: userName, email: email, reputation: reputation, profileImageURL: profilePicURL, uid: user.uid)
        }

如果我想为标签添加价值,我只需这样做(这个声誉是唯一可以经常改变的东西):

self.reputationLabel.text = String(self.currentUser.generalDetails.reputation)

【问题讨论】:

    标签: ios swift firebase firebase-realtime-database


    【解决方案1】:

    您可以执行以下任一操作:-

    • 使用委托协议方法在单例和您的类之间进行通信,每当您的存储库更改并更新您的标签时触发类中的委托方法。

    • 在你的网络链接中打开一个不同的线程来获取用户在 viewController 本身中的声誉:-

      override func viewDidLoad() {
      super.viewDidLoad()
      
      FIRDatabase.database().reference().child("users").child(FIRAuth.auth()!.currentUser!.uid).child("reputation").observe(.childChanged, with: {(Snapshot) in
      
          print(Snapshot.value!)
          //Update yor label
      })
      

      每次声望值变化时都会调用它。

    【讨论】:

    • 由于某种原因它仍然没有更新标签。是因为我有标签视图吗?
    • 你把这段代码放在哪里了??在 viewController 上的单例中。放在viewController中,也可以试试.value
    • 当然我是在viewController viewDidLoad中添加的。也尝试了 .value ,但仍然没有。因为我使用标签,所以我也在 viewWillAppear 内部尝试过。
    • 知道了!我改变了参考。我可以更改有效参考的答案吗?我做了.chil("users").child("FIRAuth.auth()!.currentUser!.uid).child("reputation")
    • 你能告诉我在这种情况下.childAdded和.value有什么区别吗?
    【解决方案2】:

    我喜欢 Dravidian 的回答,我想提供一个替代方案:KVO

    我们使用 Key-Value Observing 来监控我们的应用是否与 Firebase 服务器断开连接。这是概述。

    我们有一个存储布尔变量 isConnected 的单例,该变量是通过观察 Firebase 中的一个特殊节点来设置的

    var isConnected = rootRef.child(".info/connected")
    

    当连接/断开时,isConnected var 改变状态。

    我们的视图上有一个小图标,向用户指示连接状态;连接时为绿色,断开时为红色,并有一条线穿过。

    那个图标是一个类,在每个类中我们都有观察 isConnected 变量的代码;当它的状态改变时,所有的图标都会自动改变。

    它只需要很少的代码,可重用,干净且易于维护。

    这是来自 Apple 文档的代码 sn-p

    //define a class that you want to observe
    class MyObjectToObserve: NSObject {
        dynamic var myDate = NSDate()
        func updateDate() {
            myDate = NSDate()
        }
    }
    
    //Create a global context variable.
    private var myContext = 0
    
    //create a class that observes the myDate var
    //   and will be notified when that var changes
    class MyObserver: NSObject {
        var objectToObserve = MyObjectToObserve()
    
        objectToObserve.addObserver(self, 
                                    forKeyPath: "myDate",
                                    options: .new, 
                                    context: &myContext)
    

    还有更多,但仅此而已。

    Apple 文档在这里

    Using Swift with Cocoa and Obj-c 3.01: Design Patterns

    并向下滚动 Key-Value Observing 部分。这是一个很好的阅读和非常强大的。它遵循与 Firebase 相同的设计模式(反之亦然)——观察一个节点(变量)并告诉我它何时发生变化。

    【讨论】:

      猜你喜欢
      • 2016-03-15
      • 2016-01-20
      • 1970-01-01
      • 2017-05-06
      • 1970-01-01
      • 1970-01-01
      • 2021-10-27
      • 2011-10-04
      • 2022-11-18
      相关资源
      最近更新 更多