Skip to content
/ PADO Public
forked from 4T2F/PADO

PADO - 파도, 내가 꾸미는 친구의 공간

License

Notifications You must be signed in to change notification settings

hamfan524/PADO

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PADO

🪧 목차



📜 프로젝트 소개

앱스쿨 3기 마지막 프로젝트인 "PADO" 는 안티 SNS로써, 친구들이 사용자를 촬영한 사진, 사용자와의 일상을 공유했던 추억 사진을 통해 내 피드를 꾸며주고 소통하는 소셜 미디어 앱 입니다.



🌊 PADO 팀소개

강치우 김명현 최동호 황민채 황성진
사진
한줄 소개 그거 그렇게 하는거 맞아요? 숟가락 청년 무례하긴 순애야 판숙이 건실한 청년
깃허브 Github Github Github Github Github



✨ 앱 필요성

현재의 소셜 미디어 환경에서 나르시시즘과 같은 심리적 특성은 거짓 정보의 신뢰와 공유에 영향을 미칠 수 있습니다.

[1] 소셜 미디어 사용자들은 종종 정보 과부하, 사생활 침해, 사이버불링 등으로 인해 감정적 소진과 소셜 미디어 피로감(Social Media Fatigue)을 경험합니다.

[2] 이러한 문제들은 건강하지 못한 소셜 미디어 사용을 조장하고, 사용자들의 심리적 건강에 부정적인 영향을 미칠 수 있습니다.

"PADO" 는 이러한 문제를 해결하고자, 사용자들이 소셜 미디어를 보다 진정성 있고 건강하게 사용할 수 있도록 돕습니다.

이 앱은 사용자들이 자신의 모습을 보다 자연스럽게 표현하고 친구들과의 유대를 강화할 수 있는 새로운 방식의 소셜 미디어 경험을 제공합니다.

이를 통해 사용자들은 소셜 미디어의 긍정적인 측면을 더욱 부각시키고, 피로감을 줄일 수 있습니다.



🚩 개발목표

image



💾 개발도구 및 사용기술

개발도구

image

사용기술

image

image

image



🌴 아키텍쳐 및 파이어베이스 구조

프로젝트 아키텍쳐

image

파이어베이스 구조

image



💡 핵심경험

  • Firestorage 활용한 이미지 업데이트, 불러오기
  • FireStore를 이용한 데이터 읽기, 저장, 삭제 로직 구현
  • Firebase Auth를 이용한 로그인, 로그아웃, 회원가입, 회원탈퇴 구현
  • MVVM 패턴에 대한 이해와 ViewModel의 분리 중요성
  • View 를 만들때 다양한 기기에서 사용려면 고려해야 하는 요소
  • 사용자 친화적인 UI/UX 구현 (적절한 입력 컴포넌트 사용, 알맞은 키보드 타입 지정)
  • HIG를 이용한 디자인 구성
  • CoreGraphics의 이해
  • PencileKit의 이해
  • PhotosUI의 활용
  • Lottie의 사용
  • 앱 배포경험 및 출시 후 피드백 반영의 중요성
  • Geometryreader의 활용
  • 뷰의 생명주기
  • FCM을 통한 알람 방송 및 뷰 이동



🕰 타임라인

2024년 1월 15일 ~ 2월 28일 예정

총 45일 소요 예정

첫째 주

첫째 주

날짜 작업 내용
24.01.15 UX 전략 회의 및 노션 정리
24.01.16 Figma WireFrame 작업
24.01.17 UI 작업
24.01.18 UI 작업, 로그인 회원가입 기능 구현
24.01.19 UI, 애니메이션 작업, 로그인 회원가입 기능 구현
24.01.20 UI, 애니메이션 작업, 로그인 회원가입 기능 구현, FireStorage 프로필 이미지 기능 구현
24.01.21 UI, 애니메이션 작업, FireStorage 프로필 이미지 기능 구현
둘째 주

둘째 주

