Skip to content

Commit

Permalink
Merge branch 'develop/stage_3-firebase'
Browse files Browse the repository at this point in the history
  • Loading branch information
peterfriese committed Jan 24, 2020
2 parents 80ec82b + 94e2ec1 commit 7fc1cdc
Show file tree
Hide file tree
Showing 9 changed files with 480 additions and 10 deletions.
16 changes: 16 additions & 0 deletions final/MakeItSo/MakeItSo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
88169CCF23C8A083009CFC9C /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 88169CCE23C8A083009CFC9C /* Preview Assets.xcassets */; };
88169CD223C8A083009CFC9C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 88169CD023C8A083009CFC9C /* LaunchScreen.storyboard */; };
88169CDD23C8A455009CFC9C /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88169CDC23C8A455009CFC9C /* Task.swift */; };
8825908123D9A51900AB7022 /* AuthenticationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8825908023D9A51900AB7022 /* AuthenticationService.swift */; };
886471E923D606BC0095AD8E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 886471E823D606BC0095AD8E /* GoogleService-Info.plist */; };
88D22F5D23CCC5D5003C6D03 /* TaskListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88D22F5C23CCC5D5003C6D03 /* TaskListViewModel.swift */; };
88D22F5F23CCC5E6003C6D03 /* TaskCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88D22F5E23CCC5E6003C6D03 /* TaskCellViewModel.swift */; };
88D22F8223CDDC73003C6D03 /* TaskRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88D22F8123CDDC73003C6D03 /* TaskRepository.swift */; };
Expand All @@ -33,6 +35,8 @@
88169CD123C8A083009CFC9C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
88169CD323C8A083009CFC9C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
88169CDC23C8A455009CFC9C /* Task.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = "<group>"; };
8825908023D9A51900AB7022 /* AuthenticationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationService.swift; sourceTree = "<group>"; };
886471E823D606BC0095AD8E /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
88D22F5C23CCC5D5003C6D03 /* TaskListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskListViewModel.swift; sourceTree = "<group>"; };
88D22F5E23CCC5E6003C6D03 /* TaskCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskCellViewModel.swift; sourceTree = "<group>"; };
88D22F8123CDDC73003C6D03 /* TaskRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskRepository.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -74,13 +78,15 @@
isa = PBXGroup;
children = (
88169CD923C8A0D6009CFC9C /* App */,
8825907F23D9A4FE00AB7022 /* Services */,
88D22F8023CDDC4B003C6D03 /* Repositories */,
88169CDB23C8A1B7009CFC9C /* Models */,
88D22F5B23CCC5BD003C6D03 /* ViewModels */,
88169CDA23C8A0EA009CFC9C /* Views */,
88169CCB23C8A083009CFC9C /* Assets.xcassets */,
88169CD023C8A083009CFC9C /* LaunchScreen.storyboard */,
88169CD323C8A083009CFC9C /* Info.plist */,
886471E823D606BC0095AD8E /* GoogleService-Info.plist */,
88169CCD23C8A083009CFC9C /* Preview Content */,
);
path = MakeItSo;
Expand Down Expand Up @@ -120,6 +126,14 @@
path = Models;
sourceTree = "<group>";
};
8825907F23D9A4FE00AB7022 /* Services */ = {
isa = PBXGroup;
children = (
8825908023D9A51900AB7022 /* AuthenticationService.swift */,
);
path = Services;
sourceTree = "<group>";
};
88D22F5B23CCC5BD003C6D03 /* ViewModels */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -215,6 +229,7 @@
buildActionMask = 2147483647;
files = (
88169CD223C8A083009CFC9C /* LaunchScreen.storyboard in Resources */,
886471E923D606BC0095AD8E /* GoogleService-Info.plist in Resources */,
88169CCF23C8A083009CFC9C /* Preview Assets.xcassets in Resources */,
88169CCC23C8A083009CFC9C /* Assets.xcassets in Resources */,
);
Expand Down Expand Up @@ -272,6 +287,7 @@
88D22F8423CDDE13003C6D03 /* AppDelegate+Injection.swift in Sources */,
88169CDD23C8A455009CFC9C /* Task.swift in Sources */,
88169CC623C8A081009CFC9C /* AppDelegate.swift in Sources */,
8825908123D9A51900AB7022 /* AuthenticationService.swift in Sources */,
88D22F5D23CCC5D5003C6D03 /* TaskListViewModel.swift in Sources */,
88D22F5F23CCC5E6003C6D03 /* TaskCellViewModel.swift in Sources */,
88169CC823C8A081009CFC9C /* SceneDelegate.swift in Sources */,
Expand Down
4 changes: 3 additions & 1 deletion final/MakeItSo/MakeItSo/App/AppDelegate+Injection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import Resolver
extension Resolver: ResolverRegistering {
public static func registerAllServices() {
// register { TestDataTaskRepository() as TaskRepository }.scope(application)
register { LocalTaskRepository() as TaskRepository }.scope(application)
// register { LocalTaskRepository() as TaskRepository }.scope(application)
register { AuthenticationService() }.scope(application)
register { FirebaseTaskRepository() as TaskRepository }.scope(application)
}
}
18 changes: 13 additions & 5 deletions final/MakeItSo/MakeItSo/App/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,36 @@
//

