Skip to content

jcrescent61/ios-wanted-GyroData

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

76 Commits
 
 
 
 
 
 
 
 

Repository files navigation

🗂 Gyro Data 프로젝트

📘 목차


📜 프로젝트 및 개발자 소개

소개 : 6축 데이터(acc 3축 + gyro 3축)를 다뤄보고, 데이터를 생성하여 CoreData와 json파일로 저장하고, 불러오는 앱입니다.
프로젝트 기간 : 2022.12.26 ~ 2022.12.30

엘렌(Ellen) 언체인(Unchain) 예톤(Yeton)

엘렌(Ellen)

  • MVVM 아키텍처 구조 설계
  • 측정 및 플레이 로직 구현
  • AnalysisView 측정 화면 구현

언체인(unchain)

  • 그래프뷰 구현
  • SwiftUI와 UIKit 데이터 바인딩
  • 메인화면 구현

예톤(Yeton)

  • 코어데이터 구현
  • 파일매니저 구현
  • PlayView 구현

⚙️ 개발환경 및 라이브러리

swift xcode img FileManager


🟦 Gyro Data 프로젝트 로고

💡 키워드

  • Combine
  • FileManager
  • SwiftUI
  • Charts(SwiftUI)
  • CoreData
  • MVVM
  • UITableView
  • GraphView
  • DataFormatting
  • SwiftUI + Combine
  • UIKit

📱 구현 화면

메인 화면 측정 화면

Play 화면 View 화면

FileManager 저장

  • 그래프를 그려주는 모델을 저장
  • file url 경로를 타고 들어가면 아래와 같은 파일이 생성되어 있음

CoreData 저장

  • 테이블 뷰 셀을 그려주는 모델을 CoreData에 저장

👩🏻‍💻 코드 설명

CoreData
  • GraphFileManager : File에 json 데이터 형태로 그래프 관련 데이터를 저장하는 FileManager Manager
  • CoreDataManager : CoreData에 key value 형태로 셀 관련 데이터를 저장하는 CoreData Manager


Model
  • CellModel : Cell에 보여지는 모델 타입
  • GraphModel : Graph에 보여지는 모델 타입
  • AnalysisType : Acc와 Gyro 타입을 선택할 수 있는 enum

Manager
  • AnalysisManager : 측정을 시작하고 종료하는 메서드를 관리하는 타입

Domain
  • GraphRecordViewModel: 그래프와 관련된 모델을 전달받아 뷰컨트롤러에 전달해주는 뷰 모델
  • GraphRecordViewController: 일반 View와 Play View를 조건에 맞게 화면에 보여주는 뷰 컨트롤러
  • AnalyzeListViewController: 첫 번째 화면, 측정이 완료되면 기록되는 테이블 뷰를 가지고 있는 뷰 컨트롤러
  • AnalyzeListViewModel: 셀에 보여줄 데이터를 전달해주는 뷰 모델
  • AnalysisTableViewCell: 테이블 뷰에 보여질 오토레이아웃과 요소들을 설정한 셀
  • HostingViewController: SwiftUI의 뷰와 UIKit의 코드를 연결해주기 위해 생성한 뷰 컨트롤러
  • AnalyzeViewController: 측정 버튼을 누르면 그래프가 실시간으로 측정되어 그려지는 화면을 보여주는 뷰 컨트롤러
  • AnalyzeViewModel: 측정된 값을 코어데이터에 저장하는 뷰 모델

Extension
  • UIColor+: 자주 사용되는 색을 지정할 수 있도록 확장
  • UIView+ : 뷰컨트롤러에 뷰를 추가하는 기능을 확장
  • Date+: DateFormatter를 사용하여 날짜 형식 기능 확장

SupportFile
  • GyroData: CoreData에 존재하는 Entity 타입

📁 폴더 구조