날짜 작업 내용
24.01.22 노션 정리, 요구사항 명세서 작성
24.01.23 UI작업, 앱스쿨 발표준비,SufferView 카메라, 앨범 작업, Splash View 작업
24.01.24 SettingView UI 작업, 로그아웃 오류 수정, ReadMe.md 1차 작업, 컴포넌트 정리
24.01.25 UI Gradient 작업, 오늘 파도 스크롤링 추가, Splash View 오류 수정, SurffingView 파일 구조 변경, SurffingViewModel 리팩토링
24.01.26 SettingView 정보 변경 기능, TodayView 오류 수정, Profile 변경 로직 수정, 로그인 로직 오류 수정, MainView 모델링 및 로직 수정, AuthViewModel 리팩토링
24.01.27 파이어베이스에서 사진 불로오는 기능 구현
24.01.28 KingFisher 적용, FCM 뱃지 구현, MainView 디자인 변경, Lottie 적용, 게시굴 올리는 함수 구현
셋째 주

셋째 주

날짜 작업 내용
24.01.29 게시하기 기능 구현, 스토리 셀 로직 구현, 캐시지우기 구현, 회원탈퇴 로직 수정, 파이어베이스 문서 이름 규칙 수정, 로그인 오류 수정, 로그아웃 모달 적용, 메인 피드에서 시간, 제목, 하트수 서버에서 SnapShot으로 받아오게 구현
24.01.30 문의하기 사진 첨부 기능 구현, 팔로워 팔로잉 기능 구현, 댓글 입력창 디자인 수정, 포스팅 관련 스트리지 데이터 구조 변경, 댓글 기능 구현, ProfileView 디자인 변경
24.01.31 메인피드 사진 사이즈 수정, 팔로잉 한 사람의 피드만 가져오게 변경, 포토모지 카메라 기능 구현, 프로필에서 SNS연동 기능 구현, 팔로워/팔로잉 뷰 디자인 수정
24.02.01 댓글에서 프로필 이미지 로드기능 구현, 이미지 자르기 구현, 프로필 없을시 기본프로필 적용, 이미지 화절 저하 문제 해결, 검색기능 구현, 좋아요 눌린 피드 하이라이트 적용
24.02.02 피드 데이터 로직 수정, 페이스모지 기능 구현, 다른사람 프로필 뷰 구현, 검색을 통한 유저 프로필 이동기능 구현, 앱 아이콘 변경, 다른사람 프로필에서 팔로워/팔로잉 수 보이게 구현, 댓글에서 프로필 이동 구현, 검색기록 구현, 댓글 없을 때 뷰 반영, 키보트 탭하여 내리기 구현, 대,소문자 구분없이 검색가능하게 변경, 검색 로직 일부 수정
24.02.03 포스팅 시 서퍼지정 뷰/로직연결, Comment 서버 구조 변경, 하트 로직 수정, 게시물 중복으로 불러오는 오류 수정, 새로고침 오류 수정, 서퍼로 게시글 등록시 포스팅 올라가게 구현, Z스택 사용 최소화 리팩토링, 프로필에서 게시글들 최신순으로 불러오게 구현, 텍스트필드 자동으로 키보드 올라가게 구현, 팔로우 FCM기능 구현, 메인 뷰 햅틱 피드백 추가
24.02.04 댓글 카운트 반영 안되던 오류 수정, 하트, 서퍼지정, 게시올리기 FCM 로직 추가, 그라데이션 수정, 팔로잉 관련 로직 수정, 현재 보고있는 스토리 셀 표시되게 구현, 포토모지 삭제기능 구현, 하트 로티 적용, 신고 메일 발송기능 구현, 알림설정 기능 구현, 포토모지 이모지 선택기능 구현
넷째 주

넷째 주

