@@ -14,13 +14,14 @@ struct AppDataScreen: View {
1414 @State private var showDeleteDataConfirmation = false
1515 @State private var isCreatingBackup = false
1616 @State private var isRestoringFromBackup = false
17- @State private var showResult = false
1817 @State private var operationResult : OperationResult ?
1918
2019 var body : some View {
2120 VStack ( spacing: 16 ) {
2221 Group {
23- backupDataButton
22+ if !items. isEmpty {
23+ backupDataButton
24+ }
2425 restoreDataButton
2526 if !items. isEmpty {
2627 removeAllDataButton
@@ -32,7 +33,7 @@ struct AppDataScreen: View {
3233 . animation ( . default, value: items. isEmpty)
3334 . alert (
3435 operationResult? . title ?? " " ,
35- isPresented: $showResult ,
36+ isPresented: $operationResult . mappedToBool ( ) ,
3637 presenting: operationResult,
3738 actions: { _ in
3839 Button ( " Ok " ) { }
@@ -51,7 +52,7 @@ struct AppDataScreen: View {
5152 . accessibilityIdentifier ( " backupDataButton " )
5253 . fileExporter (
5354 isPresented: $isCreatingBackup,
54- document: BackupFileDocument ( items: items. map ( BackupFileDocument . makeBackupItem ) ) ,
55+ document: BackupFileDocument ( items: items. map ( BackupFileDocument . toBackupItem ) ) ,
5556 contentType: . json,
5657 defaultFilename: " Days backup "
5758 ) { result in
@@ -61,7 +62,6 @@ struct AppDataScreen: View {
6162 case let . failure( error) :
6263 operationResult = . error( error. localizedDescription)
6364 }
64- showResult = true
6565 }
6666 }
6767
@@ -77,21 +77,25 @@ struct AppDataScreen: View {
7777 ) { result in
7878 switch result {
7979 case let . success( urls) :
80- if let url = urls. first,
81- url. startAccessingSecurityScopedResource ( ) ,
82- let data = try ? Data ( contentsOf: url) ,
83- let importedItems = try ? JSONDecoder ( ) . decode ( [ BackupFileDocument . BackupItem ] . self, from: data) {
80+ guard let url = urls. first, url. startAccessingSecurityScopedResource ( ) else {
81+ operationResult = . failedToRestore
82+ return
83+ }
84+ do {
8485 defer { url. stopAccessingSecurityScopedResource ( ) }
85- let mappedRealItems = importedItems. map ( \. realItem)
86- mappedRealItems. forEach { modelContext. insert ( $0) }
86+ let data = try Data ( contentsOf: url)
87+ let importedItems = try JSONDecoder ( ) . decode ( [ BackupFileDocument . BackupItem ] . self, from: data)
88+ let currentItems = items. map ( \. backupItem)
89+ let newItemsFromBackup = importedItems. filter { !currentItems. contains ( $0) }
90+ newItemsFromBackup. forEach { modelContext. insert ( $0. realItem) }
91+ try modelContext. save ( )
8792 operationResult = . restoreSuccess
88- } else {
93+ } catch {
8994 operationResult = . failedToRestore
9095 }
9196 case let . failure( error) :
9297 operationResult = . error( error. localizedDescription)
9398 }
94- showResult = true
9599 }
96100 }
97101
@@ -109,10 +113,11 @@ struct AppDataScreen: View {
109113 Button ( " Delete " , role: . destructive) {
110114 do {
111115 try modelContext. delete ( model: Item . self)
116+ try modelContext. save ( )
117+ operationResult = . deletionSuccess
112118 } catch {
113119 assertionFailure ( error. localizedDescription)
114120 operationResult = . error( error. localizedDescription)
115- showResult = true
116121 }
117122 }
118123 . accessibilityIdentifier ( " confirmRemoveAllDataButton " )
@@ -124,12 +129,13 @@ extension AppDataScreen {
124129 private enum OperationResult : Equatable {
125130 case backupSuccess
126131 case restoreSuccess
132+ case deletionSuccess
127133 case failedToRestore
128134 case error( String )
129135
130136 var title : LocalizedStringKey {
131137 switch self {
132- case . backupSuccess, . restoreSuccess: " Done "
138+ case . backupSuccess, . restoreSuccess, . deletionSuccess : " Done "
133139 case . failedToRestore, . error: " Error "
134140 }
135141 }
@@ -138,6 +144,7 @@ extension AppDataScreen {
138144 switch self {
139145 case . backupSuccess: " Backup data saved "
140146 case . restoreSuccess: " Data restored from backup "
147+ case . deletionSuccess: " All data deleted "
141148 case . failedToRestore: " Unable to recover data from the selected file "
142149 case let . error( message) : . init( message)
143150 }
0 commit comments