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 } }