날짜 작업 내용
24.02.05 이모지 선택 로직 리팩토링, 프로필 저장 로직 수정, 배경화면 선택기능 추가, 문의하기 기능 구현, 프로필에서 게시글 선택하면 열리게 수정, 배경화면 없는 사람 프로필 안나오는 오류 수정
24.02.06 메인뷰 디자인 변경, 2일 이내 게시글 받아오게 구현, 이용약관, 개인정보 처리방침 작성 및 연결, 변경된 메인뷰 댓글 하트 데이터 연결, 오늘 파도 가져오는 함수 구현, 사용하지 않은 코드 삭제
24.02.07 유저값 재설정 함수 구현, 알림 기능 수정, 데이터 받아오는 로직 수정(스크롤 아래로 내리면 데이터를 추가로 받아오게 구현), 그리드 뷰 연동, 파도타기 기초 UI 작업
24.02.08 파도타기 기능 구현, 알림 로직 수정, 프로필, 팔로워, 세팅 디자인 변경, 인기 게시글 받아오기, 새로고침 로직 수정, 다른 사람 피드에서 게시글 선택하면 열리게 구현
24.02.09 회원가입, 로그아웃 오류 수정, 포스트 스냅샷 로직 수정, 그리드 관련 오류 수정, 방명록 기능 구현
24.02.10 방명록 관련 오류, 디자인 수정, FCM 방명록 추가, 파도타기 메인뷰 연결, 모달뷰 수정, 데이터 포맷 변경 및 검색 뷰 크기 통일화, 차단 뷰 구현, 폰트 및 크기 통일화
24.02.11 오늘파도 관련 오류 수정, 파도타기 디테일 수정, 댓글 관련 로직 수정, 댓글 삭제 인덱스 연결, 피드, 방명록에서 프로필 연결, 회원가입 관련 오류 수정
다섯째 주

다섯째 주

날짜 작업 내용
24.02.12 프로필 관련 오류 수정, 팔로우, 서퍼지정 네비게이션 링크 연결
24.02.13 오늘파도 랭킹 구현, 로그인 없이 둘러보기 기능 구현, 팔로우한 사람없을때 보여줄 뷰 구현, 댓글, 다른유저 프로필 신고하기 연결
24.02.14 로그인 회원가입 관련 오류 수정, 포토피커 로직 수정, 파도타기 디테일 작업, 인기 팔로워 구현, 프로필 관련 오류 수정
24.02.15 이미지 관련 디테일 작업, 서핑뷰 관련 오류, UI 수정, FCM관련 화면 전환기능 구현, 로직 수정
24.02.16 파도타기 UI 수정, FCM 추가, 유저 차단 기능 구현
24.02.17 포스팅 관련 디테일 작업, 파도타기 삭제기능 구현, 메인뷰 디자인, 로직 수정, 알림센터 내 뷰 이동 구현, FCM 관련 로직 수정, 인기-팔로잉 변환시 스크롤 맨위로 올라가게 구현, 서핑뷰, 오늘파도 프로그래스 뷰 구현, 차단 기능 디테일 작업, 앱내 어투, 폰트 수정
24.02.18 설정-차단목록 작업, 차단 기능 디테일 작업, 전체적인 모달 수정, 가입할 때 이용약관 동의 추가, 알림뷰 오류 수정, 문자 인증 안오던 오류 수정
여섯째 주

여섯째 주

날짜 작업 내용
24.02.19 프로필, 배경사진 터치 이벤트 추가, 불필요 파일 삭제, 각종 오류 수정, 게시글 삭제시 새로고침 구현
24.02.20 앱 출시 및 각종 오류 수정
24.02.21 유저 피드백에 의한 앱 수정 / 온보딩 뷰 추가, 유저 차단시 새로고침 로직 구현, 메인뷰 디자인 수정, 하이라이트 공개 여부 설정기능 구현, FCM 관련 뷰 이동 로직 수정
24.02.22 유저 피드백에 의한 앱 수정 / 파도 보내기 기능 추가, 커스텁 탭바 구현, 각종 오류 수정, 일부 디자인 변경
24.02.23 유저 피드백에 의한 앱 수정 / FCM 관련 로직 수정, 각종 오류 수정, 게시글 삭제시 시트 내려가게 구현
24.02.24 유저 피드백에 의한 앱 수정 / 모달관련 로직 수정, 프로필 뷰 새로고침 기능 구현, 각종 오류 수정, 커스텀 탭바 관련 디테일 작업
24.02.25 유저 피드백에 의한 앱 수정 / 댓글 좋아요 추가 구현, 발표자로 준비, README 작성
일곱번째 주