import UIKit
import Firebase
import Resolver

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {


@Injected var authenticationService: AuthenticationService

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.

FirebaseApp.configure()
authenticationService.signIn()

return true
}

// MARK: UISceneSession Lifecycle

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}

func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}

}

5 changes: 4 additions & 1 deletion final/MakeItSo/MakeItSo/Models/Task.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
//

import Foundation
import FirebaseFirestore
import FirebaseFirestoreSwift

enum TaskPriority: Int, Codable {
case high
Expand All @@ -15,10 +17,11 @@ enum TaskPriority: Int, Codable {
}

struct Task: Codable, Identifiable {
var id: String = UUID().uuidString
@DocumentID var id: String?
var title: String
var priority: TaskPriority
var completed: Bool
@ServerTimestamp var createdTime: Timestamp?
}

#if DEBUG
Expand Down
79 changes: 79 additions & 0 deletions final/MakeItSo/MakeItSo/Repositories/TaskRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
import Foundation
import Disk

import Firebase
import FirebaseFirestore
import FirebaseFirestoreSwift

import Combine
import Resolver

class BaseTaskRepository {
@Published var tasks = [Task]()
}
Expand Down Expand Up @@ -89,3 +96,75 @@ class LocalTaskRepository: BaseTaskRepository, TaskRepository, ObservableObject
}
}
}

class FirebaseTaskRepository: BaseTaskRepository, TaskRepository, ObservableObject {
var db = Firestore.firestore()

@Injected var authenticationService: AuthenticationService
var userTasksPath: String = "tasks"

private var cancellables = Set<AnyCancellable>()

override init() {
super.init()

// compute path to task if user changes
authenticationService.$user
.compactMap { user in
user?.uid
}
.map { userId in
"users/\(userId)/tasks"
}
.assign(to: \.userTasksPath, on: self)
.store(in: &cancellables)

// (re)load data if user changes
authenticationService.$user
.receive(on: DispatchQueue.main)
.sink { user in
self.loadData()
}
.store(in: &cancellables)
}

private func loadData() {
db.collection(userTasksPath).order(by: "createdTime").addSnapshotListener { (querySnapshot, error) in
if let querySnapshot = querySnapshot {
self.tasks = querySnapshot.documents.compactMap { document -> Task? in
try? document.data(as: Task.self)
}
}
}
}

func addTask(_ task: Task) {
do {
let _ = try db.collection(userTasksPath).addDocument(from: task)
}
catch {
print("There was an error while trying to save a task \(error.localizedDescription).")
}
}

func removeTask(_ task: Task) {
if let taskID = task.id {
db.collection(userTasksPath).document(taskID).delete { (error) in
if let error = error {
print("Error removing document: \(error.localizedDescription)")
}
}
}
}

func updateTask(_ task: Task) {
if let taskID = task.id {
do {
try db.collection(userTasksPath).document(taskID).setData(from: task)
}
catch {
print("There was an error while trying to update a task \(error.localizedDescription).")
}
}
}
}
36 changes: 36 additions & 0 deletions final/MakeItSo/MakeItSo/Services/AuthenticationService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// AuthenticationService.swift
// MakeItSo
//
// Created by Peter Friese on 23/01/2020.
// Copyright © 2020 Google LLC. All rights reserved.
//

import Foundation
import Firebase

class AuthenticationService: ObservableObject {

@Published var user: User?

func signIn() {
registerStateListener()
Auth.auth().signInAnonymously()
}

private func registerStateListener() {
Auth.auth().addStateDidChangeListener { (auth, user) in
print("Sign in state has changed.")
self.user = user

if let user = user {
let anonymous = user.isAnonymous ? "anonymously " : ""
print("User signed in \(anonymous)with user ID \(user.uid).")
}
else {
print("User signed out.")
}
}
}

}
2 changes: 1 addition & 1 deletion final/MakeItSo/MakeItSo/ViewModels/TaskCellViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class TaskCellViewModel: ObservableObject, Identifiable {
.store(in: &cancellables)

$task
.map { $0.id }
.compactMap { $0.id }
.assign(to: \.id, on: self)
.store(in: &cancellables)

Expand Down
6 changes: 5 additions & 1 deletion final/MakeItSo/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,9 @@ target 'MakeItSo' do
# Pods for MakeItSo
pod 'Resolver'
pod 'Disk', '~> 0.6.4'


pod 'Firebase/Auth'
pod 'Firebase/Analytics'
pod 'Firebase/Firestore'
pod 'FirebaseFirestoreSwift'
end
Loading

0 comments on commit 7fc1cdc

Please sign in to comment.