- 
                Notifications
    
You must be signed in to change notification settings  - Fork 3
 
책 수정 화면 로직 구현 #113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
책 수정 화면 로직 구현 #113
Changes from all commits
d57ec45
              071f402
              3a59a31
              b6e6d83
              977d300
              0e5cae0
              c9a5465
              b86d39d
              24fc2dd
              9d8fb5f
              c6571b9
              6627556
              08e4eea
              5637107
              1478723
              d9407a2
              218cba7
              e3c1865
              a50363d
              533a457
              b13a005
              84c8220
              40438b5
              0aa8f67
              230d7bc
              1ff40f2
              3d43247
              bd0f4b4
              667b01c
              56ddcf1
              3bb9487
              6f334c5
              e98544d
              acfa79f
              e4f2f0e
              2c6e872
              2aad98f
              d8ae689
              2aa3cdc
              fefb2e3
              73cf917
              165df54
              09e3f66
              961e538
              2bc516a
              43c4a1a
              7cefd53
              878ebf3
              b63dede
              4e6f1e0
              6c475ec
              47ead38
              54358d3
              340a3cf
              9a136aa
              d60becb
              68a2b0d
              ad14f84
              d019cfe
              bb0924c
              3f66fd0
              4159dc3
              7a2a84a
              201c1cf
              61a2d60
              2b6bfb6
              260a00e
              604cbc9
              8b263d2
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -1,17 +1,17 @@ | ||
| import MHFoundation | ||
| import MHCore | ||
| 
     | 