일곱번째 주

날짜 작업 내용
24.02.26 유저 피드백에 의한 앱 수정 / 발표자로 준비, README 작성
24.02.27 유저 피드백에 의한 앱 수정 / 답글 기능 구현, 발표자로 준비, README 작성
24.02.28 프로젝트 종료
24.02.29 ~ 유지보수, 코드 리팩토링 실시 예정



📱 구현 화면

서버

image

앱 설명

image

image

image

image

image



✅ 구현 List

Pages

  • Splash
  • Start
  • Login
  • Search
  • Surfing
  • Today
  • Profile
  • Setting
  • Notification
  • PadoRide
  • Onboarding
  • ImageCrop

Function

  • 둘러보기 시 제한된 기능으로 오늘의 파도 만들기
  • Firebase Auth 를 통한 로그인, 로그아웃, 회원가입 기능
  • Firebase Auth 에서 이미 가입된 회원의 정보는 데이터 받아오기
  • FireStore 를 통해 유저 정보 저장
  • FireStore 를 통해 메인 게시물 불러오기
  • FireStore 를 통해 댓글, 좋아요, 포토모지 저장, 불러오기
  • FCM을 통한 조건에 따른 알림 발송
  • FCM을 통한 조건에 따른 뷰 이동
  • 게시물 신고, 문의하기 메일 발송
  • 제스터를 통한 메인 피드 인터렉션
  • 유저 정보 검색 기능
  • 사용자의 카메라, 앨범에 접근해 게시물, 포토모지 작성
  • 오늘 파도 게시물 불러오기, 정렬 기능
  • 오늘 파도 애니메이션
  • 내 프로필 정보 표시, 저장
  • 서퍼 지정, 해제, 알림
  • 팔로잉, 팔로워 수 불러오기
  • 캐시 지우기 기능
  • 회원 탈퇴 기능
  • FCM 알림 받기 여부 설정
  • 메일을 통한 문의 기능
  • APNs FireStore에 등록
  • 개시물 댓글, 하트, 팔로우 팔로잉 알림
  • 서퍼가 내 게시물 작성시 알림
  • 파도타기 기능, 알림 구현
  • 방명록 기능, 알림 구현



🧑‍🤝‍🧑 유저 피드백

image

image

image



⚠️ 트러블 슈팅 - Step1

Step1

TCA와 MVVM 아키텍쳐 관련 고민

우리 팀은 아이키텍처에 대한 선택의 고민이 가장 컸어요.

대중적이고 검증된 MVVM과 최근 시장에서 주목받고 있는 TCA 사이에서 말이죠. 이는 단순한 기술적 선택이 아니라, 우리의 성장 방향과 프로젝트의 목표 사이에서의 균형을 찾는 과정이었습니다.

TCA를 배우고 싶은 열망이 있었지만, 우리는 먼저 팀원들과 함께 깊이 있는 학습과 논의의 시간을 가졌어요. 이 과정에서 우리는 서로의 의견을 나누고, 각자의 관점을 이해하는 중요한 경험을 했습니다.

멘토의 조언에 따르면 우리가 프로젝트의 완성도를 우선시한다면 MVVM을, 배움을 추구한다면 TCA를 선택해야 한다는 결론에 도달했죠.