.
├── AppDelegate.swift
├── CoreData
│   ├── CoreDataManager.swift
│   └── GraphFileManager.swift
├── Domain
│   ├── Analyze
│   │   ├── AnalyzeViewController.swift
│   │   ├── AnalyzeViewModel.swift
│   │   └── HostingViewController.swift
│   ├── GraphView.swift
│   ├── Record
│   │   ├── GraphRecordView.swift
│   │   └── GraphRecordViewModel.swift
│   └── TableView
│       ├── AnalyzeListViewController.swift
│       ├── AnalyzeListViewModel.swift
│       └── Cell
│           └── AnalysisTableViewCell.swift
├── Extension
│   ├── UIColor+.swift
│   ├── UIDate+.swift
│   └── UIView+.swift
├── Manager
│   └── AnalysisManager.swift
├── Model
│   └── AnalysisType.swift
├── SceneDelegate.swift
├── SupportFile
│   ├── Assets.xcassets
│   │   ├── AccentColor.colorset
│   │   │   └── Contents.json
│   │   ├── AppIcon.appiconset
│   │   │   └── Contents.json
│   │   └── Contents.json
│   ├── Base.lproj
│   │   └── LaunchScreen.storyboard
│   ├── GyroData.xcdatamodeld
│   │   └── GyroData.xcdatamodel
│   │       └── contents
│   └── Info.plist
└── ios-wanted-GyroData.txt

⚡️ 트러블 슈팅

1. UIKit과 SwiftUI의 Charts의 데이터 바인딩

처음 과제를 받고 차트를 그리려고 할 때 올해 WWDC에서 보았던 SwiftUI Charts가 생각이 났습니다. iOS16에서 사용할 수 있는 신 기술이기도 해서 한번 적용해보고 싶은 마음에 SwiftUIView를 그려서 UIHostingViewcontroller를 이용하여 사용했습니다. charts를 사용하여 만든 그래프뷰에 데이터가 바로 반영이 되지않는 트러블이 일어났습니다. 컴바인을 사용했기 때문에 데이터 바인딩이 잘 됐을거라고 판단을 했었지만 그것은 UIKit의 관점에서는 당연했지만 SwiftUIView는 프로퍼티레퍼로 바인딩된 데이터에만 뷰를 새로 그리기 때문에 다른방법을 찾아야 했습니다. 처음에는 ObservableObject를 이용하여 바인딩을 시도 했었는데 어떤 이유에선지 바인딩이 잘 되지 않았고 Environmentobject를 활용하기로 했습니다. 일반적인 데이터의 전달은 ObservableObject를 이용 하지만 모든 뷰가 동일 한 모델을 가리키고 데이터의 변화에 즉시 업데이트가 필요한 경우에 사용하게 됩니다. Environmentobject의 장점이 데이터의 변경에 따라 어떤 부분이든 동기화를 보장 한다는 것이기 때문입니다.

2. 단방향 구조의 MVVM 설계

데이터 흐름을 오직 단방향으로 흐르게 구현했습니다. 데이터 흐름이 단순하여 새로운 기능이 추가되어도 리팩토링에 용이합니다. 또한 Swift의 프로토콜 프로그래밍 패러다임을 채택하여 ViewModel의 Input 시그널과 Output 시그널 모두를 Protocol을 사용하여 인터페이스화 했습니다.


3. Model 타입에 대한 고민

처음 Model을 구상하였을 때에는 Model 내부 프로퍼티의 타입에 아래와 같이 Core Data에서 제공하는 기본 타입이 아닌 커스텀한 타입이 존재했습니다.

struct GyroDataModel: Codable {
    let id: UUID
    let analysisType: AnalysisType
    let savedAt: [Date]
    let measurementTime: Double
}

커스텀 한 타입인 AnalysisType, [Date] 등을 Core Data에 넣어주고자 했으나 이미 만들어진 entity와 파일을 수정하는 것에 어려움을 겪었습니다. 그래서 아이폰 앱마다 존재하는 공간을 관리하는 매니저FileManager를 사용하는 방식을 추가하였습니다.

결론적으로 CoreData셀에 보여지는 기본적인 타입을 저장하는 데 사용했고, FileManager아이폰 앱 내부 경로에 json 형태로 커스텀 한 타입을 저장할 때 사용하여 두 가지 방식을 모두 채택하였습니다.

🔗 참고 링크

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Swift 100.0%