Skip to content

야곰 아카데미 iOS 일기장 프로젝트 저장소입니다

Notifications You must be signed in to change notification settings

Hoon94/ios-diary

This branch is up to date with karenyang835/ios-diary:Step3.

Folders and files

NameName
Last commit message
Last commit date

Latest commit

0482761 · Sep 16, 2023

History

49 Commits
Sep 15, 2023
Aug 29, 2023
Sep 15, 2023
Aug 29, 2023
Jun 6, 2022
Aug 29, 2023
Aug 29, 2023
Aug 29, 2023
Sep 16, 2023

Repository files navigation

📕Diary

🔖 목차

  1. 프로젝트 소개
  2. 실행 화면
  3. 시각적 프로젝트 구조
  4. 트러블 슈팅
  5. 참고 링크
  6. about TEAM


1. 💬 프로젝트 소개

CoreData를 활용하여 만든 일기장 앱으로 수정이 간편하고, 날짜별로 날씨 정보를 함께 저장합니다.

Xcode swift IOS SwiftLint



2.📱실행 화면

Diary - 새 일기 작성 Diary - 일기 수정
Diary - 공유, 삭제(메인) Diary - 더보기(디테일)
Diary - Alert Error Diary - Toast Error


3. 📊 시각적 프로젝트 구조

📂 폴더 구조

┌── Diary
│   ├── Network
│   │   ├── Location
│   │   ├── URLComponents
│   │   ├── NetworkAPI
│   │   └── WeatherAPI
│   ├── Error
│   │   ├── DecodingManager
│   │   ├── NetworkAPIDefinition
│   │   └── CacheStore
│   ├── CoreData
│   │   ├── CoreDataManager
│   │   ├── PersistentContainer
│   │   ├── Diary
│   │   │   ├── Diary v2
│   │   │   └── Diary
│   │   └── MappingFile 
│   ├── Model
│   │   ├── DiaryModel
│   │   └── CellIdentifier
│   ├── View
│   │   ├── LaunchScreen
│   │   └── DiaryCell
│   ├── Controller
│   │   ├── DiaryViewController
│   │   └── DiaryDetailViewController
│   ├── Protocol
│   │   ├── Shareable
│   │   └── Toastable
│   ├── Extension
│   │   ├── DateFormatter+
│   │   ├── UITextView+
│   │   └── Array+
│   ├── Application
│   │   ├── AppDelegate
│   │   └── SceneDelegate
│   └── Resource
│       ├── Assets
│       └── Info
│
└── README.md

🎨 Class Diagram


image



4. 🚨 트러블 슈팅

1️⃣ 지역별 현지화

⛔️ 문제점

  • 다이어리의 작성 일자에 대한 날짜 표현 형식을 사용자에 맞게 표현해 주기 위한 방법이 필요했습니다. JSON 파일에 저장된 날짜는 시스템 시간으로 1970년을 기준으로 한 Double 타입의 값이었기 때문에 사용자에게 표현하는 형식을 선택해야 했습니다.

✅ 해결 방법

  • JSON 파일에서 받아온 날짜를 디바이스의 지역에 맞는 형식으로 표현해 주기 위해 아래와 같이 Locale을 사용하였습니다.

    extension DateFormatter {
        static let diaryFormatter = {
            let formatter = DateFormatter()
            formatter.dateStyle = .long
            formatter.locale = Locale.current
    
            return formatter
        }()
    }
    
    // 적용
    let date = Date(timeIntervalSince1970: diaryModel[indexPath.row].date)
    let formattedDate = DateFormatter.diaryFormatter.string(from: date)

    지역에 맞게 날짜의 형식을 변경해 주는 diaryFormatter를 사용하여 JSON 데이터를 디코딩 한 값인 date(Double 타입)을 매개변수로 전달하였습니다.

2️⃣CoreData 사용

⛔️ 문제점

  • CoreData를 활용하는데 어려움이 많았습니다. 그중에서 새 일기장을 만들고 아무것도 입력하지 않은 상태로 다시 나오거나 입력을 하다가 다 지우고 나오면 생성되지 않아야 된다고 생각을 하였는데 생성이 되는 문제점이 발생했습니다.

✅ 해결 방법

  • textView의 내용이 비어있으면 delete를 해주어 해결했습니다.

     func saveDiary() {
            guard !contentTextView.text.isEmpty else {
                CoreDataManager.shared.deleteDiary(item: diary)
                return
            }
    
            let contents = contentTextView.text.split(separator: "\n")
            let title = String(contents[0])
            let body = contents.dropFirst().joined(separator: "\n")
    
            if contents.isEmpty {
                saveContents(title: "", body: "")
            } else {
                saveContents(title: title, body: body)
            }
        }

