article

Tuesday, October 5, 2021

SwiftUI Firebase Simple Tinder App

SwiftUI Firebase Simple Tinder App

In this tutorial i'm going to create a simple Tinder App Using Firebase With SwiftUI.

ContentView.swift
 
//
//  ContentView.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import Firebase
import SDWebImageSwiftUI

struct ContentView: View {
    
    @ObservedObject var obs = observer()
    @State var showLiked = false
    
    var body: some View {
       
        ZStack{
            Color(.white).edgesIgnoringSafeArea(.all)
            if obs.users.isEmpty{
                Loader()
            }
            
            VStack{
                TopView(show: $showLiked)
                swipeView()
            }
        }
        .sheet(isPresented: $showLiked) {
            LikedPeople()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
observer.swift
 
//
//  observer.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import Firebase

class observer : ObservableObject{
  
  @Published var users = [datatype]()
  @Published var last = -1
  
  init() {
      
      let db = Firestore.firestore()
      
      db.collection("users").getDocuments { (snap, err) in
          
          if err != nil{
              print((err?.localizedDescription)!)
              return
          }
          
          for i in snap!.documents{
              
              let name = i.get("name") as! String
              let age = i.get("age") as! String
              let image = i.get("image") as! String
              let id = i.documentID
              let status = i.get("status") as! String
              
              if status == ""{
                  self.users.append(datatype(id: id, name: name, image: image, age: age, swipe: 0, degree: 0))
              }
          }
      }
  } //End init()
  
  func update(id : datatype,value : CGFloat,degree : Double){
      print("update \(id.id)")
      for i in 0..<self.users.count{
          
          if self.users[i].id == id.id{
              
              self.users[i].swipe = value
              self.users[i].degree = degree
              self.last = i
          }
      }
  }

  
  func updateDB(id : datatype,status : String){
      
      let db = Firestore.firestore()
      
      db.collection("users").document(id.id).updateData(["status":status]) { (err) in
          
          if err != nil{
              print(err!.localizedDescription)
              return
          }
          print("success \(id.id)")
          
          for i in 0..<self.users.count{
              if self.users[i].id == id.id{
                  if status == "liked"{
                      self.users[i].swipe = 500
                  }else if status == "dislike"{
                      self.users[i].swipe = -500
                  }else{
                      self.users[i].swipe = 0
                  }
              }
          }
          
          if status == "liked" {
              db.collection("liked").document(id.id).setData(["name":id.name,"age":id.age,"image":id.image]) { (err) in
                  if err != nil{
                      print((err?.localizedDescription)!)
                      return
                  }
              }
          }
          
      }
  }// End updateDB
}
datatypes.swift
 
//
//  datatypes.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import Foundation
import SwiftUI

struct datatype : Identifiable {
  
  var id : String
  var name : String
  var image : String
  var age : String
  var swipe : CGFloat
  var degree : Double
}

struct datatype1 : Identifiable {
  var id : String
  var name : String
  var age : String
  var image : String
}
TopView.swift
 
//
//  TopView.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI

struct TopView : View {
  
  @Binding var show : Bool
    
  var body : some View{
        HStack(alignment: .top){
              
              Button(action: {
                  //No action
              }) {
                  Image("photo1").resizable().frame(width: 35, height: 35)
              }.foregroundColor(.gray)
              
              Spacer()
              
              Button(action: {
                  //No action
              }) {
                  Image(systemName: "flame.fill").resizable().frame(width: 30, height: 35)
              }.foregroundColor(.red)
              
              Spacer()
              
              Button(action: {
                  self.show.toggle()
              }) {
                  Image(systemName: "message").resizable().frame(width: 35, height: 35)
              }.foregroundColor(.gray)
              
        }.padding()
    }
}
swipeView.swift
 
//
//  swipeView.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import SDWebImageSwiftUI

struct swipeView: View {
    
    @ObservedObject var obser = observer()
    
    var body : some View{
        VStack {
            GeometryReader{geo in
                
                ZStack{
                    
                    ForEach(self.obser.users){i in

                        SwipeDetailsView(name: i.name, age: i.age, image: i.image, height: geo.size.height - 100).gesture(DragGesture()
                        
                            .onChanged({ (value) in
                                if value.translation.width > 0{
                                    self.obser.update(id: i, value: value.translation.width, degree: 8)
                                }
                                else{
                                    self.obser.update(id: i, value: value.translation.width, degree: -8)
                                }
                            }).onEnded({ (value) in
                                if i.swipe > 0{
                                    if i.swipe > geo.size.width / 2 - 80{
                                        self.obser.update(id: i, value: 500, degree: 0)
                                    }
                                    else{
                                        self.obser.update(id: i, value: 0, degree: 0)
                                    }
                                }
                                else{
                                    if -i.swipe > geo.size.width / 2 - 80{
                                        self.obser.update(id: i, value: -500, degree: 0)
                                    }
                                    else{
                                        self.obser.update(id: i, value: 0, degree: 0)
                                    }
                                }
                            })
                        ).offset(x: i.swipe)
                        .rotationEffect(.init(degrees: i.degree))
                        .animation(.spring())
                    } //End Foreach
                }//End ZStack
            }// End GeometryReader
            
            HStack{
                Button(action: {
                    //No action
                }) {
                    Image(systemName: "arrow.clockwise.circle").resizable().frame(width: 25, height: 25).padding()
                }.foregroundColor(.yellow)
                .background(Color.white)
                .shadow(radius: 25)
                .clipShape(Circle())
                
                //dislike
                Button(action: {
                    if self.obser.last == -1{
                        self.obser.updateDB(id: self.obser.users[self.obser.users.count - 1], status: "dislike")
                    }
                    else{
                        self.obser.updateDB(id: self.obser.users[self.obser.last - 1], status: "dislike")
                    }
                }) {
                    Image(systemName: "xmark.circle").resizable().frame(width: 30, height: 30).padding()
                }.foregroundColor(.pink)
                .background(Color.white)
                .shadow(radius: 25)
                .clipShape(Circle())
                
                Button(action: {
                    //no action
                }) {
                    Image(systemName: "star").resizable().frame(width: 25, height: 25).padding()
                }.foregroundColor(.blue)
                .background(Color.white)
                .shadow(radius: 25)
                .clipShape(Circle())
                
                Button(action: {
                    if self.obser.last == -1{
                        self.obser.updateDB(id: self.obser.users[self.obser.users.count - 1], status: "liked")
                    }
                    else{
                        self.obser.updateDB(id: self.obser.users[self.obser.last - 1], status: "liked")
                    }
                }) {
                    Image(systemName: "heart").resizable().frame(width: 35, height: 35).padding()
                }.foregroundColor(.blue)
                .background(Color.white)
                .shadow(radius: 25)
                .clipShape(Circle())
                
                Button(action: {
                    //no action
                }) {
                    
                    Image(systemName: "rectangle.dashed.badge.record").resizable().frame(width: 25, height: 25).padding()
                    
                }.foregroundColor(.purple)
                .background(Color.white)
                .shadow(radius: 25)
                .clipShape(Circle())
            }
        }
    }
}

struct swipeView_Previews: PreviewProvider {
    static var previews: some View {
        swipeView()
    }
}
Loader.swift
 
//
//  Loader.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI

struct Loader : UIViewRepresentable {
  
  func makeUIView(context: UIViewRepresentableContext<Loader>) -> UIActivityIndicatorView {
      
      let indicator = UIActivityIndicatorView(style: .large)
      indicator.startAnimating()
      return indicator
  }
  
  func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext<Loader>) {
      
      
  }
}
//
//  SwipeDetailsView.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import SDWebImageSwiftUI

struct SwipeDetailsView: View {
    
    var name = ""
    var age = ""
    var image = ""
    var height : CGFloat = 0
    var body: some View {
        ZStack {
            AnimatedImage(url: URL(string: image)!).resizable().cornerRadius(20).padding(.horizontal, 15)
            
            VStack {
                
                Spacer()
                
                HStack {
                    VStack(alignment: .leading, content: {
                        Text(name).fontWeight(.heavy).font(.system(size: 25)).foregroundColor(.white)
                        Text(age).foregroundColor(.white)
                    })
                    Spacer()
                }
            }.padding([.bottom, .leading], 35)
            
        }.frame(height:height)
    }
}

struct SwipeDetailsView_Previews: PreviewProvider {
    static var previews: some View {
        SwipeDetailsView()
    }
}
likedPeople.swift
//
//  likedPeople.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import SDWebImageSwiftUI
import Firebase

struct LikedPeople: View {
  
  @ObservedObject var datas = observer1()
  var body: some View {
      
      VStack{
          if datas.data.isEmpty{
              Text("No Liked People")
          }
          else{
              NavigationView {
                  List(datas.data){i in
                      NavigationLink(destination : Details(userItem: i)) {
                          cards(name: i.name, image: i.image)
                      }
                  }.navigationBarTitle("Like Users")
              }
          }
      }
  }
}

struct cards : View {
  
  var name = ""
  var image = ""
  var body : some View{
      
      HStack{
          AnimatedImage(url: URL(string: image)!).resizable().frame(width: 65, height: 65).clipShape(Circle())
          Text(name).fontWeight(.heavy)
      }
  }
}

class observer1 : ObservableObject{
  
  @Published var data = [datatype1]()
  
  init() {
      
      let db = Firestore.firestore()
      db.collection("liked").getDocuments { (snap, err) in
          
          if err != nil{
              
              print((err?.localizedDescription)!)
              return
          }
          
          for i in snap!.documents{
              
              let name = i.get("name") as! String
              let age = i.get("age") as! String
              let image = i.get("image") as! String
              
              self.data.append(datatype1(id: UUID().uuidString, name: name, age: age, image: image))
          }
      }
  }
}
Details.swift
//
//  Details.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import SDWebImageSwiftUI

struct Details: View {
     
    let userItem : datatype1
    
    var body: some View {
        GeometryReader{geo in
            //Text(userItem.name)
            VStack {
                Text("Username : \(userItem.name)")
                    .font(.title2)
                  
                AnimatedImage(url: URL(string: userItem.image))
                    .resizable().frame(height: geo.size.height - 100)
                    .padding(.horizontal, 15)
                    .cornerRadius(20)
            }
        }
    }
}
DevSwiftUIApp.swift
//
//  DevSwiftUIApp.swift
//  DevSwiftUI
//
//  Created by Cairocoders
//

import SwiftUI
import Firebase

@main
struct DevSwiftUIApp: App {

    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class AppDelegate: NSObject,UIApplicationDelegate{
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        
        FirebaseApp.configure()
        return true
    }
}

Related Post