Coder Social home page Coder Social logo

alejandro-piguave / tindercloneswiftui Goto Github PK

View Code? Open in Web Editor NEW
74.0 4.0 19.0 41.56 MB

Tinder clone application written using SwiftUI, Firebase, Swift Package Manager and iOS 15 features.

License: MIT License

Swift 100.00%
ios swift chat-application swiftui firebase firebase-auth firebase-firestore firebase-storage dark-theme light-theme

tindercloneswiftui's Introduction

TinderCloneSwiftUI

Tinder clone application written using SwiftUI, Firebase, Swift Package Manager and iOS 15 technologies with an MVVM architectural pattern. The app contains localizations for both English and Spanish languages and support for dark mode. Below a more detailed description of the app features.

Login and Create Profile

Only Google Sign in is allowed. Either of these two actions should be performed:

  • If the user has an account: Click on the "Sign in with Google" button and enter valid credentials. If the login is sucessful and the account exists, the user will be redirected to the home page, otherwise, an error dialog will apear.
  • If the user doesn't has an account: Click on the "Create a new account button" to navigate to the "Create Profile" screen.

In the Create Profile screen the user will be required to complete the following actions:

  • Add at least two profile pictures. These can be obtained through the phone's photo library or the device camera. The necessary permissions are requested accordingly.
  • Provide a user name.
  • Provide a birth date. This will be used to calculate their age.
  • Provide a gender (in order to simplify profile fetching only two options are available).
  • Provide a preference: their own gender, the opposite gender or both.

A bio up to 500 characters is optional. The remaining amount of characters are shown as the user is typing.

Once the information has been filled in and the user clicks on the "Sign Up with Google button", if the user didn't exist before and the creation of the account was successful, the user will be redirected to the home page, otherwise an error dialog will appear.

Home screen

Here the user will be able to browse through profiles and swipe left or right on them in a Tinder-like fashion. Both swipe and button click to perform these actions are supported. If a user likes a user that has liked them before, a match will be created. Once a profile has been liked or disliked it will not be shown again to that user. From here the user can access to:

  • The Edit Profile screen
  • The Messages Screen

Edit Profile screen

In this screen the user can modify the same fields as in the "create profile" screen except for the name and birth date. Their design is almost identical.

Messages screen

Here the user will be able to see his matches and access the corresponding Chat screen to send them messages.

Chat Screen

Here the user will be able to send messages to his matches and they will be updated in real time using Firebase snaphot listeners.

Note: The file "GoogleService-Info.plist" required for the project to work is missing. You will need to connect it to your own Firebase project.

tindercloneswiftui's People

Contributors

alejandro-piguave avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

tindercloneswiftui's Issues

Setting Up

Hi, amazing project. I do not know if you are still online but a little update is needed. There are issues with the packages. Can you take a look that would be increible :D gracias

Please help: Value of type 'Date' has no member 'years'

I am using Xcode 14.1, iOS 16 and recreating your project.

In your file, FirestoreUser.swift, there is an issue with the return of age:

var age: Int{
return Date().years(from: birthDate)
}

I am getting this error :: Value of type 'Date' has no member 'years'

Please advise..
Thank you,

Instructions for project

I am wondering if you can provide step by step instructions for this project or if you followed a tutorial, can you provide the link?
I cannot seem to get this project working right once i get to the setting up profile.

Issues in final update

After add Google plist for Firebase, the following errors are coming up all in one file: EditProfileViewModel.swift:

  1. Invalid redeclaration of 'ProfilePicture' on line 11
  2. 'ProfilePicture' is ambiguous for type lookup in this context on line 22
  3. Type of expression is ambiguous without more context on line 30
  4. 'ProfilePicture' is ambiguous for type lookup in this context on line 40
  5. 'ProfilePicture' is ambiguous for type lookup in this context on line 77
  6. Type of expression is ambiguous without more context on line 79
  7. Command SwiftCompile failed with a nonzero exit code

