이번주차 스터디 과제로, 클론 프로젝트를 간단하게 해보기로 했었다!
스터디장님이 올려주신 것 중 나는 흔히 간단하게 다들하는,, Todo List 를 만들어보기로 결정!
이미 만들어진 Project를 따라 코딩하면서 화면 구성과 AutoLayout 그리고 Todo List에 필요한 디테일한 기능을 다뤄볼 예정
자세한 코드는 여기로!
8/15
탭바로 묶기 전에 일단 화면부터 구성해보기로!
나 증말.. 지지리도 Auto Layout 못해서 화면 구성조차 오래걸린다 .. ㅎ~
- 일단 TodoListViewController 생성
- 아 CollectionReusableView는 처음본당! 이거는 Collection View에서 Header View Cell 과 같은 의미! "Reusable"이 붙은 뷰는 헤더뷰와 푸터뷰에 사용되는 특수위젯. (나중에 포스팅 예정)
- 메인화면 구성 완료
- 대충 구성만 아주 사알짝 해놓고
이제 Storage.swift를 작성해보자..
( Storage.swift 파일은 FileManager을 통해, 말그대로 앱 공간을 관리하는 Storage를 위한건데, todo 데이터를 저장, 회복, 초기화, 삭제 등을 할 수 있는 메소드들을 만들어 놓은 곳)
아래는 Storage.swift를 작성하며 모르는 메소드들 기록해둔 것!
File Manager ?
- 아이폰 마다 자신의 앱 공간을 가지고 있는데 이를 관리하는 Manager!
FileManager.SearchPathDirectory : 탐색할 디렉토리 지정
FileManager.SearchPathDirectory.documentDirectory : Document directory
FileManager.SearchPathDirectory.cachesDirectory : 삭제가능한 Caches file(library/cache)
FileManager.default.contents(atPath:) : 파일의 내용을 포함한 NSData 객체
FileManager.default.contentsOfDirectory(atPath:) : 해당 디렉토리 안의 파일리스트를 배열로 반환 [String]
FileManager.default.urls(for: , in: )
→ urls(for:, in:) ? SearchPathDomainMask 범위에서 SearchPathDirectory를 찾는 메소드
→ 첫번째 파라미터(for) ? SearchPathDirectory : enum 형태로 구현되어 있어, 실제로 사용자가 사용하는 디렉토리 경로를 지칭한다.
→ 두번째 파라미터(in) ? SearchPathDomainMask : userDomainMask로 설정할 경우, /User 보다 위에 있는 디렉토리는 접근 X
즉, SearchPathDomainMask보다 상위에 있는 디렉토리를 찾으려고 할 경우 에러가 난다는 말!
JSONEncoder() : JSON 데이터로 인코딩하는 객체
JSONDecoder() : JSON 데이터를 디코딩하는 객체
Storage.swift
import Foundation
public class Storage {
private init() { }
// TODO: FileManager을 통해, 앱 공간을 관리!
enum Directory {
case documents
case caches
var url: URL {
let path: FileManager.SearchPathDirectory
switch self {
case .documents:
path = .documentDirectory
case .caches:
path = .cachesDirectory
}
return FileManager.default.urls(for: path, in: .userDomainMask).first!
}
}
// TODO: store 로직
// Cadable encode : JSON 타입으로
static func store<T: Encodable>(_ obj: T, to directory: Directory, as fileName: String) {
// appendingPathComponent : 경로를 새롭게 추가
let url = directory.url.appendingPathComponent(fileName, isDirectory: false)
print("---> save to here: \(url)")
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted // 출력 줄바꿈 설정
do {
let data = try encoder.encode(obj)
if FileManager.default.fileExists(atPath: url.path) {
try FileManager.default.removeItem(at: url)
}
FileManager.default.createFile(atPath: url.path, contents: data, attributes: nil)
} catch let error {
print("---> Failed to store msg: \(error.localizedDescription)")
}
}
// TODO: retrive 로직
// 파일을 Data 타입 형태로 읽기
// Codable decode : Data 타입으로
static func retrive<T: Decodable>(_ fileName: String, from directory: Directory, as type: T.Type) -> T? {
let url = directory.url.appendingPathComponent(fileName, isDirectory: false)
guard FileManager.default.fileExists(atPath: url.path) else { return nil }
guard let data = FileManager.default.contents(atPath: url.path) else { return nil }
let decoder = JSONDecoder()
do {
let model = try decoder.decode(type, from: data)
return model
} catch let error {
print("---> Failed to decode msg: \(error.localizedDescription)")
return nil
}
}
// TODO: remove 로직
static func remove(_ fileName: String, from directory: Directory) {
let url = directory.url.appendingPathComponent(fileName, isDirectory: false)
guard FileManager.default.fileExists(atPath: url.path) else { return }
do {
try FileManager.default.removeItem(at: url)
} catch let error {
print("---> Failed to remove msg: \(error.localizedDescription)")
}
}
// TODO: clear 로직
static func clear(from directory: Directory) {
let url = directory.url
do {
let contents = try FileManager.default.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: []) // contents 안에는 파일리스트가 배열로 들어가게 됨.
for content in contents { // 하나하나 다 지워!
try FileManager.default.removeItem(at: content)
}
} catch {
print("---> Failed to clear directory ms: \(error.localizedDescription)")
}
}
}
'iOS > Toy project' 카테고리의 다른 글
[iOS : Toy Project] Todo List 만들기 (3) (0) | 2022.08.17 |
---|---|
[iOS : Toy Project] Todo List 만들기 (2) (0) | 2022.08.16 |
[iOS : Toy Project] Github Profile (2) : Refactoring (0) | 2022.07.17 |
[iOS : Toy Project] Github Profile (1) (0) | 2022.07.16 |
[iOS : Toy Project] Apple Framework List (4) : Combine (0) | 2022.07.08 |