-
카테고리
-
세부 분야
모바일 앱 개발
-
해결 여부
미해결
8번 프로젝트 > 도전과제 2번 질문
21.07.30 15:30 작성 조회수 112
0
데이터 형식을 json에서 property list 로 전환하는 부분에서 [저장]이 잘 안되고 있습니다.
저장을 했을 때, 아래의 saveToPlistFile 에서 별다른 에러없이 동작을 마칩니다.
해당 메소드에 진입하는 것까지 확인했습니다.
(읽어와서 테이블뷰와 보기모드에는 잘 표현됩니다.)
혹시 아래 정보만으로 원인을 파악해주실 수 있을까요?
Todos.plist
extension Todo {
static var all: [Todo] = Todo.loadTodosFromPlistFile()
/// Todo JSON 파일 위치
private static var todosPathURL: URL {
return try! FileManager.default.url(for: FileManager.SearchPathDirectory.applicationSupportDirectory, in: FileManager.SearchPathDomainMask.userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("todos.plist")
}
/// Todo plist 읽어오기
private static func loadTodosFromPlistFile() -> [Todo] {
guard let asset: NSDataAsset = NSDataAsset(name: "Todos") else {
print("에셋 로드 실패")
return []
}
do {
let decoder: PropertyListDecoder = PropertyListDecoder()
return try decoder.decode([Todo].self, from: asset.data)
} catch {
print("데이터 디코딩 실패")
print(error.localizedDescription)
return []
}
}
/// 현재 Todo 배열 상태를 plist에 저장
@discardableResult private static func saveToPlistFile() -> Bool {
do {
let encoder: PropertyListEncoder = PropertyListEncoder()
let data: Data = try encoder.encode(self.all)
try data.write(to: todosPathURL)
return true
} catch {
print("Property List 저장 실패")
print(error.localizedDescription)
return false
}
}
}
답변을 작성해보세요.
1
yagom
지식공유자2021.08.02
아, 타입 프로퍼티군요! 타입 메서드인지 연산 프로퍼티인지로 착각했어요. 죄송합니다!
앱을 아예 종료했다가 다시 실행했을때도 저장했던 내용이 반영이 안되어있나요?
write(to:) 메서드는 기존 내용을 덮어쓸텐데 희안하네요. 더군다나 오류 없이 마친다니...
어디 다른쪽 문제려나요?
저도 이 코드 조각만으로는 잘 모르겠습니다 ㅠ
0
yagom
지식공유자2021.07.30
답을 알려드리면 서운해 하실것 같아 힌트를 드리자면,
let data: Data = try encoder.encode(self.all)
코드가 문제인 것 같다는 생각이 듭니다 :)
yagom
지식공유자2021.08.01
let data: Data = try encoder.encode(self.all)
를 호출하게 되면 어떤 코드가 실행될까요?
맨 윗줄의
static var all: [Todo] = Todo.loadTodosFromPlistFile()
가 실행될텐데요, 그러면 `loadTodosFromPlistFile()` 메서드가 실행돼서 다시 디스크의 프로퍼티 리스트를 통해 Todo를 가져오겠네요.
그렇게 되면 지금의 상태를 저장하는 것이 아니라 방금 디스크에서 불러온 내용을 다시 디스크에 쓰게 되는거죠.
혹시 제가 잘못 이해한거라면 말씀주세요 :)
namgi kim
질문자2021.08.02
let data: Data = try encoder.encode(self.all)
try data.write(to: todosPathURL)
위 코드의 write() 라인에 breakpoint를 걸은 후, 콘솔에서 'po all' 명령문으로 all 이 아래와 같이 변경된 상태임을 확인했습니다. 이러면 문제없지 않을까요?
(lldb) po all
▿ 2 elements
▿ 0 : Todo
- title : "작업이름1 - 작업 제목 수정함"
▿ due : 2021-07-30 04:59:58 +0000
- timeIntervalSinceReferenceDate : 649313998.0
▿ memo : Optional<String>
- some : "작업메모1"
- shouldNotify : true
- id : "1001"
▿ 1 : Todo
- title : "작업이름2"
▿ due : 2021-07-30 05:19:03 +0000
- timeIntervalSinceReferenceDate : 649315143.0
▿ memo : Optional<String>
- some : "작업메모2"
- shouldNotify : false
- id : "1002"
------------
let data: Data = try encoder.encode(self.all)
위 코드에서 왜 Todo.loadTodosFromPlistFile() 가 호출되는지 이해가 부족합니다ㅠㅠ
구동 시 Todo.loadTodosFromPlistFile() 는 최초 한번만 호출되는 걸로 이해하고 있었습니다.
static이 수시로 때에 따라서 호출되나요?
답변 2