3️⃣ Diary 생성 위치

⛔️ 문제점

  • DiaryCreat하는 위치에 따라 tableViewcell이 추가되는 시점이 달랐습니다. 두 번째 화면인 DiaryDetailViewController에서 Diary를 생성하고 저장하는 경우 이전 화면으로 돌아와 tableView를 확인하면 목록에 없는 문제가 발생하였습니다. 다음 화면으로 넘어갔다가 다시 돌아오면 그제야 celltableView에 추가되었습니다. tableViewcell이 그려지는 시점이 문제였습니다.

✅ 해결 방법

  • 이를 해결하기 위해 Diary를 첫 화면인 DiaryViewController에서 생성하여 다음 화면인 DiaryDetailViewController로 넘겨주는 작업을 수행하였습니다.

    let action = UIAction { _ in
        let diary = CoreDataManager.shared.createDiary()
        let diaryDetailViewController = DiaryDetailViewController(diary: diary, isUpdate: false)
        self.navigationController?.pushViewController(diaryDetailViewController, animated: true)
    }

    생성한 Diary에 입력을 하는 경우 save 또는 update 동작을 분리하기 위하여 isUpdate를 통해 구분하였습니다.

4️⃣ 오토레이아웃

⛔️ 문제점

  • Hierarchy로 확인을 했을 때 해당 오류가 발생됐습니다.

✅ 해결 방법

  • 확인을 해보니 날짜를 받아오는 label의 사이즈가 변동이 되면서 발생된 문제점이라 Hugging을 주어서 해결했습니다.

        private let dateLabel = {
                let label = UILabel()
                label.font = .preferredFont(forTextStyle: .body)
                label.setContentHuggingPriority(.defaultHigh, for: .horizontal)
    
                return label
            }()

5️⃣CoreData 사용

⛔️ 문제점

  • 새 일기장을 만들고 아무것도 입력하지 않은 상태로 다시 나오거나 입력을 하다가 다 지우고 나오면 생성되지 않아야 된다고 생각을 하였는데 생성이 되는 문제점이 발생했습니다.

✅ 해결 방법

  • textView의 내용이 비어있으면 delete를 해주어 해결했습니다.

     func saveDiary() {
            guard !contentTextView.text.isEmpty else {
                CoreDataManager.shared.deleteDiary(item: diary)
                return
            }
    
            let contents = contentTextView.text.split(separator: "\n")
            let title = String(contents[0])
            let body = contents.dropFirst().joined(separator: "\n")
    
            if contents.isEmpty {
                saveContents(title: "", body: "")
            } else {
                saveContents(title: title, body: body)
            }
        }

6️⃣ Diary 생성 위치

⛔️ 문제점

  • DiaryCreat하는 위치에 따라 tableViewcell이 추가되는 시점이 달랐습니다. 두 번째 화면인 DiaryDetailViewController에서 Diary를 생성하고 저장하는 경우 이전 화면으로 돌아와 tableView를 확인하면 목록에 없는 문제가 발생하였습니다. 다음 화면으로 넘어갔다가 다시 돌아오면 그제야 celltableView에 추가되었습니다. tableViewcell이 그려지는 시점이 문제였습니다.

✅ 해결 방법

  • Diary를 첫 화면인 DiaryViewController에서 생성하여 다음 화면인 DiaryDetailViewController로 넘겨주는 작업을 수행하였습니다.

    let action = UIAction { _ in
        let diary = CoreDataManager.shared.createDiary()
        let diaryDetailViewController = DiaryDetailViewController(diary: diary, isUpdate: false)
        self.navigationController?.pushViewController(diaryDetailViewController, animated: true)
    }

    생성한 Diary에 입력을 하는 경우 save 또는 update 동작을 분리하기 위하여 isUpdate를 통해 구분하였습니다.

7️⃣ 오토레이아웃

⛔️ 문제점

  • 일기장을 새로 만든 후에 날씨 아이콘을 받아와서 등록됐을때는 온전하게 오토 레이아웃이 적용됐는데 일기장을 들어갔다 나오면 날씨 아이콘이 커져버리는 문제점이 발생했습니다.

✅ 해결 방법

  • dateLabel의 높이에 맞추어서 날씨 아이콘의 크기가 변경되도록 제약조건을 잡아주고 dateLabelsetContentHuggingPriorityrequired로 가장 높게 잡아주어 해결했습니다.

     private let dateLabel = {
            let label = UILabel()
            label.font = .preferredFont(forTextStyle: .body)
            label.setContentHuggingPriority(.required, for: .vertical)
            label.setContentHuggingPriority(.defaultHigh, for: .horizontal)
    
            return label
        }()
    
        private let weatherIconImageView = {
            let imageView = UIImageView()
            imageView.contentMode = .scaleAspectFit
    
            return imageView
        }()

8️⃣ API KEY 숨기기

⛔️ 문제점

  • API KEY를 코드에 직접 입력하여 사용하는 경우 API KEY가 외부에 드러날 수 있다는 문제점이 있었습니다. 팀원과의 협업을 위해 git을 통해 코드를 업로드 하는 과정에서 입력했던 API KEY가 함께 업로드 되었습니다.

✅ 해결 방법

  • API KEY를 감추기 위해 plist 파일을 생성하여 외부에 드러나지 않도록 숨겼습니다. API KEY를 위해 생성한 파일을 git에 저장하고 이후 git에서 추적하지 않도록 설정하여 실제 KEY 값을 사용하였습니다.

    git update-index --skip-worktree Diary/Resource/WeatherInfo.plist


5.🔗 참고 링크



6. 🎩 aboutTEAM

hoon ♓️ Karen ♉️
https://github.com/Hoon94 https://github.com/karenyang835
⏰ 타임 라인 (펼쳐보기)
날 짜 내 용
2023.08.28. 📝 프로젝트에서 필요로 하는 핵심기능 공부 - CoreData
2023.08.29. 🖨️ SwiftLint 라이브러리 추가
✴️ tableView 구현
✴️ navigationController 구현
2023.08.30. ✴️ parseData 메서드 구현
✴️ custom cell 구현
✴️ diaryFormatter 구현
💥 DiaryDetailViewController 화면이동 추가 구현
2023.08.31. ✴️ DiaryDetailViewController 레이아웃 구현
💥 keyboard에 맞춰 제약조건 수정
2023.09.01. 💥 DiaryCell 선택시 다음 화면으로 이동
✴️ CellIdentifier 구현
✴️ DataAsset을 불러오지 못하는 경우 presentAlert메소드 추가
💥 중복 사용하는 프로퍼티를 상수로 선언
💥 UITableViewDelegateUITableViewDataSource extension 분리
💥 diaryList로 네이밍 변경
✍️ README수정
2023.09.04. 📝 프로젝트에서 필요로 하는 핵심기능 공부 - CoreData CRUD
2023.09.05. 📝 프로젝트에서 필요로 하는 핵심기능 공부 - UITextViewDelegate
2023.09.06. 📝 프로젝트에서 필요로 하는 핵심기능 공부 - UISwipeActionsConfiguration
2023.09.07. ✴️ CoreData Diary Entity 생성
✴️ Coredata loadDiary 메소드 추가
✴️ CoreData saveDiary 메소드 추가
✴️ Coredata deleteDiary 메소드 추가
2023.09.08. ✴️ CoreData updateDiary 메소드 추가
✴️ keyboard Done버튼 추가
💥 DiaryDetailViewController의 화면 레이아웃을 하나의 contentTextView로 통합
2023.09.09. ✴️ CoreDataManager 추가
✴️ 백그라운드로 진입하는 경우 일기 자동저장 구현
💥 기존 CRUD코드 통합
2023.09.11. ✴️ showActivityView 메서드 추가
✴️ Shareable Protocol 생성
✴️ Alert 기능 추가
💥 tableView swipe action 공유기능 추가
2023.09.12. ✴️ Array extension 추가
💥CoreDataManager을 제너릭타입 활용으로 변경
💥 isUpdated 상수명 수정
💥closure 순환참조 방지를 위한 weak self 수정
2023.09.13. 💥 configureCell 메서드 매개변수 타입 변경
💥 Shareable 프로토콜 제네릭 타입으로 변경
2023.09.14. ✴️ WeatherAPI 생성 및 API KEY 숨기기
✴️ NetworkManager 생성 및 fetchWeather메서드 구현
✴️ decodeData 메서드 구현 및 모델 생성
✴️ CoreLocation기반 위치정보 가져오기 구현
2023.09.15. 💥 prepareForReuse 메서드 수정
💥 CacheStore로 네이밍 변경
💥 NetworkAPI 수정
✴️ NetworkAPI 생성
💥 Cell 재사용을 위한 초기화 및 날씨 icon autolayout 수정
✴️ CoreData 마이그레이션 및 fetchIconImage 메서드 추가
2023.09.16. ✴️ showToast 메서드 생성
💥 if let으로 수정하여 가독성 향상
🖨️ 스토리보드 삭제


About

야곰 아카데미 iOS 일기장 프로젝트 저장소입니다

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Swift 100.0%