自定义Firebase数据服务类:Swift 3

我正在寻找一种干净的方式来检索(有时保存)来自Swift中Firebase的数据。 我讨厌所有的数据库调用都写在视图控制器代码的中间。 所以我正在寻找一些自定义的数据服务类。 我发现这个教程是接近我想要的: http : //www.mobilecyberpunks.com/ ?p= 82 。

他们答应了第二部分,但我找不到第二部分,所以我猜这是从来没有。 在第二部分中,他们承诺将使用此自定义数据服务(这是整个事件中最重要的部分)来检索和保存数据。

我正在考虑一个API类(如在教程中),当我检索数据,并完成从Firebase检索,我把它保存在这个API类的数据集。 然后我会通知通知中心。 但是我不确定这是最好的做法还是做这件事的好方法。

有没有人有一个想法如何做到这一点(完成本教程我发现或以另一种方式)?

提前致谢!

如果您需要大量的function并且多次调用您的服务器,为通信创build自定义类通常是一个好主意。

这两个首选的方法是:

  • Protocol-Delegate方法

  • _completionBlocks:

下面的答案包含两个。

自定义类

 import Foundation import Firebase @objc protocol FIRShowAlertDelegate { func showFIRAlert(_ message : String) @objc optional func activityIndic() } class FIRController :{ var delegate : FIRShowAlertDelegate! func loginUser(_ emailAddress : String!, password : String , completionBlock : @escaping ((currentUserID : String!) -> Void)){ FIRAuth.auth()?.signIn(withEmail: emailAddress, password: password, completion: {(user,err) in if err != nil{ self.delegate.showFIRAlert("Error logging you in,\(err?.localizedDescription)") }else{ completionBlock(user!.uid) } }) } func retrieveUserData(_ currentId : String!, completionBlock : @escaping ((_ userName : String?) -> Void)){ FIRDatabase.database().reference().child("Users").child(currentId).observeSingleEvent(of: .value, with: {(userSnap) in if userSnap.exists(){ if let userDict = userSnap.value! as? [String:AnyObject]{ completionBlock(userDict["username"] as! String } }else{ completionBlock(nil, nil) print("No such user exists: \(currentId)") } }) } } 

你的ViewController

 class AnyViewController : UIViewController, FIRShowAlertDelegate{ let firebaseControllerHandle : FIRController = FIRController() override func viewDidLoad() { super.viewDidLoad() firebaseControllerHandle.delegate = self firebaseControllerHandle.loginUser("abc@xyz.com", password: "123454321", completionBlock: { (userID) in print("user : \(userID), logged in") }) } func showFIRAlert(_ message : String){ let alertController : UIAlertController = UIAlertController(title: "MyApp", message: message, preferredStyle: .alert) let okAction : UIAlertAction = UIAlertAction(title: "Ok", style: .default) { (alert) in print("User pressed ok function") } alertController.addAction(okAction) alertController.popoverPresentationController?.sourceView = view alertController.popoverPresentationController?.sourceRect = view.frame self.present(alertController, animated: true, completion: nil) } func activityIndic() { // Use for showing the activity indicator while the data is being retrieved } } 

我开始使用这个解决scheme并对其进行了一些修改,然后我find了一个非常方便的解决scheme。

我创build了一个名为FirebaseAPI的自定义类。 这是一个单身人士课程。 该类包含Firebase(authentication,数据库,存储…)的所有方法。

例:

FirebaseAPI.swift

 import FirebaseAuth import FirebaseDatabase class FirebaseAPI { static let shared = FirebaseAPI() private init() {} //Authentication func logInUser(onCompletion: @escaping (String?) -> Void { FIRAuth.auth().signInAnonymously(completion: {(user, error) in if error == nil { onCompletion(user!.uid) } else { onCompletion(nil) } }) } //Database func getObjects(parameter: ParamaterClass, onCompletion: @escaping ([ObjectClass]) -> Void) { Constants.Firebase.References.Object?.observe(.value, with: { snapshot in var objects = [ObjectClass]() if snapshot.exists() { for child in snapshot.children.allObjects { let object = Object(snapshot: child as! FIRDataSnapshot) objects.append(object) } } onCompletion(objects) }) } } 

Constants.swift

 import FirebaseDatabase struct Constants { struct Firebase { static var CurrentUser: FIRDatabaseReference? static var Objects: FIRDatabaseReference? } } 

AppDelegate.swift

 import UIKit import Firebase @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { FIRApp.configure() FirebaseAPI.shared.logInUser(onCompletion { uid in if uid != nil { Constants.Firebase.References.CurrentUser = FIRDatabase.database().reference().child("users").child(uid!) Constants.Firebase.References.CurrentUser.keepSynced(true) Constants.Firebase.References.Objects = FIRDatabase.database().reference().child("objects") Constants.Firebase.Reference.Objects?.keepSynced(true) } }) } return true } 

我可以给你一个在ViewController的FirebaseAPI中调用方法的例子,但是在这里的AppDelegate.swift的代码(FirebaseAPI.shared.logInUser方法)中给出了一个这样的方法的例子。

到目前为止,在3个不同的项目中使用这个结构,它的工作stream利!