2017-04-19 35 views
2

在我的主要VC我看起来像这样在我的FB数据库的变化:同步数据,以避免造成同一观察者再次

ref.child("posts").observe(.childChanged, with: { (snapshot) in 
    .......     
}) 

从这个VC,我可以进入被设置为“存在VC2模态“在我的segue。

现在我想知道我是否可以将实时FB数据从VC1传递到VC2?我知道我可以使用一个segue.identifier并传递数据,当我继续下一个VC时,但这只是一次只发送。或者我应该设置一个委托从vc1获取数据到vc2?

所以有什么办法可以将数据从VC1发送到VC2一旦节点已更新或者我必须在VC2中设置新的.observe()函数?

+0

我想邀请您阅读关于单身人士,并考虑它以解决您的问题:) –

+0

@AchrefGassoumi当然,任何资源,你可以建议? – user2722667

+0

我认为这是你需要的 https://krakendev.io/blog/the-right-to-write-a-singleton ,如果你解决了你的问题,我想看看你的答案,如果没有请留下一个评论,我会在稍后发布一个答案(现在我正在工作不能这样做,对不起) 也尝试阅读这个 https://www.raywenderlich.com/86477/introducing-ios-design-patterns-in- swift-part-1 –

回答

2

首先,我想提醒你的单身设计模式: 在软件工程中,Singleton模式是限制类的实例一个对象一个设计模式。当系统需要一个对象协调动作时,这非常有用。

因此,您需要做的第一件事是创建一个调用,其中包含您从Firebase获得的数据作为参数,我已经做了以下操作以获取以下内容以便在登录时获取用户数据我的应用程序,然后在我的应用程序的每一个部分使用这些数据(我没有任何意图VC之间传递数据,这是绝对错误的做法) 我的用户类是这样的:

import Foundation 
class User { 

    static let sharedInstance = User() 

    var uid: String! 
    var username: String! 
    var firstname: String! 
    var lastname: String! 
    var profilePictureData: Data! 
    var email: String! 
} 

后我已经创建了另一个FirebaseUserManager类(您可​​以在视图控制器中执行此操作,但是为了使未来的更新变得简单,将您的控制器和模型视图分离开来总是一个值得赞赏的想法为您或其他开发者) 所以我firebaseUserManager类包含了这样的事情

import Foundation 
    import Firebase 
    import FirebaseStorage 
    protocol FirebaseSignInUserManagerDelegate: class { 
     func signInSuccessForUser(_ user: FIRUser) 
     func signInUserFailedWithError(_ description: String) 
    } 
    class FirebaseUserManager { 
    weak var firebaseSignInUserManagerDelegate: FirebaseSignInUserManagerDelegate! 
func signInWith(_ mail: String, password: String) { 

     FIRAuth.auth()?.signIn(withEmail: mail, password: password) { (user, error) in 
      if let error = error { 

       self.firebaseSignInUserManagerDelegate.signInUserFailedWithError(error.localizedDescription) 

       return 
      } 

      self.fechProfileInformation(user!) 
     } 
    }   

func fechProfileInformation(_ user: FIRUser) { 

      var ref: FIRDatabaseReference! 
      ref = FIRDatabase.database().reference() 

      let currentUid = user.uid 

      ref.child("users").queryOrderedByKey().queryEqual(toValue: currentUid).observeSingleEvent(of: .value, with: { snapshot in 

       if snapshot.exists() { 

        let dict = snapshot.value! as! NSDictionary 

        let currentUserData = dict[currentUid] as! NSDictionary 

        let singletonUser = User.sharedInstance 
        singletonUser.uid = currentUid 
        singletonUser.email = currentUserData["email"] as! String 
        singletonUser.firstname = currentUserData["firstname"] as! String 
        singletonUser.lastname = currentUserData["lastname"] as! String 
        singletonUser.username = currentUserData["username"] as! String 

        let storage = FIRStorage.storage() 
        let storageref = storage.reference(forURL: "gs://versus-a107c.appspot.com") 
        let imageref = storageref.child("images") 
        let userid : String = (user.uid) 
        let spaceref = imageref.child("\(userid).jpg") 

        spaceref.data(withMaxSize: 1 * 1024 * 1024) { data, error in 
         if let error = error { 
          // Uh-oh, an error occurred! 
          print(error.localizedDescription) 
         } else { 

          singletonUser.profilePictureData = data! 

          print(user) 

          self.firebaseSignInUserManagerDelegate.signInSuccessForUser(user) 
         } 
        } 
       } 
      }) 
     } 
    } 

所以基本上这个类包含了一些协议,我们将实现两个功能,该经理的火力点签到和fechProfileInformation,这将让用户信息

比我的登录视图控制器我做了以下内容:1 落实协议

class LoginViewController: UIViewController, FirebaseSignInUserManagerDelegate 

2在登录butto ñ我做了以下

@IBAction func loginAction(_ sender: UIButton) { 



     guard let email = emailTextField.text, let password = passwordTextField.text else { return } 

     let firebaseUserManager = FirebaseUserManager() 
     firebaseUserManager.firebaseSignInUserManagerDelegate = self 

     firebaseUserManager.signInWith(email, password: password) 
    } 

3实现协议方法: FUNC signInSuccessForUser(_用户:FIRUser){

// Do something example navigate to the Main Menu 
} 

func signInUserFailedWithError(_ description: String) { 
    // Do something : example alert the user 
} 

所以现在当按钮标志上的用户点击有一个创建包含用户数据保存在firebase数据库上的对象

现在出现有趣的部分(您的问题的答案:如何获取应用程序中每个位置的用户数据)

在我的应用程序的每一个部分我可以做

print(User.sharedInstance.uid) or print(User.sharedInstance. username) 

,我得到我想要的价值。

PS:为了正确使用单例,您需要确保在实例化时调用对象。