특히, TCA를 적용할 때 우리 앞에 놓인 가장 큰 도전은 애니메이션 구현이었습니다. SNS 앱의 특성상 다양하고 매력적인 애니메이션은 필수적인 요소였지만, TCA 아키텍처 하에서 이를 구현하는 것은 시간적인 제약으로 인해 어려움이 있었어요.

결국, 우리는 팀의 의견을 모아 MVVM을 선택했습니다. 이 결정은 단지 기술적인 선택을 넘어서, 우리 팀이 어떻게 함께 성장하고, 어떻게 프로젝트를 성공적으로 이끌어갈 것인지에 대한 근본적인 질문에 답하는 과정이었어요.

MVVM을 통해, 우리는 안정적이면서도 유연한 애니메이션 구현이 가능해졌고, 팀원 간의 협력과 의사소통을 강화하는 계기가 되었습니다.

이 경험은 우리에게 단순한 기술 선택 이상의 것을 가르쳐주었어요.

서로 다른 의견을 조율하고, 각자의 성장과 팀의 목표를 조화롭게 이끌어가는 법을 말이이에요.

이 경험은 우리가 앞으로 나아갈 길에 있어서 소중한 경험이 될 것입니다.



⚠️ 트러블 슈팅 - Step2

Step2

이미지 저장시 생기는 흰색 배경화면

앱에서 이미지를 다루면서 특히 파도타기 기능을 구현하는 과정에서, 이미지 하단에 원치 않는 흰색 배경이 추가되는 문제에 직면했어요. 이런 문제는 사용자 경험을 저해하고, 앱의 전체적인 외관을 떨어뜨릴 수 있죠. 이를 해결하기 위해 여러 시도 끝에, 이미지를 저장하기 전에 흰색 배경을 제거하는 방법을 채택했습니다.

 let imageView = UIImageView(image: padorideVM.selectedUIImage)
        imageView.frame = CGRect(x: 0, y: 0, width: rect.width, height: rect.height - 50)
        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true

이미지의 위치를 -50 끌어 올리면서 이미지의 밑에 부분에는 흰색 배경이 들어가게 되었습니다.

CropWhiteBackground 클래스를 만들어서 이미지 처리를 담당하는 processImage 함수를 구현했어요. 이 함수는 입력된 이미지에서 흰색 배경을 제거해줍니다. 이미지의 크기와 배율을 고려하여, 실제로 사용자가 보게 될 이미지 부분만 남기고, 나머지는 잘라냅니다. 이 과정에서 CGImage의 cropping 메소드를 활용하여, 이미지의 특정 부분을 정확하게 크롭합니다. 이로써, 이미지의 중요한 부분만을 강조하고, 불필요한 배경은 제거할 수 있게 되었습니다.

class CropWhiteBackground {
    func processImage(inputImage: UIImage) async throws -> UIImage {
        
        enum CroppingError: Error {
            case imageNotFound, failedToCrop
        }
        
        let croppingFrame: CGRect
        let scaleFactor: CGFloat
        let processedImageWidth: CGFloat
        let processedImageHeight: CGFloat
        let croppedImage: UIImage
        guard let cgImage: CGImage = inputImage.cgImage else {
            print("image not found")
            throw CroppingError.imageNotFound
        }
        
        // Declaration of cropping frame size
        scaleFactor = inputImage.scale
        processedImageWidth = (inputImage.size.width * scaleFactor)
        processedImageHeight = (inputImage.size.height * scaleFactor) - (36 * scaleFactor)
        
        // Declaration of frame for cropping
        croppingFrame = CGRect(x: 0, y: 0, width: processedImageWidth, height: processedImageHeight)
        
        // Cropping CGImage
        guard let processedCGImage: CGImage = cgImage.cropping(to: croppingFrame) else {
            print("image not found")
            throw CroppingError.failedToCrop
        }
        
        // Convert CGImage to UIImage
        croppedImage = UIImage(cgImage: processedCGImage, scale: scaleFactor, orientation: inputImage.imageOrientation)
        
        return croppedImage
    }
}

