2017-04-19 66 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:爲了正確使用單例,您需要確保在實例化時調用對象。