||
| struct MHFileManager { | ||
| private let fileManager = FileManager.default | ||
| public struct MHFileManager: Sendable { | ||
| private var fileManager: FileManager { FileManager.default } | ||
| private let directoryType: FileManager.SearchPathDirectory | ||
| 
     | 
||
| init(directoryType: FileManager.SearchPathDirectory) { | ||
| public init(directoryType: FileManager.SearchPathDirectory) { | ||
| self.directoryType = directoryType | ||
| } | ||
| } | ||
| 
     | 
||
| extension MHFileManager: FileStorage { | ||
| func create(at path: String, fileName name: String, data: Data) async -> Result<Void, MHDataError> { | ||
| public func create(at path: String, fileName name: String, data: Data) async -> Result<Void, MHDataError> { | ||
| guard let directory = fileManager.urls( | ||
| for: directoryType, | ||
| in: .userDomainMask | ||
| 
        
          
        
         | 
    @@ -22,13 +22,13 @@ | |
| 
     | 
||
| do { | ||
| try fileManager.createDirectory(at: directory, withIntermediateDirectories: true) | ||
| try data.write(to: dataPath) | ||
| try data.write(to: dataPath, options: .atomic) | ||
| 
         There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3: 해당 option은 어떤걸 뜻하는 것인가욥?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저장할 때 임시파일 만들었다가 저장이 완료되면 실제 파일로 바뀌는 옵션입니다!  | 
||
| return .success(()) | ||
| } catch { | ||
| return .failure(.fileCreationFailure) | ||
| } | ||
| } | ||
| func read(at path: String, fileName name: String) async -> Result<Data, MHDataError> { | ||
| public func read(at path: String, fileName name: String) async -> Result<Data, MHDataError> { | ||
| guard let directory = fileManager.urls( | ||
| for: directoryType, | ||
| in: .userDomainMask | ||
| 
        
          
        
         | 
    @@ -47,7 +47,7 @@ | |
| return .failure(.fileReadingFailure) | ||
| } | ||
| } | ||
| func delete(at path: String, fileName name: String) async -> Result<Void, MHDataError> { | ||
| public func delete(at path: String, fileName name: String) async -> Result<Void, MHDataError> { | ||
| guard let directory = fileManager.urls( | ||
| for: directoryType, | ||
| in: .userDomainMask | ||
| 
        
          
        
         | 
    @@ -63,7 +63,7 @@ | |
| return .failure(.fileDeletionFailure) | ||
| } | ||
| } | ||
| func copy(at url: URL, to newPath: String, newFileName name: String) async -> Result<Void, MHDataError> { | ||
| public func copy(at url: URL, to newPath: String, newFileName name: String) async -> Result<Void, MHDataError> { | ||
| let originDataPath = url | ||
| 
     | 
||
| guard fileManager.fileExists(atPath: originDataPath.path) else { | ||
| 
        
          
        
         | 
    @@ -86,7 +86,7 @@ | |
| return .failure(.fileMovingFailure) | ||
| } | ||
| } | ||
| func copy(at path: String, fileName name: String, to newPath: String) async -> Result<Void, MHDataError> { | ||
| public func copy(at path: String, fileName name: String, to newPath: String) async -> Result<Void, MHDataError> { | ||
| guard let originDirectory = fileManager.urls( | ||
| for: directoryType, | ||
| in: .userDomainMask | ||
| 
          
            
          
           | 
    @@ -115,7 +115,7 @@ | |
| return .failure(.fileMovingFailure) | ||
| } | ||
| } | ||
| func move(at path: String, fileName name: String, to newPath: String) async -> Result<Void, MHDataError> { | ||
| public func move(at path: String, fileName name: String, to newPath: String) async -> Result<Void, MHDataError> { | ||
| guard let originDirectory = fileManager.urls( | ||
| for: directoryType, | ||
| in: .userDomainMask | ||
| 
          
            
          
           | 
    @@ -144,7 +144,7 @@ | |
| return .failure(.fileMovingFailure) | ||
| } | ||
| } | ||
| func moveAll(in path: String, to newPath: String) async -> Result<Void, MHDataError> { | ||
| public func moveAll(in path: String, to newPath: String) async -> Result<Void, MHDataError> { | ||
| guard let originDirectory = fileManager.urls( | ||
| for: directoryType, | ||
| in: .userDomainMask | ||
| 
          
            
          
           | 
    @@ -174,7 +174,7 @@ | |
| return .failure(.fileMovingFailure) | ||
| } | ||
| } | ||
| func getURL(at path: String, fileName name: String) async -> Result<URL, MHDataError> { | ||
| public func getURL(at path: String, fileName name: String) async -> Result<URL, MHDataError> { | ||
| guard let originDirectory = fileManager.urls( | ||
| for: directoryType, | ||
| in: .userDomainMask | ||
| 
        
          
        
         | 
    @@ -185,5 +185,19 @@ | |
| 
     | 
||
| return .success(originDataPath) | ||
| } | ||
| public func getFileNames(at path: String) async -> Result<[String], MHDataError> { | ||
| guard let originDirectory = fileManager.urls( | ||
| for: directoryType, | ||
| in: .userDomainMask | ||
| ).first?.appending(path: path) | ||
| 
         
      Comment on lines
    
      +189
     to 
      +192
    
   
  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당 메서드는 어떤뜻인지 궁금합니다 ! userDomainMask는 어떤 옵션인지 궁금해요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. urls(for:in:)메스드에서 저희는 ~/Document를 사용한다고 코딩해놓은 것입니다! 문서가 더 잘 설명되어있으니 한번 보셔도 좋을 것같아요!  | 
||
| else { return .failure(.directorySettingFailure) } | ||
| 
     | 
||
| do { | ||
| let files = try fileManager.contentsOfDirectory(atPath: originDirectory.path) | ||
| return .success(files) | ||
| } catch { | ||
| return .failure(.fileNotExists) | ||
| } | ||
| } | ||
| } | ||
| 
     | 
||
| 
         Check warning on line 203 in MemorialHouse/MHData/MHData/LocalStorage/FileManager/MHFileManager.swift 
    
   | 
||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| 
          
            
          
           | 
    @@ -4,9 +4,11 @@ | |
| import MHCore | ||
| import AVFoundation | ||
| 
     | 
||
| // TODO: nil이라면 바로 error를 return하도록 수정 | ||
| 
         Check warning on line 7 in MemorialHouse/MHData/MHData/Repository/LocalMediaRepository.swift 
    
   | 
||
| 
         There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 나중에 해도 될까요...하하하....ㅠ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 당근이져.. 여기서 더 추가되는건...저도 원치 않아요......  | 
||
| public struct LocalMediaRepository: MediaRepository { | ||
| public struct LocalMediaRepository: MediaRepository, Sendable { | ||
| private let storage: FileStorage | ||
| private let temporaryPath = "temp" // TODO: - 지워질 것임! | ||
| 
         Check warning on line 10 in MemorialHouse/MHData/MHData/Repository/LocalMediaRepository.swift 
    
   | 
||
| private let snapshotFileName = ".snapshot" | ||
| 
     | 
||
| public init(storage: FileStorage) { | ||
| self.storage = storage | ||
| 
        
          
        
         | 
    @@ -18,34 +20,33 @@ | |
| to bookID: UUID? | ||
| ) async -> Result<Void, MHDataError> { | ||
| let path = bookID == nil | ||
| ? "temp" | ||
| ? temporaryPath | ||
| : bookID!.uuidString | ||
| let fileName = mediaDescription.id.uuidString | ||
| let fileName = fileName(of: mediaDescription) | ||
| 
     | 
||
| return await storage.create(at: path, fileName: fileName, data: data) | ||
| } | ||
| 
     | 
||
| public func create( | ||
| media mediaDescription: MediaDescription, | ||
| from: URL, | ||
| to bookID: UUID? | ||
| ) async -> Result<Void, MHDataError> { | ||
| let path = bookID == nil | ||
| ? "temp" | ||
| ? temporaryPath | ||
| : bookID!.uuidString | ||
| let fileName = mediaDescription.id.uuidString | ||
| let fileName = fileName(of: mediaDescription) | ||
| 
     | 
||
| return await storage.copy(at: from, to: path, newFileName: fileName) | ||
| } | ||
| 
     | 
||
| public func read( | ||
| public func fetch( | ||
| media mediaDescription: MediaDescription, | ||
| from bookID: UUID? | ||
| ) async -> Result<Data, MHDataError> { | ||
| let path = bookID == nil | ||
| ? "temp" | ||
| ? temporaryPath | ||
| : bookID!.uuidString | ||
| let fileName = mediaDescription.id.uuidString | ||
| let fileName = fileName(of: mediaDescription) | ||
| 
     | 
||
| return await storage.read(at: path, fileName: fileName) | ||
| } | ||
| 
        
          
        
         | 
    @@ -55,9 +56,9 @@ | |
| at bookID: UUID? | ||
| ) async -> Result<Void, MHDataError> { | ||
| let path = bookID == nil | ||
| ? "temp" | ||
| ? temporaryPath | ||
| : bookID!.uuidString | ||
| let fileName = mediaDescription.id.uuidString | ||
| let fileName = fileName(of: mediaDescription) | ||
| 
     | 
||
| return await storage.delete(at: path, fileName: fileName) | ||
| } | ||
| 
        
          
        
         | 
    @@ -77,16 +78,49 @@ | |
| from bookID: UUID? | ||
| ) async -> Result<URL, MHDataError> { | ||
| let path = bookID == nil | ||
| ? "temp" | ||
| ? temporaryPath | ||
| : bookID!.uuidString | ||
| let fileName = mediaDescription.id.uuidString | ||
| let fileName = fileName(of: mediaDescription) | ||
| 
     | 
||
| return await storage.getURL(at: path, fileName: fileName) | ||
| } | ||
| 
     | 
||
| public func moveAllTemporaryMedia(to bookID: UUID) async -> Result<Void, MHDataError> { | ||
| let path = bookID.uuidString | ||
| 
     | 
||
| return await storage.moveAll(in: "temp", to: path) | ||
| return await storage.moveAll(in: temporaryPath, to: path) | ||
| } | ||
| 
     | 
||
| // MARK: - Snpashot | ||
| public func createSnapshot(for media: [MediaDescription], in bookID: UUID) async -> Result<Void, MHDataError> { | ||
| let path = bookID.uuidString | ||
| let mediaList = media.map { fileName(of: $0) } | ||
| guard let snapshot = try? JSONEncoder().encode(mediaList) | ||
| else { return .failure(.snapshotEncodingFailure) } | ||
| 
     | 
||
| return await storage.create(at: path, fileName: snapshotFileName, data: snapshot) | ||
| } | ||
| 
         
      Comment on lines
    
      +95
     to 
      +102
    
   
  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 미디어 데이터를 저장하는 코드로 보이는데 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 편집뷰에서 수정완려/저장 버튼을 눌렀을 때 호출됩니다!  | 
||
| public func deleteMediaBySnapshot(for bookID: UUID) async -> Result<Void, MHDataError> { | ||
| let path = bookID.uuidString | ||
| 
     | 
||
| do { | ||
| let snapshotData = try await storage.read(at: path, fileName: snapshotFileName).get() | ||
| let mediaSet = Set<String>(try JSONDecoder().decode([String].self, from: snapshotData)) | ||
| // snapshot 파일은 제외 | ||
| let currentFiles = Set<String>(try await storage.getFileNames(at: path).get()).subtracting([snapshotFileName]) | ||
| 
         Check warning on line 110 in MemorialHouse/MHData/MHData/Repository/LocalMediaRepository.swift 
    
   | 
||
| let shouldDelete = currentFiles.subtracting(mediaSet) | ||
| for fileName in shouldDelete { | ||
| _ = try await storage.delete(at: path, fileName: fileName).get() | ||
| } | ||
| return .success(()) | ||
| } catch let error as MHDataError { | ||
| return .failure(error) | ||
| } catch { | ||
| return .failure(.generalFailure) | ||
| } | ||
| } | ||
| // MARK: - Helper | ||
| private func fileName(of media: MediaDescription) -> String { | ||
| return media.id.uuidString + media.type.defaultFileExtension | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
연산 프로퍼티로 하신 이유가 있나요 ?
연산 프로퍼티는 접근할 때마다 매번 새로 호출되는 걸로 아는데, 이 경우
private let fileManager = FileManager.default가 더 괜찮지 않은지 질문 드립니다 !!만약 테스트를 할 거면 생성자 시점에서 주입 받아도 괜찮구요