이런 방식으로 문제를 해결하니 사용자들이 이미지를 보았을 때, 더 이상 하단의 흰색 배경에 신경 쓰지 않아도 되고, 우리가 전달하고자 하는 주요 내용에 더 집중할 수 있게 되었어요.

이 경험을 통해, 앱 개발 과정에서 마주칠 수 있는 다양한 문제들을 해결하기 위해 창의적인 해결책을 모색하는 것의 중요성을 다시 한번 깨닫게 되었습니다. 코드 한 줄 한 줄이 사용자 경험에 얼마나 큰 영향을 미칠 수 있는지를 실감하였습니다.



⚠️ 트러블 슈팅 - Step3

Step3

이미지 원본비율을 유지하기

사용자들로 부터 받은 피드백으로 이미지가 원본 비율을 유지하면서도 화면에 잘 맞게 조정되는 것이었어요.

팀에서도 해당 문제에 대해 동의 하고 있었습니다.

이 문제를 인지한 후, 우리 팀은 이미지 처리를 위한 해결하기 위해 ImageRatioResize라는 싱글톤 클래스를 만들기를 사용했습니다.

ImageRatioResize 클래스는 두 가지 함수로 구성되어있어요. 첫 번째 함수인 resizedImageRect는 이미지의 비율을 유지하면서 원하는 사이즈로 조정해주는 것입니다. 이는 이미지가 화면에 꽉 차게 표시되길 원하지만, 그 과정에서 이미지가 원본의 비율이 깨지는 것을 원하지 않는 사용자들의 피드백에 의해 만들어 졌어요

두 번째 함수인 resizeImage 이미지를 원하는 픽셀의 크기로 정확하게 조절해주는 것입니다. 이는 특히 이미지의 세부 사항이 중요한 경우에 유용하며, 사용자가 더 선명한 이미지를 경험할 수 있도록 합니다.

class ImageRatioResize {
    
    static let shared = ImageRatioResize()
    
    private init() { }
        
    // 이미지 비율을 반영해서 원하는 사이즈로 설정해주는 함수
    func resizedImageRect(for originalImage: UIImage, targetSize: CGSize) -> CGRect {
        let widthRatio = targetSize.width / originalImage.size.width
        let heightRatio = targetSize.height / originalImage.size.height
        let ratio = min(widthRatio, heightRatio)
        
        let newSize = CGSize(width: originalImage.size.width * ratio, height: originalImage.size.height * ratio)
        let rect = CGRect(x: (targetSize.width - newSize.width) / 2.0,
                          y: (targetSize.height - newSize.height) / 2.0,
                          width: newSize.width,
                          height: newSize.height)
        return rect
    }
    
    // 이미지를 원하는 크기로 변경해주는 함수
    func resizeImage(_ originalImage: UIImage, toSize newSize: CGSize) async -> UIImage {
        let format = UIGraphicsImageRendererFormat()
        format.scale = 1 // 픽셀 기반 크기 조정을 위해 scale을 1로 설정합니다.
        let renderer = UIGraphicsImageRenderer(size: newSize, format: format)
        
        let resizedImage = renderer.image { context in
            originalImage.draw(in: CGRect(origin: .zero, size: newSize))
        }
        
        return resizedImage
    }
}

두가지 함수를 통해 우리는 사용자들로부터 받은 피드백을 해결할 수 있었습니다. 
사용자들이 우리 앱에 보내는 이미지가 얼마나 중요한지 이해하고 피드백을 최대한 반영하고자 노력했어요. 
이 과정을 통해 사용자 경험을 개선하는 것이 가장 큰 목표였어요.

결론적으로 해당 함수들을 통해 원본 이미지가 비율을 유지한 상태로 활용할 수 있게 되었어요.



⚠️ 트러블 슈팅 - Step4

Step4

이미지를 자르고 데이터가 줄어드는 현상

