Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

468 Commits

Repository files navigation

BeMeiOS

📌 프로젝트 소개

  • SOPT 27th 장기 해커톤 APPJAM
  • 기간: 2020.12.26 ~ 2021.1.16

매일 질문에 답을 하며 나를 알아가는 질문다이어리 BeMe 입니다.

24시간마다 새로운 질문 제공, 새로운 질문 받기를 통해 질문에 답을 할 수 있습니다. 자신의 글을 전체 공개하여 사람들과 소통할 수 있습니다. 마지막으로 마이페이지에서 내가 지금까지 답한 질문을 쉽게 볼 수 있으며, 내 생각이 어떻게 변했는지 확인할 수 있습니다.

📌 개발 환경 및 라이브러리

개발 환경

Swift 4XcodeswiftiOSCOCOAPODS

라이브러리

라이브러리(Library)목적(Purpose)버전(VersionA
Alamofire서버 통신Alamofire
Kingfisher이미지 처리Kingfisher
SnapKit오토레이아웃Kingfisher
Then짧은 코드 처리Kingfisher
lottie-ios로티 애니메이션 처리lottie-ios
Firebase/MessagingFirebase Cloud MessagingKingfisher
SwiftLint깔끔한 코딩 컨벤션Kingfisher

AutoLayout 적용 여부

1. iPhone 12 Pro 적용

2. iPhone 12 mini 적용

3. iPhone SE2 적용

📌 서비스 workflow

📌 협업 방식

📌 기능별 개발 여부

화면기능상세 기능개발
스플래시윤재🚀
온보딩윤재🚀
회원가입윤재🚀
로그인로그인윤재🚀
자동로그인윤재🚀
오늘의 질문 및 답변 열람윤재🚀
과거의 질문 및 답변 열람윤재🚀
추가 질문 열람윤재🚀
답변 공개 범위 설정윤재🚀
답변 수정 및 삭제윤재🚀
탐색나와 다른 답변들 열람재용🐶
다른 답변들 둘러보기최신, 흥미 탭 및 키워드 필터 검색재용🐶
스크랩/ 언스크랩재용🐶
신고하기재용🐶
팔로잉팔로잉/ 팔로워의 답변 열람윤재🚀
팔로잉/ 팔로워 열람윤재🚀
팔로잉/ 팔로워 검색사용자 검색윤재🚀
팔로우/ 언팔로우윤재🚀
팔로워 삭제윤재🚀
신고하기윤재🚀
마이페이지프로필 편집윤재🚀
내 글, 스크랩 열람세란🌿
키워드 및 필터 검색세란🌿
답변 공개 범위 설정세란🌿
스크랩/ 언스크랩세란🌿
글 상세답변답변 상세 열람재용🐶
답변 수정 및 삭제재용🐶
스크랩/언스크랩재용🐶
신고하기재용🐶
댓글댓글 작성재용🐶
댓글의 답글 작성재용🐶
댓글 공개범위 설정재용🐶
댓글 수정 및 삭제재용🐶
글 쓰기공개범위 및 댓글 기능 설정윤재🚀, 세란🌿
임시저장세란🌿
답변하기세란🌿
타인페이지팔로우/ 언팔로우세란🌿
스크랩/ 언스크랩세란🌿
신고하기세란🌿
최근 활동댓글 및 답글 알림
팔로워 알림
장기 푸쉬 알림오늘의 질문 받기윤재🚀

📌 핵심 기능 구현 방법

  • 글쓰기

answer data를 넣어서 글을 등록하는 코드

AnswerRegistService.shared.regist(answerID: answerData!.id!, content: answerData!.answer!, commentBlocked: commentSwitch.isOn, isPublic: answerSwitch.isOn){(networkResult)->(Void)inswitch networkResult{case.success(let data):print(self.isFromFollowingTab)ifself.isFromFollowingTab {self.followScrapButtonDelegate?.fromAnswerVC(indexInVC:self.indexInFollowingVC!)}case.requestErr(let msg):iflet message = msg as?String{print(message)}case.pathErr :print("pathErr")case.serverErr :print("serverErr")case.networkFail:print("networkFail")}}
  • 타인이 쓴 글 보기

다른 페이지를 다녀와서 다른 사람의 글에 변동이 생길 경우 새로 통신을 해서 Reload해줘야함 페이징 해서 정보를 받기 때문에 1페이지부터 원래의 페이지까지 다시 받아와야 함 이 과정에서 처음에는 for문을 이용해서 어려움을 겪었으나, 통신에서의 재귀함수 호출을 통해 해결

func getUpdateAnswers(){letloadingFrame=CGRect(x:0, y:0, width: view.frame.width, height: view.frame.height)LoadingHUD.show(loadingFrame: loadingFrame,color:.white)
curPage =0
answers =[]updateDataOnePage()}func updateDataOnePage(){
curPage +=1letloadingFrame=CGRect(x:0, y:0, width: view.frame.width, height: view.frame.height)FollowingGetAnswersService.shared.getAnswerData(page: curPage){(networkResult)->(Void)inswitch networkResult{case.success(let data):iflet answerDatas = data as?FollowingAnswersData{self.pageLen = answerDatas.pageLen
foranswerDatain answerDatas.answers{self.answers.append(answerData)}}ifself.curPage <self.answerPage {self.updateDataOnePage()}else{DispatchQueue.global(qos:.background).sync{self.wholeCollectionView.reloadData()self.wholeCollectionView.setContentOffset(CGPoint(x:0, y:self.lastY), animated:false)}LoadingHUD.hide()ifself.answers.count ==0{self.customEmptyView.setItems(text:"아이쿠..! 아직 팔로우하는 사람이 없군요\n팔로잉을 하고 다른 사람들의 글을 둘러보세요")self.wholeCollectionView.addSubview(self.customEmptyView)print(self.customEmptyView.superview?.bounds.minX)self.customEmptyView.snp.makeConstraints{
$0.centerX.equalToSuperview()
$0.top.equalToSuperview().offset(362)
$0.height.equalTo(80)}}else{self.customEmptyView.removeFromSuperview()}}print("success")case.requestErr(let msg):iflet message = msg as?String{print(message)}case.pathErr :print("pathErr")case.serverErr :print("serverErr")case.networkFail:print("networkFail")}}}

📌 Extension을 통한 메소드 설명

  • UIView Extension

    extensionUIView{
    // Set Rounded View
    func makeRounded(cornerRadius :CGFloat?){
    // UIView 의 모서리가 둥근 정도를 설정
    iflet cornerRadius_ = cornerRadius {self.layer.cornerRadius = cornerRadius_
    }else{
    // cornerRadius 가 nil 일 경우의 default
    self.layer.cornerRadius =self.layer.frame.height /2}self.layer.masksToBounds =true}
    // Set UIView's Shadow
    func dropShadow(color:UIColor, offSet:CGSize, opacity:Float, radius:CGFloat){
    // 그림자 색상 설정
    layer.shadowColor = color.cgColor
    // 그림자 크기 설정
    layer.shadowOffset = offSet
    // 그림자 투명도 설정
    layer.shadowOpacity = opacity
    // 그림자의 blur 설정
    layer.shadowRadius = radius
    // 구글링 해보세요!
    layer.masksToBounds =false}
    // Set UIView's Border
    func setBorder(borderColor :UIColor?, borderWidth :CGFloat?){
    // UIView 의 테두리 색상 설정
    iflet borderColor_ = borderColor {self.layer.borderColor = borderColor_.cgColor
    }else{
    // borderColor 변수가 nil 일 경우의 default
    self.layer.borderColor =UIColor(red:205/255, green:209/255, blue:208/255, alpha:1.0).cgColor
    }
    // UIView 의 테두리 두께 설정
    iflet borderWidth_ = borderWidth {self.layer.borderWidth = borderWidth_
    }else{
    // borderWidth 변수가 nil 일 경우의 default
    self.layer.borderWidth =1.0}}}
  • UIViewController

    extensionUIViewController{
    // 토스트 메세지
    func showToast(text:String, completion:@escaping()->()){lettoast=ToastView(frame:CGRect(x:0, y:0, width:343, height:84))
    toast.setLabel(text: text)
    toast.alpha =0self.view.addSubview(toast)
    toast.snp.makeConstraints{
    $0.leading.equalToSuperview().offset(16)
    $0.trailing.equalToSuperview().offset(-16)
    $0.bottom.equalToSuperview().offset(-101)}UIView.animate(withDuration:0.3, animations:{
    toast.alpha =1},completion:{ finish inUIView.animate(withDuration:0.3, delay:0.7, animations:{
    toast.alpha =0}, completion:{ finish inif finish {
    toast.removeFromSuperview()completion()}})})}}
  • UIImageView

    // Kingfisher를 이용하여 url로부터 이미지를 가져오는 extension
    extensionUIImageView{publicfunc imageFromUrl(_ urlString:String?){iflet url = urlString {self.kf.setImage(with:URL(string: url), options:[.transition(ImageTransition.fade(0.5))])}}}

📌 팀원 소개

윤재세란재용
네이스

목차

About

📝 나에 대해 알아가는 질문 다이어리, BeMe

Resources

Stars

9 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages