Skip to content

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

Notifications You must be signed in to change notification settings

Hoon94/ios-diary

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

49 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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%