이번 문제는 앱에서 사용자가 이미지를 원하는 크기로 자를 때 발생한 문제로 이미지를 사용자가 원하는 크기로 자르는 뷰를 별도로 만들어서 사용하고 있습는데 여기서 발생했어요.

이미지를 자른 후에 이미지의 품질이 떨어지는 현상을 찾았어요. 문제의 원인을 찾기위해 이미지를 자르기 전에 파이어베이스 서버에 올리면 이미지 크기가 정상적으로 들어것을 확인했고, 이미지를 자르면 원본 크기를 유지하지 못하고 이미지 크기가 크게 저하되는 문제가 생긴다는 것을 알게되었어요.

기본적으로 ImageRenderer의 scale은 이미지를 렌더링할 때 해상도를 결정하는 중요한 요소라는 것을 알게 되었고. renderer.scale = 3 을 설정함으로써 이미지가 자동으로 작아지는 것을 방지하고, 원본에 가까운 품질을 유지할 수 있게 되었습니다. 이 작은 변경으로 사용자가 이미지를 자른 후에도 이미지의 품질이 크게 개선되었고, 원하는 크기로 조정해도 이미지가 선명함을 유지할 수 있게 되었죠.

Button {
    let renderer = ImageRenderer(content: imageView(true))
    renderer.scale = 3
    renderer.proposedSize = .init(crop.size())
    if let image = renderer.uiImage {
        onCrop(image, true)
        surfingVM.postingUIImage = image
        if let uiImage = surfingVM.postingUIImage {
                surfingVM.postingImage = Image(uiImage: uiImage)
            }
            surfingVM.showPostView.toggle()
        } else {
            onCrop(nil, false)
    }
}

ImageRenderer의 scale 속성을 조정하는 간단한 해결책을 통해, 우리는 사용자가 이미지를 자르고도 높은 품질의 이미지를 유지할 수 있도록 도왔습니다.



⚠️ 트러블 슈팅 - Step5

Step5

특정 이미지가 안올라가는 오류

다음으로 발생한 문제는 사진 중 안올라가는 사진이 있었습니다.

근데 이 이미지가 주로 png 타입일 경우가 많았고, 이상하게도 모든 png가 다 안올라가는 게 아니였고, 규칙을 찾기가 힘들었습니다.

그래서 파이어베이스에 올릴때 do catch 문으로 오류에 대해 파악하고자 했어요.

그렇게 찍힌 오류는

writeImageAtIndex:906: *** CMPhotoCompressionSessionAddImage: err = kCMPhotoError_UnsupportedPixelFormat [-16995] (codec: 'jpeg')

라는 오류 문구를 확인했습니다.

이것에 대해 찾아보니 UIImage가 사용하는 픽셀 포맷이나 색상 공간이 JPEG 인코딩과 호환되지 않을 수 있다는 것을 알게 되었습니다.

이에 대한 해결방법으로는 UIImage 를 CIImage 타입으로 바꿔주고 다시 UIImage로 바꿔주면 해결가능하다는 글을 찾게 되었습니다.

if let ciImage = CIImage(image: image) {
    let context = CIContext(options: nil)
    let colorSpace = CGColorSpaceCreateDeviceRGB()
    // CIImage를 CGImage로 변환하면서 색상 공간 지정
    if let newCGImage = context.createCGImage(ciImage, from: ciImage.extent, format: .RGBA8, colorSpace: colorSpace) {
        let normalizedImage = UIImage(cgImage: newCGImage)
        guard let normalizedImageData = normalizedImage.jpegData(compressionQuality: imageQuality.rawValue) else { return nil }
        // normalizedImageData를 사용하여 업로드 로직을 계속 진행
    }
}

그래서 파이어베이스에 업로드 하기전 다음과 같이 이미지 포맷 변환 로직 추가 해주면서 문제를 해결할 수 있었습니다.



😆 프로젝트 회고

강치우

