• RootViewController
  • Firestore().collection() - snapshot.documents
  • Refactoring for firebase datas
  • Correct CardView
  • Optional binding for using properties

Set rootViewcontroller as HomeController()

// HomeController
    fileprivate func setupLayout() {
        view.backgroundColor = .white

originally view.backgroundColor is black

import FirebaseFirestore

    fileprivate func fetchUsersFromFirestore() {
        Firestore.firestore().collection("users").getDocuments { (snapshot, err) in
            if let err = err {
                print("Failed to fetch users :", err)
                return
            }
            
            snapshot?.documents.forEach({ (documentSnapshot) in
                let userDictionary = documentSnapshot.data()
                print(userDictionary)
            })
        }
    }

Use collection("users").getDocuments function to get snapshot from Firestore. after checking an error, snapshot?.documents is array for every datas in users.

in forEach documentSnapshot.data() returns each user’s data as dictionary

documentSnapshot.data()

Retrieves all fields in the document as an NSDictionary. Returns nil if the document doesn’t exist.

How to fetch firestore documents?

Let’s go to the Users.swift, add init function with argument as dictionary

// User.swift
    init(dictionary: [String: Any]) {
        // we'll initialize our users here
        // set some default values
        let name = dictionary["fullName"] as? String ?? ""
        self.age = 0
        self.profession = "Jobless"
        self.name = name
        
        let imageUrl = dictionary["imageUrl1"] as? String ?? ""
        self.imageNames = [imageUrl]
    }

Now we have an imageUrl on firestore instead of imageNames or imageName, we need some changes to use it for image.

// HomeController.swift
            snapshot?.documents.forEach({ (documentSnapshot) in
                let userDictionary = documentSnapshot.data()
                let user = User(dictionary: userDictionary)
                self.cardViewModels.append(user.toCardViewModel())
            })
            self.setupDummyCards()

as User’s init function is changed, change the way to make User Models.

  1. make a user for Each data in Firestore
  2. make them to CardViewModel and append to cardViewModels array
  3. call setupDummyCards() to change cardViewModel’s datas to CardView
    fileprivate func setupDummyCards() {
        cardViewModels.forEach { (cardVM) in
            let cardView = CardView(frame: .zero)
            cardView.cardViewModel = cardVM
            cardsDeckView.addSubview(cardView)
            cardView.fillSuperview()
        }
    }

CardView

original CardView.swift

            let imageName = cardViewModel.imageNames.first ?? ""
            imageView.image = UIImage(named: imageName)
import SDWebImage

    var cardViewModel: CardViewModel! {
        didSet {
            let imageName = cardViewModel.imageNames.first ?? ""
            // load our image using some kind of url instead
            if let url = URL(string: imageName) {
                imageView.sd_setImage(with: url)
            }
          ...

import SDWebImage to use sd_setImage(with: url)

imageView.sd_setImage(with: <>, completed: <>)

Set the imageView image with an url.

refactoring in User.swift

struct User: ProducesCardViewModel {

//    let imageNames: [String]
    let imageUrl1: String
    let uid: String
    
    init(dictionary: [String: Any]) {
        ...
        self.imageUrl1 = dictionary["imageUrl1"] as? String ?? ""
        self.uid = dictionary["uid"] as? String ?? ""
    }
    
    func toCardViewModel() -> CardViewModel {
        ...
        return CardViewModel(imageNames: [imageUrl1], attributedString: attributedText, textAlignment: .left)
    }
}

We need 3 pictures each user, change the imageName to imageUrl1 and add uid property

    init(dictionary: [String: Any]) {
        // we'll initialize our users here
        self.age = 0
        self.profession = "Jobless"
        
        self.name = dictionary["fullName"] as? String ?? ""
        self.imageUrl1 = dictionary["imageUrl1"] as? String ?? ""
    }

Make properties optional because every properties could be nil

struct User: ProducesCardViewModel {
    // defining our properties for our model layer
    var name: String?
    var age: Int?
    var profession: String?
//    let imageNames: [String]
    var imageUrl1: String?
    var uid: String?
    
    init(dictionary: [String: Any]) {
        // we'll initialize our users here
        self.age = 0
        self.profession = "Jobless"
        
        self.name = dictionary["fullName"] as? String ?? ""
        self.imageUrl1 = dictionary["imageUrl1"] as? String ?? ""
        self.uid = dictionary["uid"] as? String ?? ""
    }
  
    ...
}

correct init(), toCardViewModel()

    init(dictionary: [String: Any]) {
        // we'll initialize our users here
        self.age = dictionary["age"] as? Int
        self.profession = dictionary["profession"] as? String
        self.name = dictionary["fullName"] as? String ?? ""
        self.imageUrl1 = dictionary["imageUrl1"] as? String ?? ""
        self.uid = dictionary["uid"] as? String ?? ""
    }
    func toCardViewModel() -> CardViewModel {
        let attributedText = NSMutableAttributedString(string: name ?? "", attributes: [.font: UIFont.systemFont(ofSize: 32, weight: .heavy)])
        
        let ageString = age != nil ? "\(age!)" : "N\\A"
        
        attributedText.append(NSAttributedString(string: "  \(ageString)", attributes: [.font: UIFont.systemFont(ofSize: 24, weight: .regular)]))
        
        let professionString = profession != nil ? profession! : "Not available"
        
        attributedText.append(NSAttributedString(string: "\n\(professionString)", attributes: [.font: UIFont.systemFont(ofSize: 20, weight: .regular)]))
        
        return CardViewModel(imageNames: [imageUrl1 ?? ""], attributedString: attributedText, textAlignment: .left)
    }

issue #3

it was because of code in init function. self.profession doesn’t need to be "" when it is nil

as?, as!

다운캐스팅

태그: ,

카테고리:

업데이트:

댓글남기기