diff --git a/Project.swift b/Project.swift index 728e20fa..763691f9 100644 --- a/Project.swift +++ b/Project.swift @@ -1,4 +1,5 @@ import ExternalDependencyPlugin +import MicroFeaturePlugin import ProjectDescription import ProjectDescriptionHelpers @@ -17,28 +18,12 @@ func commonTargets() -> [Target] { appendSchemeTo: &schemes ), - // MARK: Utility - - Target.makeCommonFramework( - name: Module.utility, - scripts: [ - // 공동 작업자의 githook path 자동 세팅을 위함 - .pre( - path: "Scripts/set_githooks_path.sh", - name: "Set githooks path", - basedOnDependencyAnalysis: false - ), - ], - hasTests: true, - appendSchemeTo: &schemes - ), - // MARK: Domain Target.makeCommonFramework( name: Module.domain.core, dependencies: [ - .target(name: Module.utility), + .target(utilityFeature.source), .external(name: .foundationPlus), .external(name: .swinject), .external(name: .swinjectExtension), @@ -191,16 +176,16 @@ func commonTargets() -> [Target] { func iOSTargets() -> [Target] { [ Target.target( - name: "\(PROJECT_NAME)UITests", + name: "\(env.projectName)UITests", destinations: [.iPhone], product: .uiTests, - bundleId: "\(BASIC_BUNDLE_ID)UITests", - deploymentTargets: .iOS(MINIMUM_IOS_VERSION), - sources: "Tests/\(PROJECT_NAME)UITests/**", + bundleId: "\(env.baseBundleID)UITests", + deploymentTargets: .iOS(env.minimumIOSVersion), + sources: "Tests/\(env.projectName)UITests/**", dependencies: [ - .target(name: "\(PROJECT_NAME)Dev"), + .target(name: "\(env.projectName)Dev"), .target(name: Module.iOSSupport), - .target(name: Module.utility), + .target(utilityFeature.source), .target(name: Module.testsSupport), ] ), @@ -208,13 +193,13 @@ func iOSTargets() -> [Target] { name: "SnapshotGenerator", destinations: .iOS, product: .uiTests, - bundleId: "\(BASIC_BUNDLE_ID).SnapshotGenerator", - deploymentTargets: .iOS(MINIMUM_IOS_VERSION), + bundleId: "\(env.baseBundleID).SnapshotGenerator", + deploymentTargets: .iOS(env.minimumIOSVersion), sources: "Tests/SnapshotGenerator/**", dependencies: [ - .target(name: "\(PROJECT_NAME)Dev"), + .target(name: "\(env.projectName)Dev"), .target(name: Module.iOSSupport), - .target(name: Module.utility), + .target(utilityFeature.source), .target(name: Module.testsSupport), ] ), @@ -222,8 +207,8 @@ func iOSTargets() -> [Target] { name: "IOSSceneIntegrationTests", destinations: .iOS, product: .unitTests, - bundleId: "\(BASIC_BUNDLE_ID).IOSSceneIntegrationTests", - deploymentTargets: .iOS(MINIMUM_IOS_VERSION), + bundleId: "\(env.baseBundleID).IOSSceneIntegrationTests", + deploymentTargets: .iOS(env.minimumIOSVersion), sources: "Tests/IOSSceneIntegrationTests/**", dependencies: [ .target(name: Module.iOSScene.wordChecking), @@ -241,7 +226,7 @@ func iOSTargets() -> [Target] { Target.makeIOSFramework( name: Module.iOSSupport, dependencies: [ - .target(name: Module.utility), + .target(utilityFeature.source), .target(name: Module.domain.googleDrive), .target(name: Module.domain.localNotification), .target(name: Module.domain.userSettings), @@ -290,7 +275,7 @@ func iOSTargets() -> [Target] { name: "IOSScene_WordCheckingExample", destinations: .iOS, product: .app, - deploymentTargets: .iOS(MINIMUM_IOS_VERSION), + deploymentTargets: .iOS(env.minimumIOSVersion), infoPlist: .file(path: .path(Constant.Path.iOSExampleInfoPlist)), dependencies: [ .target(name: Module.iOSScene.wordChecking), @@ -322,7 +307,7 @@ func iOSTargets() -> [Target] { name: "\(Module.iOSScene.wordList)Example", destinations: .iOS, product: .app, - deploymentTargets: .iOS(MINIMUM_IOS_VERSION), + deploymentTargets: .iOS(env.minimumIOSVersion), infoPlist: .file(path: .path(Constant.Path.iOSExampleInfoPlist)), dependencies: [ .target(name: Module.iOSScene.wordList), @@ -351,7 +336,7 @@ func iOSTargets() -> [Target] { name: "\(Module.iOSScene.wordDetail)Example", destinations: .iOS, product: .app, - deploymentTargets: .iOS(MINIMUM_IOS_VERSION), + deploymentTargets: .iOS(env.minimumIOSVersion), infoPlist: .file(path: .path(Constant.Path.iOSExampleInfoPlist)), dependencies: [ .target(name: Module.iOSScene.wordDetail), @@ -396,7 +381,7 @@ func iOSTargets() -> [Target] { name: "IOSScene_UserSettingsExample", destinations: .iOS, product: .app, - deploymentTargets: .iOS(MINIMUM_IOS_VERSION), + deploymentTargets: .iOS(env.minimumIOSVersion), infoPlist: .file(path: .path(Constant.Path.iOSExampleInfoPlist)), dependencies: [ .target(name: Module.iOSScene.userSettings), @@ -413,7 +398,7 @@ func iOSTargets() -> [Target] { name: "TestingApp", destinations: .iOS, product: .app, - deploymentTargets: .iOS(MINIMUM_IOS_VERSION), + deploymentTargets: .iOS(env.minimumIOSVersion), infoPlist: .file(path: .path(Constant.Path.iOSExampleInfoPlist)), dependencies: [ .target(name: Module.iOSSupport), @@ -427,7 +412,7 @@ func iOSTargets() -> [Target] { name: Module.iOSDriver, destinations: [.iPhone, .iPad], product: .framework, - deploymentTargets: .iOS(MINIMUM_IOS_VERSION), + deploymentTargets: .iOS(env.minimumIOSVersion), dependencies: [ .target(name: Module.container), .target(name: Module.iOSSupport), @@ -443,7 +428,7 @@ func iOSTargets() -> [Target] { name: Module.iPhoneDriver, destinations: [.iPhone], product: .framework, - deploymentTargets: .iOS(MINIMUM_IOS_VERSION), + deploymentTargets: .iOS(env.minimumIOSVersion), dependencies: [ .target(name: Module.container), .target(name: Module.iOSDriver), @@ -455,7 +440,7 @@ func iOSTargets() -> [Target] { name: Module.iPadDriver, destinations: [.iPad], product: .framework, - deploymentTargets: .iOS(MINIMUM_IOS_VERSION), + deploymentTargets: .iOS(env.minimumIOSVersion), dependencies: [ .target(name: Module.container), .target(name: Module.iOSDriver), @@ -464,11 +449,11 @@ func iOSTargets() -> [Target] { appendSchemeTo: &schemes ), Target.makeTargets( - name: PROJECT_NAME, + name: env.projectName, destinations: [.iPhone, .iPad], product: .app, - bundleID: BASIC_BUNDLE_ID, - deploymentTargets: .iOS(MINIMUM_IOS_VERSION), + bundleID: env.baseBundleID, + deploymentTargets: .iOS(env.minimumIOSVersion), infoPlist: .file(path: .path(Constant.Path.iOSInfoPlist)), dependencies: [ .target(name: Module.iPhoneDriver), @@ -489,11 +474,11 @@ func iOSTargets() -> [Target] { appendSchemeTo: &schemes ), Target.makeTargets( - name: "\(PROJECT_NAME)Dev", + name: "\(env.projectName)Dev", destinations: [.iPhone, .iPad], product: .app, - bundleID: "\(BASIC_BUNDLE_ID)Dev", - deploymentTargets: .iOS(MINIMUM_IOS_VERSION), + bundleID: "\(env.baseBundleID)Dev", + deploymentTargets: .iOS(env.minimumIOSVersion), infoPlist: .file(path: .path(Constant.Path.iOSInfoPlist)), dependencies: [ .target(name: Module.iPhoneDriver), @@ -518,11 +503,11 @@ func iOSTargets() -> [Target] { } let macAppTargets = Target.makeTargets( - name: "\(PROJECT_NAME)Mac", + name: "\(env.projectName)Mac", destinations: [.mac], product: .app, - bundleID: "\(BASIC_BUNDLE_ID)Mac", - deploymentTargets: .macOS(MINIMUM_MACOS_VERSION), + bundleID: "\(env.baseBundleID)Mac", + deploymentTargets: .macOS(env.minimumMacOSVersion), infoPlist: .file(path: .path(Constant.Path.macInfoPlist)), entitlements: .file(path: .path(Constant.Path.macEntitlements)), dependencies: [ @@ -549,13 +534,14 @@ let allTargets: [Target] = [ macAppTargets ] .flatMap { $0 } ++ utilityFeature.resolveModules() // MARK: - Project let project: Project = .init( - name: PROJECT_NAME, - organizationName: ORGANIZATION, - options: .options(automaticSchemesOptions: .disabled), + name: env.projectName, + organizationName: env.organization, + options: .options(), packages: [ .package(url: "https://github.com/google/google-api-objectivec-client-for-rest.git", .exact("3.5.4")), .package(url: "https://github.com/google/GoogleSignIn-iOS.git", .exact("6.2.4")), @@ -571,32 +557,32 @@ let project: Project = .init( targets: allTargets, schemes: schemes + [ .scheme( - name: PROJECT_NAME, - buildAction: .buildAction(targets: ["\(PROJECT_NAME)"]), + name: env.projectName, + buildAction: .buildAction(targets: ["\(env.projectName)"]), runAction: .runAction( configuration: .release, attachDebugger: false, - executable: "\(PROJECT_NAME)" + executable: "\(env.projectName)" ), - profileAction: .profileAction(executable: "\(PROJECT_NAME)") + profileAction: .profileAction(executable: "\(env.projectName)") ), .scheme( - name: "\(PROJECT_NAME)Dev", - runAction: .runAction(executable: "\(PROJECT_NAME)Dev") + name: "\(env.projectName)Dev", + runAction: .runAction(executable: "\(env.projectName)Dev") ), .scheme( - name: "\(PROJECT_NAME)Dev_InMemoryDB", + name: "\(env.projectName)Dev_InMemoryDB", runAction: .runAction( - executable: "\(PROJECT_NAME)Dev", + executable: "\(env.projectName)Dev", arguments: .arguments(launchArguments: [ .launchArgument(name: "-useInMemoryDatabase", isEnabled: true) ]) ) ), .scheme( - name: "\(PROJECT_NAME)Dev_SampleDB", + name: "\(env.projectName)Dev_SampleDB", runAction: .runAction( - executable: "\(PROJECT_NAME)Dev", + executable: "\(env.projectName)Dev", arguments: .arguments(launchArguments: [ .launchArgument(name: "-sampledDatabase", isEnabled: true) ]) diff --git a/README.md b/README.md index d4030541..aec9fc1a 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,13 @@ Add frequently forgotten words and memorize them! https://apps.apple.com/kr/app/id6465133881 + +## Screenshots + + + + + + + +![iPad Pro (12 9-inch) (4th generation)-02-quick-add_framed](https://github.com/user-attachments/assets/cd2b1bb2-3848-4bf9-a28d-420051eb126e) diff --git a/Resources/IOSScene/WordList/Localizable.xcstrings b/Resources/IOSScene/WordList/Localizable.xcstrings index 222df14d..6520be49 100644 --- a/Resources/IOSScene/WordList/Localizable.xcstrings +++ b/Resources/IOSScene/WordList/Localizable.xcstrings @@ -101,6 +101,22 @@ } } }, + "edit_list" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Edit list" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "목록 수정" + } + } + } + }, "editWord" : { "localizations" : { "en" : { diff --git a/Sources/Domain/GoogleDrive/Service/DefaultGoogleDriveService.swift b/Sources/Domain/GoogleDrive/Service/DefaultGoogleDriveService.swift index 79c0f183..0345ae95 100644 --- a/Sources/Domain/GoogleDrive/Service/DefaultGoogleDriveService.swift +++ b/Sources/Domain/GoogleDrive/Service/DefaultGoogleDriveService.swift @@ -10,7 +10,7 @@ import GoogleAPIClientForRESTCore import GoogleAPIClientForREST_Drive import RxSwift import RxSwiftSugar -import Utility +import UtilitySource public final class DefaultGoogleDriveService: GoogleDriveService { @@ -154,7 +154,8 @@ public final class DefaultGoogleDriveService: GoogleDriveService { } return .create { observer in - Task { + let task = Task { + try Task.checkCancellation() let backupFileList = try await self.fetchBackupFileList(backupFileName: backupFileName.rawValue) guard let backupFileID = backupFileList.files?.first?.identifier else { @@ -162,14 +163,18 @@ public final class DefaultGoogleDriveService: GoogleDriveService { return } - let dataObject = try await GoogleDriveAPI(authentication: currentUser.authentication).files.get(forFileID: backupFileID) + try Task.checkCancellation() + let api = GoogleDriveAPI(authentication: currentUser.authentication) + let dataObject = try await api.files.get(forFileID: backupFileID) observer(.success(BackupFile(name: backupFileName, data: dataObject.data))) } catch: { observer(.failure($0)) } - return Disposables.create() + return Disposables.create { + task.cancel() + } } } @@ -179,7 +184,8 @@ public final class DefaultGoogleDriveService: GoogleDriveService { } return .create { observer in - Task { + let task = Task { + try Task.checkCancellation() let backupFileList = try await self.fetchBackupFileList(backupFileName: backupFileName.rawValue) guard let backupFiles = backupFileList.files else { @@ -187,9 +193,11 @@ public final class DefaultGoogleDriveService: GoogleDriveService { return } + try Task.checkCancellation() + let api = GoogleDriveAPI(authentication: currentUser.authentication) try await backupFiles.compactMap(\.identifier) .asyncForEach { - try await GoogleDriveAPI(authentication: currentUser.authentication).files.delete(byFileID: $0) + try await api.files.delete(byFileID: $0) } observer(.success(())) @@ -197,7 +205,9 @@ public final class DefaultGoogleDriveService: GoogleDriveService { observer(.failure($0)) } - return Disposables.create() + return Disposables.create { + task.cancel() + } } } } diff --git a/Sources/Domain/UserSettings/DI/Public/DomainUserSettingsAssemblyDev.swift b/Sources/Domain/UserSettings/DI/Public/DomainUserSettingsAssemblyDev.swift index 054d3cf8..7938d606 100644 --- a/Sources/Domain/UserSettings/DI/Public/DomainUserSettingsAssemblyDev.swift +++ b/Sources/Domain/UserSettings/DI/Public/DomainUserSettingsAssemblyDev.swift @@ -9,7 +9,7 @@ import ExtendedUserDefaults import Foundation import Swinject -import Utility +import UtilitySource public final class DomainUserSettingsAssemblyDev: Assembly { diff --git a/Sources/Domain/UserSettings/Service/UserDefaultsUserSettingsService.swift b/Sources/Domain/UserSettings/Service/UserDefaultsUserSettingsService.swift index 3bee528f..9306709f 100644 --- a/Sources/Domain/UserSettings/Service/UserDefaultsUserSettingsService.swift +++ b/Sources/Domain/UserSettings/Service/UserDefaultsUserSettingsService.swift @@ -1,6 +1,6 @@ import ExtendedUserDefaults import Foundation -import Utility +import UtilitySource public protocol UserSettingsService { func saveUserSettings(_ userSettings: UserSettings) throws diff --git a/Sources/Domain/WordManagement/DI/WordRepositoryAssemblyDev.swift b/Sources/Domain/WordManagement/DI/WordRepositoryAssemblyDev.swift index a7f3fb36..4c3e2830 100644 --- a/Sources/Domain/WordManagement/DI/WordRepositoryAssemblyDev.swift +++ b/Sources/Domain/WordManagement/DI/WordRepositoryAssemblyDev.swift @@ -9,7 +9,7 @@ import Foundation import RealmSwift import Swinject -import Utility +import UtilitySource internal final class WordRepositoryAssemblyDev: Assembly { diff --git a/Sources/Domain/WordManagement/Service/UnmemorizedWordListRepositoryImpl.swift b/Sources/Domain/WordManagement/Service/UnmemorizedWordListRepositoryImpl.swift index 18367852..d454782c 100644 --- a/Sources/Domain/WordManagement/Service/UnmemorizedWordListRepositoryImpl.swift +++ b/Sources/Domain/WordManagement/Service/UnmemorizedWordListRepositoryImpl.swift @@ -6,7 +6,7 @@ // import Foundation -import Utility +import UtilitySource @available(*, deprecated) final class UnmemorizedWordListRepository: UnmemorizedWordListRepositoryProtocol { diff --git a/Sources/IOSDriver/CommonAppDelegate.swift b/Sources/IOSDriver/CommonAppDelegate.swift index 50fa5949..7dfcb0d8 100644 --- a/Sources/IOSDriver/CommonAppDelegate.swift +++ b/Sources/IOSDriver/CommonAppDelegate.swift @@ -9,7 +9,7 @@ import IOSSupport import RxSwift import Swinject import UIKit -import Utility +import UtilitySource // Domain import Domain_GoogleDrive diff --git a/Sources/IOSDriver/CommonSceneDelegate.swift b/Sources/IOSDriver/CommonSceneDelegate.swift index 3bcbe5d8..34af80ee 100644 --- a/Sources/IOSDriver/CommonSceneDelegate.swift +++ b/Sources/IOSDriver/CommonSceneDelegate.swift @@ -1,7 +1,7 @@ import IOSSupport import RxSwift import UIKit -import Utility +import UtilitySource open class CommonSceneDelegate: UIResponder, UIWindowSceneDelegate { diff --git a/Sources/IOSScene/WordChecking/WordCheckingReactor.swift b/Sources/IOSScene/WordChecking/WordCheckingReactor.swift index c926b89a..5cc57447 100644 --- a/Sources/IOSScene/WordChecking/WordCheckingReactor.swift +++ b/Sources/IOSScene/WordChecking/WordCheckingReactor.swift @@ -205,7 +205,6 @@ final class WordCheckingReactor: Reactor { ]) }, globalAction.didDeleteWords - .filter { $0.contains(where: { $0.uuid == self.currentState.currentWord?.id }) } .flatMap { _ -> Observable in let currentWord = self.wordUseCase.getCurrentUnmemorizedWord() let totalCount = self.wordUseCase.fetchMemorizingWordList().count diff --git a/Sources/IOSScene/WordChecking/WordCheckingViewController.swift b/Sources/IOSScene/WordChecking/WordCheckingViewController.swift index f7fc8d9e..2890e015 100644 --- a/Sources/IOSScene/WordChecking/WordCheckingViewController.swift +++ b/Sources/IOSScene/WordChecking/WordCheckingViewController.swift @@ -15,7 +15,7 @@ import Then import Toast import UIKit import UIKitPlus -import Utility +import UtilitySource import WebKit public protocol WordCheckingViewControllerProtocol: UIViewController {} diff --git a/Sources/IOSScene/WordCheckingExample/AppDelegate.swift b/Sources/IOSScene/WordCheckingExample/AppDelegate.swift index 1aa0b599..5c4f6442 100644 --- a/Sources/IOSScene/WordCheckingExample/AppDelegate.swift +++ b/Sources/IOSScene/WordCheckingExample/AppDelegate.swift @@ -6,7 +6,7 @@ // import UIKit -import Utility +import UtilitySource @main class AppDelegate: UIResponder, UIApplicationDelegate { diff --git a/Sources/IOSScene/WordDetail/WordDetailViewController.swift b/Sources/IOSScene/WordDetail/WordDetailViewController.swift index 77097779..cbd8fb84 100644 --- a/Sources/IOSScene/WordDetail/WordDetailViewController.swift +++ b/Sources/IOSScene/WordDetail/WordDetailViewController.swift @@ -9,7 +9,7 @@ import IOSSupport import ReactorKit import RxCocoa import UIKit -import Utility +import UtilitySource public protocol WordDetailViewControllerDelegate: AnyObject, ViewControllerDelegate { } diff --git a/Sources/IOSScene/WordList/Common/LocalizedString.swift b/Sources/IOSScene/WordList/Common/LocalizedString.swift index d31ceb56..6723523b 100644 --- a/Sources/IOSScene/WordList/Common/LocalizedString.swift +++ b/Sources/IOSScene/WordList/Common/LocalizedString.swift @@ -21,4 +21,5 @@ internal struct LocalizedString { static let edit = NSLocalizedString("edit", bundle: Bundle.module, comment: "") static let editWord = NSLocalizedString("editWord", bundle: Bundle.module, comment: "") static let cancel = NSLocalizedString("cancel", bundle: Bundle.module, comment: "") + static let edit_list = NSLocalizedString("edit_list", bundle: Bundle.module, comment: "") } diff --git a/Sources/IOSScene/WordList/WordListNavigationItem.swift b/Sources/IOSScene/WordList/WordListNavigationItem.swift index cd3d5506..df7f20fa 100644 --- a/Sources/IOSScene/WordList/WordListNavigationItem.swift +++ b/Sources/IOSScene/WordList/WordListNavigationItem.swift @@ -30,7 +30,9 @@ final class WordListNavigationItem: UINavigationItem { ]) } - let editButton = UIBarButtonItem(systemItem: .edit) + let editButton = UIBarButtonItem(systemItem: .edit).then { + $0.accessibilityLabel = LocalizedString.edit_list + } let cancelButton = UIBarButtonItem(systemItem: .cancel) private lazy var filterWordsGroup = UIDeferredMenuElement.uncached { [weak self] completion in diff --git a/Sources/IOSSupport/Foundations/BaseView.swift b/Sources/IOSSupport/Foundations/BaseView.swift index 611dc75b..728bfcfd 100644 --- a/Sources/IOSSupport/Foundations/BaseView.swift +++ b/Sources/IOSSupport/Foundations/BaseView.swift @@ -7,7 +7,7 @@ // import UIKit -import Utility +import UtilitySource open class BaseView: UIView { diff --git a/Sources/IOSSupport/Foundations/BasicCoordinator.swift b/Sources/IOSSupport/Foundations/BasicCoordinator.swift index a76b90fe..8b4e4e10 100644 --- a/Sources/IOSSupport/Foundations/BasicCoordinator.swift +++ b/Sources/IOSSupport/Foundations/BasicCoordinator.swift @@ -7,7 +7,7 @@ // import UIKit -import Utility +import UtilitySource /// iOS 환경에서 동작하는 Coordinator 를 위한 Abstract 클래스 /// diff --git a/Sources/IOSSupport/Foundations/Coordinator.swift b/Sources/IOSSupport/Foundations/Coordinator.swift index 9c7f9d4c..54b79918 100644 --- a/Sources/IOSSupport/Foundations/Coordinator.swift +++ b/Sources/IOSSupport/Foundations/Coordinator.swift @@ -6,7 +6,7 @@ // import Foundation -import Utility +import UtilitySource public protocol Coordinator: AnyObject { diff --git a/Sources/TestsSupport/UITests/XCUIApplication+launchEnvironment.swift b/Sources/TestsSupport/UITests/XCUIApplication+launchEnvironment.swift index f2edd134..1fc3dc9f 100644 --- a/Sources/TestsSupport/UITests/XCUIApplication+launchEnvironment.swift +++ b/Sources/TestsSupport/UITests/XCUIApplication+launchEnvironment.swift @@ -6,7 +6,7 @@ // import Foundation -import Utility +import UtilitySource import XCTest extension XCUIApplication { diff --git a/Sources/UseCase/UserSettings/DefaultUserSettingsUseCase.swift b/Sources/UseCase/UserSettings/DefaultUserSettingsUseCase.swift index 43b8d258..ef29eb0a 100644 --- a/Sources/UseCase/UserSettings/DefaultUserSettingsUseCase.swift +++ b/Sources/UseCase/UserSettings/DefaultUserSettingsUseCase.swift @@ -11,7 +11,7 @@ import Foundation import RxSwift import RxRelay import RxSwiftSugar -import Utility +import UtilitySource internal final class DefaultUserSettingsUseCase: UserSettingsUseCase { diff --git a/Sources/Utility/CircularLinkedList.swift b/Sources/Utility/Source/CircularLinkedList.swift similarity index 100% rename from Sources/Utility/CircularLinkedList.swift rename to Sources/Utility/Source/CircularLinkedList.swift diff --git a/Sources/Utility/LaunchArgument.swift b/Sources/Utility/Source/LaunchArgument.swift similarity index 100% rename from Sources/Utility/LaunchArgument.swift rename to Sources/Utility/Source/LaunchArgument.swift diff --git a/Sources/Utility/NetworkMonitor.swift b/Sources/Utility/Source/NetworkMonitor.swift similarity index 100% rename from Sources/Utility/NetworkMonitor.swift rename to Sources/Utility/Source/NetworkMonitor.swift diff --git a/Sources/Utility/Utility.h b/Sources/Utility/Source/Utility.h similarity index 100% rename from Sources/Utility/Utility.h rename to Sources/Utility/Source/Utility.h diff --git a/Sources/Utility/Utility.swift b/Sources/Utility/Source/Utility.swift similarity index 100% rename from Sources/Utility/Utility.swift rename to Sources/Utility/Source/Utility.swift diff --git a/Sources/Utility/UtilityError.swift b/Sources/Utility/Source/UtilityError.swift similarity index 100% rename from Sources/Utility/UtilityError.swift rename to Sources/Utility/Source/UtilityError.swift diff --git a/Tests/UtilityTests/CircularLinkedListTests.swift b/Sources/Utility/Tests/UnitTests/CircularLinkedListTests.swift similarity index 98% rename from Tests/UtilityTests/CircularLinkedListTests.swift rename to Sources/Utility/Tests/UnitTests/CircularLinkedListTests.swift index 2ca951f4..2c0b4c60 100644 --- a/Tests/UtilityTests/CircularLinkedListTests.swift +++ b/Sources/Utility/Tests/UnitTests/CircularLinkedListTests.swift @@ -5,7 +5,7 @@ // Created by Jaewon Yun on 2023/09/10. // -@testable import Utility +@testable import UtilitySource import XCTest final class CircularLinkedListTests: XCTestCase { diff --git a/Tests/UtilityTests/UtilityUnitTests.swift b/Sources/Utility/Tests/UnitTests/UtilityUnitTests.swift similarity index 94% rename from Tests/UtilityTests/UtilityUnitTests.swift rename to Sources/Utility/Tests/UnitTests/UtilityUnitTests.swift index 8fcdebdf..c48fff74 100644 --- a/Tests/UtilityTests/UtilityUnitTests.swift +++ b/Sources/Utility/Tests/UnitTests/UtilityUnitTests.swift @@ -5,7 +5,7 @@ // Created by Jaewon Yun on 2023/09/07. // -import Utility +import UtilitySource import XCTest final class UtilityUnitTests: XCTestCase { diff --git a/Sources/WordChecker/ReleaseConfig.xcconfig b/Sources/WordChecker/ReleaseConfig.xcconfig index 8d20da54..10d38cde 100644 --- a/Sources/WordChecker/ReleaseConfig.xcconfig +++ b/Sources/WordChecker/ReleaseConfig.xcconfig @@ -1,2 +1,2 @@ -APP_VERSION = 2.0.0 -APP_BUILD_NUMBER = 6 +APP_VERSION = 2.0.1 +APP_BUILD_NUMBER = 1 diff --git a/TestPlans/IntegrationTests.xctestplan b/TestPlans/IntegrationTests.xctestplan index 93bd54a2..83343c09 100644 --- a/TestPlans/IntegrationTests.xctestplan +++ b/TestPlans/IntegrationTests.xctestplan @@ -147,13 +147,6 @@ "name" : "WordCheckerUITests" } }, - { - "target" : { - "containerPath" : "container:WordChecker.xcodeproj", - "identifier" : "585092990423BB1A0834B60A", - "name" : "UtilityTests" - } - }, { "target" : { "containerPath" : "container:WordChecker.xcodeproj", @@ -244,6 +237,13 @@ "identifier" : "FEB2EA1DFBE61874EF1A8640", "name" : "IOSSceneIntegrationTests" } + }, + { + "target" : { + "containerPath" : "container:WordChecker.xcodeproj", + "identifier" : "B4760D68D950DD960933E277", + "name" : "UtilityUnitTests" + } } ], "version" : 1 diff --git a/TestPlans/Utility.xctestplan b/TestPlans/Utility.xctestplan deleted file mode 100644 index 0977cc9e..00000000 --- a/TestPlans/Utility.xctestplan +++ /dev/null @@ -1,24 +0,0 @@ -{ - "configurations" : [ - { - "id" : "19E7DB7D-10BA-4431-9064-714FFE448D98", - "name" : "Test Scheme Action", - "options" : { - - } - } - ], - "defaultOptions" : { - "codeCoverage" : false - }, - "testTargets" : [ - { - "target" : { - "containerPath" : "container:WordChecker.xcodeproj", - "identifier" : "585092990423BB1A0834B60A", - "name" : "UtilityTests" - } - } - ], - "version" : 1 -} diff --git a/Tests/WordCheckerUITests/WordCheckerUITests.swift b/Tests/WordCheckerUITests/WordCheckerUITests.swift index c8ed185d..1add3d5b 100644 --- a/Tests/WordCheckerUITests/WordCheckerUITests.swift +++ b/Tests/WordCheckerUITests/WordCheckerUITests.swift @@ -13,7 +13,7 @@ @testable import IOSSupport @testable import IPhoneDriver import TestsSupport -import Utility +import UtilitySource import XCTest typealias WordCheckingString = IOSScene_WordChecking.LocalizedString diff --git a/Tuist/Config.swift b/Tuist/Config.swift index be48ffc5..cd961768 100644 --- a/Tuist/Config.swift +++ b/Tuist/Config.swift @@ -3,5 +3,6 @@ import ProjectDescription let config = Config( plugins: [ .git(url: "https://github.com/Woin2ee-Modules/tuist-external-dependency-plugin.git", tag: "1.0.1"), + .git(url: "https://github.com/Woin2ee-Modules/tuist-micro-feature-plugin.git", tag: "0.4.0"), ] ) diff --git a/Tuist/ProjectDescriptionHelpers/Configurations.swift b/Tuist/ProjectDescriptionHelpers/Configurations.swift deleted file mode 100644 index 8b157f02..00000000 --- a/Tuist/ProjectDescriptionHelpers/Configurations.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// Configurations.swift -// ProjectDescriptionHelpers -// -// Created by Jaewon Yun on 2023/09/12. -// - -import Foundation -import ProjectDescription - -// MARK: - Configurations - -public let ORGANIZATION = "woin2ee" - -public let PROJECT_NAME = "WordChecker" - -public let BASIC_BUNDLE_ID = "com.\(ORGANIZATION).\(PROJECT_NAME)" - -public let MINIMUM_IOS_VERSION = "17.0" - -public let MINIMUM_MACOS_VERSION = "14.0.0" - -public let ALL_DEPLOYMENT_TARGETS: DeploymentTargets = .multiplatform( - iOS: MINIMUM_IOS_VERSION, - macOS: MINIMUM_MACOS_VERSION -) - -public let ALL_DESTINATIONS: Destinations = [.iPhone, .iPad, .mac] diff --git a/Tuist/ProjectDescriptionHelpers/Environment.swift b/Tuist/ProjectDescriptionHelpers/Environment.swift new file mode 100644 index 00000000..4e144aa9 --- /dev/null +++ b/Tuist/ProjectDescriptionHelpers/Environment.swift @@ -0,0 +1,17 @@ +import Foundation +import ProjectDescription + +public struct WordCheckerEnvironment { + public let organization = "woin2ee" + public let projectName = "WordChecker" + public let baseBundleID = "com.woin2ee.WordChecker" + public let minimumIOSVersion = "17.0" + public let minimumMacOSVersion = "14.0.0" + public private(set) lazy var allDeploymentTargets = DeploymentTargets.multiplatform( + iOS: minimumIOSVersion, + macOS: minimumMacOSVersion + ) + public let allDestinations = Destinations([.iPhone, .iPad, .mac]) +} + +public var env = WordCheckerEnvironment() diff --git a/Tuist/ProjectDescriptionHelpers/Features/Utility.swift b/Tuist/ProjectDescriptionHelpers/Features/Utility.swift new file mode 100644 index 00000000..4f4580f3 --- /dev/null +++ b/Tuist/ProjectDescriptionHelpers/Features/Utility.swift @@ -0,0 +1,20 @@ +import ExternalDependencyPlugin +import MicroFeaturePlugin +import ProjectDescription + +public let utilityFeature = FeatureManifest( + baseName: "Utility", + baseBundleID: env.baseBundleID, + destinations: env.allDestinations, + sourceProduct: .framework, + deploymentTargets: env.allDeploymentTargets, + scripts: [ + // 공동 작업자의 githook path 자동 세팅을 위함 + .pre( + path: "Scripts/set_githooks_path.sh", + name: "Set githooks path", + basedOnDependencyAnalysis: false + ), + ], + adoptedModules: [.source, .unitTests] +) diff --git a/Tuist/ProjectDescriptionHelpers/Target+.swift b/Tuist/ProjectDescriptionHelpers/Target+.swift index de7d559f..c8941d9c 100644 --- a/Tuist/ProjectDescriptionHelpers/Target+.swift +++ b/Tuist/ProjectDescriptionHelpers/Target+.swift @@ -53,7 +53,7 @@ fileprivate func _module( nameSuffix = nameComponents[1] } - let bundleID = bundleID ?? "\(BASIC_BUNDLE_ID).\(name.replacing("_", with: "."))" + let bundleID = bundleID ?? "\(env.baseBundleID).\(name.replacing("_", with: "."))" let resourceFileElements = resourceOptions .reduce(into: [ResourceFileElement](), { partialResult, option in @@ -131,7 +131,7 @@ fileprivate func _module( } else { "Tests/\(testsTargetName)/**" } - let testBundleID = "\(BASIC_BUNDLE_ID).\(testsTargetName.replacing("_", with: "."))" + let testBundleID = "\(env.baseBundleID).\(testsTargetName.replacing("_", with: "."))" let testsTarget: Target = .target( name: testsTargetName, @@ -168,7 +168,7 @@ fileprivate func _module( } else { "Sources/\(testingTargetName)/**" } - let testingBundleID = "\(BASIC_BUNDLE_ID).\(testingTargetName.replacing("_", with: "."))" + let testingBundleID = "\(env.baseBundleID).\(testingTargetName.replacing("_", with: "."))" let testingTarget: Target = .target( name: testingTargetName, @@ -257,10 +257,10 @@ extension Target { ) -> [Target] { return _module( name: name, - destinations: ALL_DESTINATIONS, + destinations: env.allDestinations, product: .framework, bundleID: nil, - deploymentTargets: ALL_DEPLOYMENT_TARGETS, + deploymentTargets: env.allDeploymentTargets, infoPlist: .default, scripts: scripts, dependencies: dependencies, @@ -293,7 +293,7 @@ extension Target { destinations: .iOS, product: .framework, bundleID: nil, - deploymentTargets: .iOS(MINIMUM_IOS_VERSION), + deploymentTargets: .iOS(env.minimumIOSVersion), infoPlist: .default, scripts: scripts, dependencies: dependencies,