• 카테고리

    질문 & 답변
  • 세부 분야

    모바일 앱 개발

  • 해결 여부

    미해결

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

        }

    }

}

답변 2

·

답변을 작성해보세요.

1

아, 타입 프로퍼티군요! 타입 메서드인지 연산 프로퍼티인지로 착각했어요. 죄송합니다!

앱을 아예 종료했다가 다시 실행했을때도 저장했던 내용이 반영이 안되어있나요?

write(to:) 메서드는 기존 내용을 덮어쓸텐데 희안하네요. 더군다나 오류 없이 마친다니...

어디 다른쪽 문제려나요?

저도 이 코드 조각만으로는 잘 모르겠습니다 ㅠ

0

답을 알려드리면 서운해 하실것 같아 힌트를 드리자면,

let data: Data = try encoder.encode(self.all)

코드가 문제인 것 같다는 생각이 듭니다 :)

namgi kim님의 프로필

namgi kim

질문자

2021.08.01

아무리 봐도 잘 모르겠습니다 ㅠㅠ..

답 알려주셔도 서운해하지 않을께요;..;!

let data: Data = try encoder.encode(self.all)

를 호출하게 되면 어떤 코드가 실행될까요?

맨 윗줄의

static var all: [Todo] = Todo.loadTodosFromPlistFile()

가 실행될텐데요, 그러면 `loadTodosFromPlistFile()` 메서드가 실행돼서 다시 디스크의 프로퍼티 리스트를 통해 Todo를 가져오겠네요.

그렇게 되면 지금의 상태를 저장하는 것이 아니라 방금 디스크에서 불러온 내용을 다시 디스크에 쓰게 되는거죠.

혹시 제가 잘못 이해한거라면 말씀주세요 :)

namgi kim님의 프로필

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이 수시로 때에 따라서 호출되나요?