게시글을 올리고 댓글을 통해 서로 소통할 수 있는 앱입니다. 팔로우/팔로잉, 게시글 좋아요/댓글 기능과 알림, 프로필 설정 등의 기능을 지원합니다.
- UIKit
- MVC Pattern
- Combine
- Firebase (Authentication, Database) / Supabase(프로필 이미지 저장용)
+) '이메일 인증 메일 보내기', '비밀번호 재설정 메일 보내기' 는 이미 제공되어있는 Firebase의 메서드를 사용하였습니다. +) 테스트 계정: asd@naver.com / tkdtn5584@
- 아이디와 비밀번호를 입력하여 로그인합니다.
- 이메일 입력을 완료하면, 일정 시간 후에 해당 이메일의 유효성을 평가합니다. (중복 여부, 형식 등)
- 이메일이 유효하다면, '확인'버튼을 눌러 이메일을 확정합니다.
- 이메일이 확정되면 비밀번호 필드가 활성화됩니다.
- 마찬가지로, 비밀번호가 유효하다면 '가입' 버튼이 활성화됩니다.
- '가입' 버튼을 누르면, 이메일 인증 메시지가 전송됩니다. 확인 버튼을 눌러 메인 화면으로 이동할 수 있으며, 해당 이메일에서 인증하면 로그인이 가능합니다.
- 이메일 인증을 하지 않은 채로 로그인하면, 다음과 같은 메시지가 출력됩니다.
- 편의를 위해, 이메일을 인증하지 않아도 로그인할 수 있도록 해당 기능을 주석처리한 상태입니다.
// 해당 부분은 주석 처리된 상태입니다.
if !result.user.isEmailVerified {
try Auth.auth().signOut()
showEmailVerificationRequiredAlert()
return
}- 이메일을 입력하여 비밀번호 재설정 메일을 보냅니다.
- 자신이 '팔로잉'하는 유저의 게시글들을 시간 순으로 보여줍니다.
- 프로필 사진, 닉네임, 게시 날짜와 게시 내용이 포함됩니다.
- 해당 게시글에 좋아요를 누르고, 댓글을 달 수 있습니다.
- Comment 버튼을 누르면, 댓글 시트가 열립니다.
- 댓글에 답글을 달 수 있고, 누구에게 답글을 다는지 표시됩니다.
- 하단의 텍스트 필드를 통해 댓글/답글을 달 수 있습니다.
- 답글을 달 때는 플레이스홀더가 '@(닉네임) 님에게 회신' 같은 형식으로 바뀝니다.
- 자신이 단 댓글/답글이라면, 삭제와 수정이 가능합니다.
- 최상위 댓글을 삭제하면, 연결된 답글까지 모두 삭제됩니다.
483961379-446317a9-5930-48bf-99dc-ffa2bc851f99.online-video-cutter.com.mp4
- 나를 팔로우하는 사람들을 보여줍니다. 닉네임과 자기 소개, 프로필 사진이 표시됩니다.
- 셀을 클릭하면, 그 유저가 작성한 글들을 보여줍니다.
483961383-2565ab92-a795-4fb1-8071-ab9a8935343f.online-video-cutter.com.mp4
- 내가 팔로우하는 사람들을 보여줍니다.
- 셀을 클릭하면, 그 유저가 작성한 글들을 보여줍니다.
- '해제'버튼을 눌러 팔로잉을 해제할 수 있습니다.
- 해당 유저의 글이 홈 화면에서 더 이상 보이지 않습니다.
483959998-603ccc03-63a1-4adb-bb02-afcbe9fdad5f.online-video-cutter.com.mp4
-
돋보기 버튼을 눌러 검색 모드로 진입합니다.
-
검색어를 포함하는 닉네임을 가진 유저들을 보여줍니다.
-
셀을 클릭하면, 그 유저가 작성한 글들을 보여줍니다.
-
'추가' 버튼을 클릭하여 해당 유저에게 팔로우를 요청합니다.
-
나, 이미 팔로잉하는 친구에게는 버튼이 보이지 않습니다.
-
이미 팔로우 요청을 보낸 유저에게 다시 팔로우 요청을 보내면, 토스트 메시지가 표시됩니다.
- 게시 탭을 누르면, 게시 시트가 활성화됩니다.
- 제목과 내용을 작성하고 '게시'버튼을 눌러 게시합니다.
- 제목과 내용이 모두 있어야 글을 게시할 수 있습니다.
- 자신에게 팔로우를 요청한 유저들의 목록을 가져옵니다.
- '수락'버튼을 눌러 수락합니다.
- 자신의 게시글에 좋아요/ 댓글이 추가될 때마다 알림이 추가됩니다.
- 해당 알림 셀을 누르면, 그 게시글로 이동합니다.
483960080-22bda060-69f5-44fc-8707-7835aa782a87.online-video-cutter.com.mp4
- 이미 삭제된 게시글로는 이동할 수 없습니다.
483960056-ba8ae7d8-5a59-45db-8c24-9f6156a536c5.online-video-cutter.com.mp4
- 왼쪽으로 드래그하여 해당 셀을 제거합니다.
Adobe.Express.-.483960139-5ba352cf-f506-47e1-9db0-579972fece14.mp4
- 내 게시글을 볼 수 있습니다.
- 셀을 꾹 누르면, 게시글을 수정하거나 삭제할 수 있습니다.
483961376-949c5c76-466a-4350-a49f-929a28f36eff.mov
- 자신의 프로필 사진과 닉네임, 자기소개를 수정할 수 있습니다.
- 카메라 버튼을 눌러 사진을 가져옵니다.
483960231-de5023da-7c3c-4966-a7ab-8eb02dffdaee.mov
- 닉네임 수정시, 현재 필드에 입력한 글자 수가 표시됩니다.
- 최대 글자수를 넘어가면, 숫자 라벨이 빨간 색으로 변하며 닉네임을 저장할 수 없습니다.
- 자기소개 수정시, 현재 필드에 입력한 글자 수가 표시됩니다.
- 2줄 이내로 작성할 수 있습니다.
- 로그아웃 버튼을 눌러 로그아웃합니다.
483961374-434c3e6b-8fef-496a-8f70-071ed8240704.mov
private func observeEmailField() {
let publisher = NotificationCenter.default.publisher(for: UITextField.textDidChangeNotification, object: signUpView.emailField)
publisher
.compactMap { ($0.object as? UITextField)?.text }
.debounce(for: .seconds(1.1), scheduler: RunLoop.main)
.removeDuplicates()
.sink { [weak self] email in
self?.handleEmailInputChange(email: email)
}
.store(in: &cancellables)
}debounce 적용 전에는, 사용자가 이메일 필드에 텍스트를 한 글자 한 글자 입력할 때마다 handleEmailInputChange()가 호출되어, 과도한 형식 오류 메시지가 발생했습니다. debounce(약 1초) 적용으로, 불필요한 이메일 검증 API 호출을 줄이고 입력 도중 과도한 형식 오류 메시지가 뜨지 않도록 UX를 개선했습니다.
enum ImageLoader {
private static var cache = NSCache<NSString, UIImage>()
static func loadImage(from urlString: String?) async -> UIImage? {
if let cached = cache.object(forKey: urlString as NSString) {
return cached
}
do {
let (data, _) = try await URLSession.shared.data(from: url)
/* ... */
cache.setObject(image, forKey: urlString as NSString)
return image
} catch {
/* ... */
}
}
}비동기 이미지 로딩 시 NSCache 기반 캐싱을 적용하여, 같은 URL의 이미지(동일한 사람의 프로필)를 여러 번 요청하는 상황에서 불필요한 네트워크 요청을 줄였습니다.



