From 0f372e1f9556c391df28b334a71baeb44f7f178d Mon Sep 17 00:00:00 2001 From: Min Hyun Date: Sun, 17 Sep 2023 23:09:42 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20AlertBuilder=20=EC=B6=94=EA=B0=80,=20Er?= =?UTF-8?q?ror=20Localization=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Diary.xcodeproj/project.pbxproj | 24 ++-- .../xcshareddata/xcschemes/Diary.xcscheme | 2 +- Diary/Builder/AlertBuilder.swift | 110 ++++++++++++++++++ .../DiaryDetailViewController.swift | 91 ++++++--------- .../Controller/DiaryListViewController.swift | 54 ++++----- Diary/Error/APIError.swift | 26 ++--- Diary/Error/CoreDataError.swift | 18 +-- Diary/Error/DecodingError.swift | 8 +- Diary/Model/Namespace/AlertNamespace.swift | 12 -- Diary/Model/Namespace/ButtonNamespace.swift | 16 --- Diary/Network/NetworkManager.swift | 2 +- en.lproj/Localizable.strings | 25 +++- ko.lproj/Localizable.strings | 25 +++- 13 files changed, 252 insertions(+), 161 deletions(-) create mode 100644 Diary/Builder/AlertBuilder.swift delete mode 100644 Diary/Model/Namespace/AlertNamespace.swift delete mode 100644 Diary/Model/Namespace/ButtonNamespace.swift diff --git a/Diary.xcodeproj/project.pbxproj b/Diary.xcodeproj/project.pbxproj index 8e8906caa..5d021eeba 100644 --- a/Diary.xcodeproj/project.pbxproj +++ b/Diary.xcodeproj/project.pbxproj @@ -12,8 +12,6 @@ 632F74F22AB14D8D003E1B97 /* WeatherResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 632F74F12AB14D8D003E1B97 /* WeatherResult.swift */; }; 632F74F42AB14DBC003E1B97 /* APIError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 632F74F32AB14DBC003E1B97 /* APIError.swift */; }; 636B19AC2AA6C5E900B5242D /* AlertDisplayble.swift in Sources */ = {isa = PBXBuildFile; fileRef = 636B19AB2AA6C5E900B5242D /* AlertDisplayble.swift */; }; - 63B12BAE2AAD9C9000D614A6 /* AlertNamespace.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B12BAD2AAD9C9000D614A6 /* AlertNamespace.swift */; }; - 63B12BB02AAD9D3400D614A6 /* ButtonNamespace.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B12BAF2AAD9D3400D614A6 /* ButtonNamespace.swift */; }; 63BB62822A9F109400524DCB /* DecodingManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63BB62812A9F109400524DCB /* DecodingManager.swift */; }; 63BB62B22AA181BE00524DCB /* Diary+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63BB62B02AA181BE00524DCB /* Diary+CoreDataClass.swift */; }; 63BB62B32AA181BE00524DCB /* Diary+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63BB62B12AA181BE00524DCB /* Diary+CoreDataProperties.swift */; }; @@ -29,6 +27,7 @@ BAECB2D92AB18611006B4A46 /* DiaryV2.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = BAECB2D82AB18611006B4A46 /* DiaryV2.xcmappingmodel */; }; BAECB2DD2AB187D6006B4A46 /* ImageCachingManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAECB2DC2AB187D6006B4A46 /* ImageCachingManager.swift */; }; BAECB2E12AB568A0006B4A46 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = BAECB2E32AB568A0006B4A46 /* Localizable.strings */; }; + BAECB2E82AB72869006B4A46 /* AlertBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAECB2E72AB72869006B4A46 /* AlertBuilder.swift */; }; C739AE25284DF28600741E8F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C739AE24284DF28600741E8F /* AppDelegate.swift */; }; C739AE27284DF28600741E8F /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C739AE26284DF28600741E8F /* SceneDelegate.swift */; }; C739AE29284DF28600741E8F /* DiaryListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C739AE28284DF28600741E8F /* DiaryListViewController.swift */; }; @@ -43,8 +42,6 @@ 632F74F32AB14DBC003E1B97 /* APIError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIError.swift; sourceTree = ""; }; 632F74F72AB17E05003E1B97 /* Diary V2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Diary V2.xcdatamodel"; sourceTree = ""; }; 636B19AB2AA6C5E900B5242D /* AlertDisplayble.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertDisplayble.swift; sourceTree = ""; }; - 63B12BAD2AAD9C9000D614A6 /* AlertNamespace.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertNamespace.swift; sourceTree = ""; }; - 63B12BAF2AAD9D3400D614A6 /* ButtonNamespace.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonNamespace.swift; sourceTree = ""; }; 63BB62812A9F109400524DCB /* DecodingManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecodingManager.swift; sourceTree = ""; }; 63BB62B02AA181BE00524DCB /* Diary+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Diary+CoreDataClass.swift"; path = "Diary/Model/CoreData/Diary+CoreDataClass.swift"; sourceTree = SOURCE_ROOT; }; 63BB62B12AA181BE00524DCB /* Diary+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Diary+CoreDataProperties.swift"; path = "Diary/Model/CoreData/Diary+CoreDataProperties.swift"; sourceTree = SOURCE_ROOT; }; @@ -63,6 +60,7 @@ BAECB2E22AB568A0006B4A46 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; BAECB2E42AB568D2006B4A46 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/LaunchScreen.strings; sourceTree = ""; }; BAECB2E52AB568D2006B4A46 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = ""; }; + BAECB2E72AB72869006B4A46 /* AlertBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertBuilder.swift; sourceTree = ""; }; C739AE21284DF28600741E8F /* Diary.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Diary.app; sourceTree = BUILT_PRODUCTS_DIR; }; C739AE24284DF28600741E8F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; C739AE26284DF28600741E8F /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -146,7 +144,6 @@ children = ( BAECB2DA2AB1877C006B4A46 /* DTO */, 63BB62B62AA185E700524DCB /* CoreData */, - BAECB2DB2AB187AB006B4A46 /* Namespace */, BAECB2DE2AB18A17006B4A46 /* ImageCache */, ); path = Model; @@ -189,21 +186,20 @@ path = DTO; sourceTree = ""; }; - BAECB2DB2AB187AB006B4A46 /* Namespace */ = { + BAECB2DE2AB18A17006B4A46 /* ImageCache */ = { isa = PBXGroup; children = ( - 63B12BAD2AAD9C9000D614A6 /* AlertNamespace.swift */, - 63B12BAF2AAD9D3400D614A6 /* ButtonNamespace.swift */, + BAECB2DC2AB187D6006B4A46 /* ImageCachingManager.swift */, ); - path = Namespace; + path = ImageCache; sourceTree = ""; }; - BAECB2DE2AB18A17006B4A46 /* ImageCache */ = { + BAECB2E62AB72855006B4A46 /* Builder */ = { isa = PBXGroup; children = ( - BAECB2DC2AB187D6006B4A46 /* ImageCachingManager.swift */, + BAECB2E72AB72869006B4A46 /* AlertBuilder.swift */, ); - path = ImageCache; + path = Builder; sourceTree = ""; }; C739AE18284DF28600741E8F = { @@ -229,6 +225,7 @@ C739AE23284DF28600741E8F /* Diary */ = { isa = PBXGroup; children = ( + BAECB2E62AB72855006B4A46 /* Builder */, 632F74EE2AB14CF3003E1B97 /* Network */, 636B19AA2AA6C5C200B5242D /* Protocol */, 63E5273D2A9ECD660000FBA6 /* Model */, @@ -372,6 +369,7 @@ 63BB62822A9F109400524DCB /* DecodingManager.swift in Sources */, 632F74F22AB14D8D003E1B97 /* WeatherResult.swift in Sources */, 63E527372A9D87660000FBA6 /* DiaryListTableViewCell.swift in Sources */, + BAECB2E82AB72869006B4A46 /* AlertBuilder.swift in Sources */, C739AE2F284DF28600741E8F /* Diary.xcdatamodeld in Sources */, BAECB2D12AB157CB006B4A46 /* NetworkConfiguration.swift in Sources */, 63BB62B52AA182AA00524DCB /* CoreDataManager.swift in Sources */, @@ -381,9 +379,7 @@ BABBDAE52A9F13A200D8D50B /* DecodingError.swift in Sources */, BABBDB362AAD904100D8D50B /* CoreDataError.swift in Sources */, BABBDB342AA6D05A00D8D50B /* ShareDisplayable.swift in Sources */, - 63B12BB02AAD9D3400D614A6 /* ButtonNamespace.swift in Sources */, 63BB62B32AA181BE00524DCB /* Diary+CoreDataProperties.swift in Sources */, - 63B12BAE2AAD9C9000D614A6 /* AlertNamespace.swift in Sources */, 63BB62B22AA181BE00524DCB /* Diary+CoreDataClass.swift in Sources */, 632F74F42AB14DBC003E1B97 /* APIError.swift in Sources */, ); diff --git a/Diary.xcodeproj/xcshareddata/xcschemes/Diary.xcscheme b/Diary.xcodeproj/xcshareddata/xcschemes/Diary.xcscheme index 1d4381008..f5cb22860 100644 --- a/Diary.xcodeproj/xcshareddata/xcschemes/Diary.xcscheme +++ b/Diary.xcodeproj/xcshareddata/xcschemes/Diary.xcscheme @@ -33,7 +33,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "ko" + language = "en" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/Diary/Builder/AlertBuilder.swift b/Diary/Builder/AlertBuilder.swift new file mode 100644 index 000000000..b9e84fda7 --- /dev/null +++ b/Diary/Builder/AlertBuilder.swift @@ -0,0 +1,110 @@ +// +// AlertBuilder.swift +// Diary +// +// Created by Min Hyun on 2023/09/17. +// + +import UIKit + +final class AlertBuilder { + private let viewController: UIViewController + private let alertController: UIAlertController + + private var type: AlertType? + private var alertActions: [UIAlertAction] = [] + + init(viewController: UIViewController, prefferedStyle: UIAlertController.Style) { + self.viewController = viewController + self.alertController = UIAlertController(title: nil, message: nil, preferredStyle: prefferedStyle) + } + + func setType(_ type: AlertType) { + self.type = type + } + + func addAction(_ actionType: AlertActionType, action: ((UIAlertAction) -> Void)? = nil) { + let action = UIAlertAction(title: actionType.title, style: actionType.style, handler: action) + alertActions.append(action) + } + + @discardableResult + func show() -> Self { + alertController.title = type?.title + alertController.message = type?.message + alertActions.forEach { alertController.addAction($0) } + + viewController.present(alertController, animated: true) + + return self + } +} + +extension AlertBuilder { + enum AlertType { + case decodingError(error: DecodingError) + case apiError(error: APIError) + case coreDataError(error: CoreDataError) + case delete + case actionSheet + + var title: String? { + switch self { + case .decodingError, .apiError: + return NSLocalizedString("networkError", comment: "") + case .coreDataError(let error): + return error.alertTitle + case .delete: + return NSLocalizedString("deleteTitle", comment: "") + case .actionSheet: + return nil + } + } + + var message: String? { + switch self { + case .decodingError(let error): + return error.message + case .apiError(let error): + return error.message + case .coreDataError(let error): + return error.message + case .delete: + return NSLocalizedString("deleteMessage", comment: "") + case .actionSheet: + return nil + } + } + } + + enum AlertActionType { + case confirm + case cancel + case share + case delete + + var title: String { + switch self { + case .confirm: + return NSLocalizedString("confirm", comment: "") + case .cancel: + return NSLocalizedString("cancel", comment: "") + case .share: + return NSLocalizedString("share", comment: "") + case .delete: + return NSLocalizedString("delete", comment: "") + } + } + + var style: UIAlertAction.Style { + switch self { + case .cancel: + return .cancel + case .delete: + return .destructive + default: + return .default + } + } + } +} diff --git a/Diary/Controller/DiaryDetailViewController.swift b/Diary/Controller/DiaryDetailViewController.swift index 6dec5c404..1cb0e84da 100644 --- a/Diary/Controller/DiaryDetailViewController.swift +++ b/Diary/Controller/DiaryDetailViewController.swift @@ -128,33 +128,28 @@ final class DiaryDetailViewController: UIViewController, AlertDisplayable, Share } private func showDeleteAlert() { - let cancelAction = UIAlertAction(title: NSLocalizedString("cancelOption", comment: ""), - style: .cancel) - let deleteAction = UIAlertAction(title: NSLocalizedString("deleteOption", comment: ""), - style: .destructive) { [weak self] _ in + let alertBuilder = AlertBuilder(viewController: self, prefferedStyle: .alert) + alertBuilder.setType(.delete) + alertBuilder.addAction(.cancel) + alertBuilder.addAction(.delete) { [weak self] _ in guard let self else { return } do { try CoreDataManager.shared.deleteDiary(self.diary) self.navigationController?.popViewController(animated: true) } catch CoreDataError.deleteFailure { - let cancelAction = UIAlertAction(title: NSLocalizedString("confirm", comment: ""), style: .cancel) - self.showAlert(title: CoreDataError.deleteFailure.alertTitle, - message: CoreDataError.deleteFailure.message, - actions: [cancelAction], - preferredStyle: .alert) + let additionalAlertBuilder = AlertBuilder(viewController: self, prefferedStyle: .alert) + additionalAlertBuilder.setType(.coreDataError(error: .deleteFailure)) + additionalAlertBuilder.addAction(.confirm) + additionalAlertBuilder.show() } catch { - let cancelAction = UIAlertAction(title: NSLocalizedString("confirm", comment: ""), style: .cancel) - self.showAlert(title: CoreDataError.deleteFailure.alertTitle, - message: CoreDataError.unknown.message, - actions: [cancelAction], - preferredStyle: .alert) + let additionalAlertBuilder = AlertBuilder(viewController: self, prefferedStyle: .alert) + additionalAlertBuilder.setType(.coreDataError(error: .unknown)) + additionalAlertBuilder.addAction(.confirm) + additionalAlertBuilder.show() } } - showAlert(title: AlertNamespace.deleteTitle, - message: AlertNamespace.deleteMessage, - actions: [cancelAction, deleteAction], - preferredStyle: .alert) + alertBuilder.show() } deinit { @@ -171,28 +166,18 @@ extension DiaryDetailViewController { } @objc private func showMoreOptions() { - let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) - - let deleteAction = UIAlertAction(title: NSLocalizedString("deleteOption", comment: ""), - style: .destructive) { [weak self] _ in + let alertBuilder = AlertBuilder(viewController: self, prefferedStyle: .actionSheet) + alertBuilder.setType(.actionSheet) + alertBuilder.addAction(.delete) { [weak self] _ in guard let self else { return } self.showDeleteAlert() } - - let shareAction = UIAlertAction(title: NSLocalizedString("shareOption", comment: ""), - style: .default) { [weak self] _ in + alertBuilder.addAction(.share) { [weak self] _ in guard let self else { return } self.shareDiary(self.diary) } - - let cancelAction = UIAlertAction(title: NSLocalizedString("cancelOption", comment: ""), - style: .cancel) - - alertController.addAction(shareAction) - alertController.addAction(deleteAction) - alertController.addAction(cancelAction) - - present(alertController, animated: true) + alertBuilder.addAction(.cancel) + alertBuilder.show() } @objc private func keyboardWillHide(_ notification: Notification) { @@ -208,17 +193,15 @@ extension DiaryDetailViewController: UITextViewDelegate { do { try CoreDataManager.shared.saveContext() } catch CoreDataError.saveFailure { - let cancelAction = UIAlertAction(title: NSLocalizedString("confirm", comment: ""), style: .cancel) - self.showAlert(title: CoreDataError.saveFailure.alertTitle, - message: CoreDataError.saveFailure.message, - actions: [cancelAction], - preferredStyle: .alert) + let alertBulder = AlertBuilder(viewController: self, prefferedStyle: .alert) + alertBulder.setType(.coreDataError(error: .saveFailure)) + alertBulder.addAction(.confirm) + alertBulder.show() } catch { - let cancelAction = UIAlertAction(title: NSLocalizedString("confirm", comment: ""), style: .cancel) - self.showAlert(title: CoreDataError.saveFailure.alertTitle, - message: CoreDataError.unknown.message, - actions: [cancelAction], - preferredStyle: .alert) + let alertBulder = AlertBuilder(viewController: self, prefferedStyle: .alert) + alertBulder.setType(.coreDataError(error: .unknown)) + alertBulder.addAction(.confirm) + alertBulder.show() } } @@ -253,22 +236,18 @@ extension DiaryDetailViewController { self.diary.weatherIcon = weatherIcon } catch { DispatchQueue.main.async { - let confirmAction = UIAlertAction(title: NSLocalizedString("confirm", comment: ""), - style: .default) - self.showAlert(title: AlertNamespace.networkErrorTitle, - message: nil, - actions: [confirmAction], - preferredStyle: .alert) + let alertBulder = AlertBuilder(viewController: self, prefferedStyle: .alert) + alertBulder.setType(.decodingError(error: .decodingFailure)) + alertBulder.addAction(.confirm) + alertBulder.show() } } case .failure: DispatchQueue.main.async { - let confirmAction = UIAlertAction(title: NSLocalizedString("confirm", comment: ""), - style: .default) - self.showAlert(title: AlertNamespace.networkErrorTitle, - message: nil, - actions: [confirmAction], - preferredStyle: .alert) + let alertBulder = AlertBuilder(viewController: self, prefferedStyle: .alert) + alertBulder.setType(.apiError(error: .requestFailure)) + alertBulder.addAction(.confirm) + alertBulder.show() } } } diff --git a/Diary/Controller/DiaryListViewController.swift b/Diary/Controller/DiaryListViewController.swift index 5c5d6c783..29b6751a8 100644 --- a/Diary/Controller/DiaryListViewController.swift +++ b/Diary/Controller/DiaryListViewController.swift @@ -84,17 +84,15 @@ extension DiaryListViewController: AlertDisplayable { diaryList = fetchedDiaries.filter { $0.title != nil } tableView.reloadData() } catch CoreDataError.dataNotFound { - let cancelAction = UIAlertAction(title: ButtonNamespace.confirm, style: .cancel) - showAlert(title: CoreDataError.dataNotFound.alertTitle, - message: CoreDataError.dataNotFound.message, - actions: [cancelAction], - preferredStyle: .alert) + let alertBuilder = AlertBuilder(viewController: self, prefferedStyle: .alert) + alertBuilder.setType(.coreDataError(error: .dataNotFound)) + alertBuilder.addAction(.confirm) + alertBuilder.show() } catch { - let cancelAction = UIAlertAction(title: ButtonNamespace.confirm, style: .cancel) - showAlert(title: CoreDataError.dataNotFound.alertTitle, - message: CoreDataError.unknown.message, - actions: [cancelAction], - preferredStyle: .alert) + let alertBuilder = AlertBuilder(viewController: self, prefferedStyle: .alert) + alertBuilder.setType(.coreDataError(error: .unknown)) + alertBuilder.addAction(.confirm) + alertBuilder.show() } } } @@ -147,17 +145,15 @@ extension DiaryListViewController: UITableViewDelegate, ShareDisplayable { self.readCoreData() success(true) } catch CoreDataError.deleteFailure { - let cancelAction = UIAlertAction(title: ButtonNamespace.confirm, style: .cancel) - self.showAlert(title: CoreDataError.deleteFailure.alertTitle, - message: CoreDataError.deleteFailure.message, - actions: [cancelAction], - preferredStyle: .alert) + let alertBuilder = AlertBuilder(viewController: self, prefferedStyle: .alert) + alertBuilder.setType(.coreDataError(error: .deleteFailure)) + alertBuilder.addAction(.confirm) + alertBuilder.show() } catch { - let cancelAction = UIAlertAction(title: ButtonNamespace.confirm, style: .cancel) - self.showAlert(title: CoreDataError.deleteFailure.alertTitle, - message: CoreDataError.unknown.message, - actions: [cancelAction], - preferredStyle: .alert) + let alertBuilder = AlertBuilder(viewController: self, prefferedStyle: .alert) + alertBuilder.setType(.coreDataError(error: .unknown)) + alertBuilder.addAction(.confirm) + alertBuilder.show() } } @@ -208,17 +204,15 @@ extension DiaryListViewController: UISearchBarDelegate { diaryList = fetchedDiaries.filter { $0.title != nil } tableView.reloadData() } catch CoreDataError.dataNotFound { - let cancelAction = UIAlertAction(title: ButtonNamespace.confirm, style: .cancel) - showAlert(title: CoreDataError.dataNotFound.alertTitle, - message: CoreDataError.dataNotFound.message, - actions: [cancelAction], - preferredStyle: .alert) + let alertBuilder = AlertBuilder(viewController: self, prefferedStyle: .alert) + alertBuilder.setType(.coreDataError(error: .dataNotFound)) + alertBuilder.addAction(.confirm) + alertBuilder.show() } catch { - let cancelAction = UIAlertAction(title: ButtonNamespace.confirm, style: .cancel) - showAlert(title: CoreDataError.dataNotFound.alertTitle, - message: CoreDataError.unknown.message, - actions: [cancelAction], - preferredStyle: .alert) + let alertBuilder = AlertBuilder(viewController: self, prefferedStyle: .alert) + alertBuilder.setType(.coreDataError(error: .unknown)) + alertBuilder.addAction(.confirm) + alertBuilder.show() } } diff --git a/Diary/Error/APIError.swift b/Diary/Error/APIError.swift index 48f9374e5..b1922e675 100644 --- a/Diary/Error/APIError.swift +++ b/Diary/Error/APIError.swift @@ -4,32 +4,30 @@ // // Created by Max, Hemg on 2023/09/13. // +import Foundation enum APIError: Error { case invalidURL - case requestFail + case requestFailure case invalidData - case dataTransferFail - case decodingFail + case dataTransferFailure case invalidHTTPStatusCode case requestTimeOut - var errorDescription: String? { + var message: String? { switch self { case .invalidURL: - return "유효하지 않은 URL입니다." - case .requestFail: - return "요청에 실패했습니다." - case .decodingFail: - return "디코딩 실패했습니다." + return NSLocalizedString("invalidURL", comment: "") + case .requestFailure: + return NSLocalizedString("requestFailure", comment: "") case .invalidData: - return "잘못된 데이터 입니다." - case .dataTransferFail: - return "데이터 변환에 실패했습니다." + return NSLocalizedString("invalidData", comment: "") + case .dataTransferFailure: + return NSLocalizedString("dataTransferFailure", comment: "") case .invalidHTTPStatusCode: - return "잘못된 HTTPStatusCode입니다." + return NSLocalizedString("invalidHTTPStatusCode", comment: "") case . requestTimeOut: - return "요청시간이 초과되었습니다." + return NSLocalizedString("requestTimeOut", comment: "") } } } diff --git a/Diary/Error/CoreDataError.swift b/Diary/Error/CoreDataError.swift index 158dc9f64..667e85ea6 100644 --- a/Diary/Error/CoreDataError.swift +++ b/Diary/Error/CoreDataError.swift @@ -5,6 +5,8 @@ // Created by Max, Hemg on 2023/09/10. // +import Foundation + enum CoreDataError: Error { case dataNotFound case saveFailure @@ -14,26 +16,26 @@ enum CoreDataError: Error { var alertTitle: String { switch self { case .dataNotFound: - return "로드 실패" + return NSLocalizedString("dataNotFoundTitle", comment: "") case .saveFailure: - return "저장 실패" + return NSLocalizedString("saveFailureTitle", comment: "") case .deleteFailure: - return "삭제 실패" + return NSLocalizedString("deleteFailureTitle", comment: "") case .unknown: - return "오류" + return NSLocalizedString("unknownErrorTitle", comment: "") } } var message: String { switch self { case .dataNotFound: - return "데이터를 찾지 못했습니다." + return NSLocalizedString("dataNotFound", comment: "") case .saveFailure: - return "저장에 실패하였습니다." + return NSLocalizedString("saveFailure", comment: "") case .deleteFailure: - return "삭제에 실패하였습니다." + return NSLocalizedString("deleteFailure", comment: "") case .unknown: - return "알 수 없는 오류입니다." + return NSLocalizedString("unknownError", comment: "") } } } diff --git a/Diary/Error/DecodingError.swift b/Diary/Error/DecodingError.swift index e4787cd64..57ceec6ea 100644 --- a/Diary/Error/DecodingError.swift +++ b/Diary/Error/DecodingError.swift @@ -5,6 +5,8 @@ // Created by Max, Hemg on 2023/08/30. // +import Foundation + enum DecodingError: Error { case fileNotFound case decodingFailure @@ -13,11 +15,11 @@ enum DecodingError: Error { var message: String { switch self { case .fileNotFound: - return "파일을 불러오지 못했습니다." + return NSLocalizedString("fileNotFound", comment: "") case .decodingFailure: - return "파일을 변환하지 못했습니다." + return NSLocalizedString("decodingFailure", comment: "") case .unknown: - return "알 수 없는 오류입니다." + return NSLocalizedString("unknownError", comment: "") } } } diff --git a/Diary/Model/Namespace/AlertNamespace.swift b/Diary/Model/Namespace/AlertNamespace.swift deleted file mode 100644 index 7c3b3ccab..000000000 --- a/Diary/Model/Namespace/AlertNamespace.swift +++ /dev/null @@ -1,12 +0,0 @@ -// -// AlertNamespace.swift -// Diary -// -// Created by Maxhyunm, Hamg on 2023/09/10. -// - -enum AlertNamespace { - static let deleteTitle = "진짜요?" - static let deleteMessage = "정말로 삭제하시겠어요?" - static let networkErrorTitle = "네트워크 오류입니다" -} diff --git a/Diary/Model/Namespace/ButtonNamespace.swift b/Diary/Model/Namespace/ButtonNamespace.swift deleted file mode 100644 index 9970ef396..000000000 --- a/Diary/Model/Namespace/ButtonNamespace.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// ButtonNamespace.swift -// Diary -// -// Created by Maxhyunm, Hamg on 2023/09/10. -// - -enum ButtonNamespace { - static let more = "더보기" - static let cancel = "취소" - static let delete = "삭제" - static let confirm = "확인" - static let deleteEnglish = "Delete" - static let shareEnglish = "Share..." - static let cancelEnglish = "Cancel" -} diff --git a/Diary/Network/NetworkManager.swift b/Diary/Network/NetworkManager.swift index 2e7cf7ad3..e6b631a59 100644 --- a/Diary/Network/NetworkManager.swift +++ b/Diary/Network/NetworkManager.swift @@ -22,7 +22,7 @@ final class NetworkManager { dataTask = URLSession.shared.dataTask(with: url) { data, response, error in if error != nil { - completionHandler(.failure(.requestFail)) + completionHandler(.failure(.requestFailure)) } guard let httpResponse = response as? HTTPURLResponse, (200...299) ~= httpResponse.statusCode else { diff --git a/en.lproj/Localizable.strings b/en.lproj/Localizable.strings index 6151fd7ad..e4474838a 100644 --- a/en.lproj/Localizable.strings +++ b/en.lproj/Localizable.strings @@ -1,6 +1,25 @@ "titleLabel" = "Diary"; "moreOptions" = "More"; -"shareOption" = "Share..."; -"deleteOption" = "Delete"; -"cancelOption" = "Cancel"; +"share" = "Share..."; +"delete" = "Delete"; +"cancel" = "Cancel"; "confirm" = "Confirm"; +"networkError" = "Network Error"; +"deleteTitle" = "Really?"; +"deleteMessage" = "Are you sure you want to delete?"; +"unknownError" = "Unknown Error"; +"unknownErrorTitle" = "Unknown"; +"fileNotFound" = "File Not Found"; +"decodingFailure" = "Decoding Failure"; +"dataNotFoundTitle" = "Error"; +"saveFailureTitle" = "Error"; +"deleteFailureTitle" = "Error"; +"dataNotFound" = "Data Not Found"; +"saveFailure" = "Save Failure"; +"deleteFailure" = "Delete Failure"; +"invalidURL" = "Invalid URL"; +"requestFailure" = "Request Failure"; +"invalidData" = "Invalid Data."; +"dataTransferFailure" = "Data Transfer Failure"; +"invalidHTTPStatusCode" = "Invalide HTTP Status Code"; +"requestTimeOut" = "Request Time Out"; diff --git a/ko.lproj/Localizable.strings b/ko.lproj/Localizable.strings index 8da2a1d42..a98532977 100644 --- a/ko.lproj/Localizable.strings +++ b/ko.lproj/Localizable.strings @@ -1,6 +1,25 @@ "titleLabel" = "일기장"; "moreOptions" = "더보기"; -"shareOption" = "공유하기"; -"deleteOption" = "삭제"; -"cancelOption" = "취소"; +"share" = "공유하기"; +"delete" = "삭제"; +"cancel" = "취소"; "confirm" = "확인"; +"networkError" = "네트워크 오류"; +"deleteTitle" = "진짜요?"; +"deleteMessage" = "정말로 삭제하시겠어요?"; +"unknownError" = "알 수 없는 오류입니다."; +"unknownErrorTitle" = "알 수 없는 오류"; +"fileNotFound" = "파일을 불러오지 못했습니다."; +"decodingFailure" = "파일을 변환하지 못했습니다."; +"dataNotFoundTitle" = "읽기 실패"; +"saveFailureTitle" = "저장 실패"; +"deleteFailureTitle" = "삭제 실패"; +"dataNotFound" = "데이터를 찾지 못했습니다."; +"saveFailure" = "저장에 실패하였습니다."; +"deleteFailure" = "삭제에 실패하였습니다."; +"invalidURL" = "유효하지 않은 URL입니다."; +"requestFailure" = "요청에 실패했습니다."; +"invalidData" = "잘못된 데이터입니다."; +"dataTransferFailure" = "데이터 변환에 실패했습니다."; +"invalidHTTPStatusCode" = "잘못된 HTTP Status Code입니다."; +"requestTimeOut" = "요청시간이 초과되었습니다.";