Archive/잡동사니

firebase 사용법(기초) - 코드리뷰

lgvv 2021. 3. 8. 00:57
//
//  ViewController.swift
//  Firebase101
//
//  Created by joonwon lee on 2021/03/07.
//  Copyright © 2021 leegeonwoo. All rights reserved.
//

import UIKit
import Firebase

class ViewController: UIViewController {

    @IBOutlet weak var dataLabel: UILabel!
    @IBOutlet weak var numOfCustomers: UILabel!
    let db = Database.database().reference()
    
    var customers: [Customer] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        updateLabel()
        saveBasicTypes()
        saveCustomers()
        fetchCustomers()
        
        //update, delete
        updateBasicTypes()
        deleteBasicTypes()
    }
    
    func updateLabel() {
        db.child("firstData").observeSingleEvent(of: .value) { snapshot in
            print("--> \(snapshot)")
            let value = snapshot.value as? String ?? ""
            DispatchQueue.main.async {
                self.dataLabel.text = value
            }
        }
    }
    
    @IBAction func createCustomer(_ sender: Any) {
        saveCustomers()
    }
    
    @IBAction func fetchCustomer(_ sender: Any) {
        fetchCustomers()
    }
    
    func updateCustomers() {
        guard customers.isEmpty == false else { return } // 데이터가 비어 있으면 guard문으로 중지 시키기
        customers[0].name = "Min" // 데베에서 커스터머 0 번 말하는거임
        
        let dictionary = customers.map { $0.toDictionary }
        db.updateChildValues(["customers": dictionary])
    }
    
    @IBAction func updateCustomer(_ sender: Any) {
        updateCustomers()
    }
    
    func deleteCustomers() {
        db.child("customers").removeValue()
    }
    
    @IBAction func deleteCustomer(_ sender: Any) {
        deleteCustomers()
    }
}

// MARK: Add Data
extension ViewController {
    func saveBasicTypes() {
        // Firebase child ("key").setValue(Value)
        // - string, number, dictionary, array
        db.child("int").setValue(3)
        db.child("double").setValue(3.5)
        db.child("str").setValue("string value - 여러분 안녕")
        db.child("array").setValue(["a", "b", "c"])
        db.child("dict").setValue(["id": "anyID", "age": 10, "city": "seoul"])
    }
    
    func saveCustomers() {
        // 책가게
        // 사용자를 저장하겠다
        // 모델 Customer + Book
        
        let books = [Book(title: "Good to Great", author: "Someone"), Book(title: "Hacking Growth", author: "Somebody")] // 책 정보 주기 위함
        
        let customer1 = Customer(id: "\(Customer.id)", name: "Son", books: books)
        Customer.id += 1 // id 갱신 위함
        let customer2 = Customer(id: "\(Customer.id)", name: "Dele", books: books)
        Customer.id += 1
        let customer3 = Customer(id: "\(Customer.id)", name: "Kane", books: books)
        Customer.id += 1
        
        db.child("customers").child(customer1.id).setValue(customer1.toDictionary) // 데이터 넣기
        db.child("customers").child(customer2.id).setValue(customer2.toDictionary)
        db.child("customers").child(customer3.id).setValue(customer3.toDictionary)
    }
}

// MARK: Read(Fetch) Data
extension ViewController {
    func fetchCustomers() {
        db.child("customers").observeSingleEvent(of: .value) { snapshot in
            print("--> \(snapshot.value)")
            do {
                let data = try JSONSerialization.data(withJSONObject: snapshot.value, options: []) // 데이터 구조가 JSON 형태라서 캐치하기 위함 - JSON 데이터 파싱한다고 생각해
                let decoder = JSONDecoder() // 디코딩해주고
                let customers: [Customer] = try decoder.decode([Customer].self, from: data) // 이것도 디코딩해주고 - Codable 작성이 필요한 시점임 여기가
                self.customers = customers // 디코딩한거 넣기
                DispatchQueue.main.async { // 스레드 처리하기 이래야 오래걸려도 사용 가능해
                    self.numOfCustomers.text = "# of Customers: \(customers.count)"
                }
            } catch let error {
                print("---> error: \(error.localizedDescription)")
            }
            
        }
    }
}

extension ViewController {
    func updateBasicTypes() {
//        db.child("int").setValue(3)
//        db.child("double").setValue(3.5)
//        db.child("str").setValue("string value - 여러분 안녕")
        
        db.updateChildValues(["int": 6])
        db.updateChildValues(["double": 5.4])
        db.updateChildValues(["str": "변경된 스트링"])
    }
    
    func deleteBasicTypes() {
        db.child("int").removeValue()
        db.child("double").removeValue()
        db.child("str").removeValue()
    }
}


struct Customer: Codable {
    let id: String
    var name: String
    let books: [Book]
    
    // 데베에 추가하기 위해서 딕셔너리 형태로 바꿔줘야한다 그래서 이 작업이 필요하다
    var toDictionary: [String: Any] {
        let booksArray = books.map { $0.toDictionary } // 달러싸인이 jQuery에서 본 것 같은데, 문자열 처리 간편하게 하기 위함이라고 기억하고 있음.
        // map은 알고리즘 공부하면서 c++에 있는 개념이라 간단히 봤었는데, 딕셔너리 형태로 바꿔주던가 그랬던걸로 기억함. 여튼 간편해서 당시에 좋았는데 ^__^
        let dict: [String: Any] = ["id": id, "name": name, "books": booksArray]
        return dict
    }
    
    // id를 숫자로 사용하기 위한 프로퍼티 개념 같으나 정확하게 이해하지는 못하였음.
    static var id: Int = 0
}

struct Book: Codable {
    let title: String
    let author: String
    
    // 데베에 추가하기 위해서 딕셔너리 형태로 바꿔줘야한다 그래서 이 작업이 필요하다
    var toDictionary: [String: Any] {
        let dict: [String: Any] = ["title": title, "author": author]
        return dict
    }
}

 

데베 구조 직접 그리며 파악하기

'Archive > 잡동사니' 카테고리의 다른 글

iOS 단축키 모음  (0) 2021.03.13
iOS <command> + <shift> + <0>  (0) 2021.03.12
Firebase에 대해서 정리  (0) 2021.03.08
nw_protocol_get_quic_image_block_invoke dlopen libquic failed 에러  (0) 2021.03.06
pod init 문제 발생 해결  (0) 2021.03.06