이상한 주제를 선택해서 하루 12시간이상 작업, 2달 안되는 기간동안 커밋 1000개, PR 약 200개를 넘겨버렸네요.. 우리가 계획했던 로직들이 다 완성되서 너무 좋았고 배포, 유지보수까지 경험해봐서 너무 뜻깊은 시간이였어요. 누가 뭐라해도 우리팀이 제일 수고 많았어요. 다들 고생했어요


김명현

난생 처음 해보는 프로젝트에서 A-Z 경험을 너무 좋은 조원들과 함께해서 더 의미가 깊었습니다. 프로젝트 동안 개인역량이 부족해 조원들에게 많이 미안하고 고마웠습니다. 이번 프로젝트를 하면서 배워야할게 아직 많구나 느끼는 좋은 동기부여가 되었습니다.앱스쿨 수강생분들, 강사님 보조강사님, 운영진분들 다들 고생 너무 많으셨습니다!!


최동호

처음 목표로 잡았던 기능들을 완성하고 배포 이후 유지보수까지 할 수 있었다는게 너무 행복합니다. PADO 화면에 로그인부터 끝까지 제가 작업한 로직들이 적용되어있다는게 너무 뿌듯해요. 그런데 기능 구현에 너무 집중하다보니 코드가 살짝 깔끔하지 못했다는점이 아쉽지만 이후에 유지보수하며 리팩토링하고 정리하며 더 배우겠습니다 :)


황민채

팀플을 이렇게 재밌게 한 경험은 처음이었던 것 같아요. 프로젝트 기간동안 거의 매일 밤을 새면서도 팀원들과 함께해서 전혀 힘들지 않았습니다. 알림 부분을가장 메인으로 맡아서 구현하게 됐는데 감도 안 잡혔던 부분들이 점점 풀려가는 걸 보며 희열을 느끼기도 했습니다. 우리 팀, 파도 너무 소중하고 감사해요! :)


황성진

처음으로 시작하는 제대로된 프로젝트였어요. 협업 단계에서 문제도 많았고 배워가는 부분도 많았고, 내가 맡은 부분을 어떻게든 해결하고자 노력하면서 성장하는 기분이였어요. 이미지파트를 주로 맡으면서 와 이렇게까지 해야지 이미지 처리가 된다고? 하는 부분도 있었지만, 나 스스로 성장할 수 있는 기회가 되었습니다. 누가 뭐래도 우리 파도팀이 짱이야! 그리고 이미지.. 다시는 만나지 말자..


📎 커밋 규칙

타입 리스트 설명
🐞 Fix 올바르지 않은 동작(버그)을 고친 경우
🌊 Feat 새로운 기능을 추가한 경우
✨ Add feat 이외의 부수적인 코드, 라이브러리 등을 추가한 경우, 새로운 파일(Component나 Activity 등)을 생성한 경우도 포함
🩹 Refactor 내부 로직은 변경하지 않고 기존의 코드를 개선한 경우, 클래스명 수정&가독성을 위해 변수명을 변경한 경우도 포함
🗑️ Remove 코드, 파일을 삭제한 경우, 필요 없는 주석 삭제도 포함
🚚 Move fix, refactor 등과 관계 없이 코드, 파일 등의 위치를 이동하는 작업만 수행한 경우
🎨 Style 내부 로직은 변경하지 않고 코드 스타일, 포맷 등을 수정한 경우, 줄 바꿈, 누락된 세미콜론 추가 등의 작업도 포함
💄 Design CSS 등 사용자 UI 디자인을 추가, 수정한 경우
📝 Comment 필요한 주석을 추가, 수정한 경우(❗ 필요 없는 주석을 삭제한 경우는 remove)
📚 Docs 문서를 추가, 수정한 경우
🔧 Test 테스트 코드를 추가, 수정, 삭제한 경우
🎸 Chore 위 경우에 포함되지 않는 기타 변경 사항
🙈 gitignore ignore파일 추가 및 수정



About

PADO - 파도, 내가 꾸미는 친구의 공간

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Swift 99.8%
  • Ruby 0.2%