Please assist

Attached is the code:

//
// EditProfileViewModel.swift
// tinder-clone
//
// Created by Alejandro Piguave on 27/10/22.
//

import Foundation
import UIKit

struct ProfilePicture: Hashable{
let filename: String?
let picture: UIImage
}

class EditProfileViewModel: NSObject, ObservableObject {

private let firestoreRepository: FirestoreRepository = FirestoreRepository.shared
private let storageRepository: StorageRepository = StorageRepository.shared

@Published var userProfile: FirestoreUser? = nil
@Published var userPictures: [ProfilePicture] = []
@Published var isProfileUpdated: Bool = false

@Published private (set) var isLoading: Bool = true
@Published private (set) var error: String = ""

func fetchProfile() {
    self.isLoading = true
    Task{
        do{
            //Fetch profile information
            let user = try await firestoreRepository.getUserProfile()
            DispatchQueue.main.async {
                self.userProfile = user
            }

            //Fetch pictures
            let pictures = try await storageRepository.getPicturesFromUser(fileNames: user.pictures)
            var profilePictures: [ProfilePicture] = []
            for i in user.pictures.indices {
                profilePictures.append(ProfilePicture(filename: user.pictures[i], picture: pictures[i]))
            }

            let finalProfilePictures = profilePictures
            DispatchQueue.main.async {
                self.userPictures = finalProfilePictures
                self.isLoading = false
            }
        }catch{
            publishError(message: error.localizedDescription)
        }
    }
}

//Update only profile fields
func updateProfile(modified profileFields: [String: Any]) {
    self.isLoading = true
    Task{
        do{
            try await firestoreRepository.updateUserProfile(modified: profileFields)
            
            self.isLoading = false
            self.isProfileUpdated = true
        }catch{
            publishError(message: error.localizedDescription)
        }
    }
}

/**
 Updates the profile pictures

 - Parameter oldPictures: Array of the file names of the pictures that are already uploaded, in their respective order.
 - Parameter newPictures: Array of either: the file name of a picture that is already uploaded or a new picture.
 */
func updateProfile(newPictures: [ProfilePicture], modified profileFields: [String: Any]? = nil){
    self.isLoading = true
    Task{
        let oldPictures = userProfile!.pictures
        //Gets the name of the pictures that are not among the new pictures.
        let filesToDelete = oldPictures.filter({ fileName in
            !newPictures.contains(where: { newPicture in
                if let newPictureFilename = newPicture.filename {
                    return fileName == newPictureFilename
                } else {
                    return false
                    
                }
            })
        })
        
        let picturesToUpload: [UIImage] = newPictures.compactMap({ pictureUpload in
            if pictureUpload.filename == nil{
                return pictureUpload.picture
            } else {
                return nil
            }
        })
        
        do{
            async let deletePictures: () = storageRepository.deleteUserPictures(fileNames: filesToDelete)
            async let uploadPictures = storageRepository.uploadUserPictures(picturesToUpload)
            
            let (_, newFileNames): ((), [String]) = try await (deletePictures, uploadPictures)
            
            var updatedFileNames: [String] = []
            var count: Int = 0
            
            newPictures.forEach({
                if let oldFilename = $0.filename {
                    updatedFileNames.append(oldFilename)
                } else {
                    updatedFileNames.append(newFileNames[count])
                    count += 1
                }
            })
            
            //If more values need to be updated then create a copy, otherwise create an empty dictionary
            var allProfileFields: [String: Any] = profileFields ?? [:]
            allProfileFields["pictures"] = updatedFileNames
            
            try await firestoreRepository.updateUserProfile(modified: allProfileFields)
            self.isLoading = false
            self.isProfileUpdated = true
        }catch{
            publishError(message: error.localizedDescription)
        }
    }
}


private func publishError(message: String) {
    DispatchQueue.main.async {
        self.error = message
        self.isLoading = false
    }
}

}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.