Skip to content

Commit 3898e07

Browse files
committed
Merge branch 'release/1.5.0'
2 parents 75302da + 5c29423 commit 3898e07

File tree

111 files changed

+1765
-874
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+1765
-874
lines changed

.package.resolved

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
"kind" : "remoteSourceControl",
1515
"location" : "https://github.com/google/google-api-objectivec-client-for-rest.git",
1616
"state" : {
17-
"revision" : "40930b2c3add6234b8be1a780c08cf88b6a7a1f7",
18-
"version" : "3.2.0"
17+
"revision" : "bcb0439b37d16d39da6f62139d4009d09e7aef14",
18+
"version" : "3.4.0"
1919
}
2020
},
2121
{
@@ -50,17 +50,17 @@
5050
"kind" : "remoteSourceControl",
5151
"location" : "https://github.com/realm/realm-core.git",
5252
"state" : {
53-
"revision" : "c569bec4d04da84030d94f376437bc4efda3686b",
54-
"version" : "13.23.1"
53+
"revision" : "a5e87a39cffdcc591f3203c11cfca68100d0b9a6",
54+
"version" : "13.26.0"
5555
}
5656
},
5757
{
5858
"identity" : "realm-swift",
5959
"kind" : "remoteSourceControl",
6060
"location" : "https://github.com/realm/realm-swift.git",
6161
"state" : {
62-
"revision" : "fd199ce07edb4db69e862f74151b95602aad3b43",
63-
"version" : "10.44.0"
62+
"revision" : "eafdd3720a8cc750bdd38bf776082d2c8cf743fc",
63+
"version" : "10.46.0"
6464
}
6565
}
6666
],

Changelog/1.5.0.md

Lines changed: 3 additions & 0 deletions

Project.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,26 @@ func targets() -> [Target] {
313313
],
314314
appendSchemeTo: &schemes
315315
)
316+
+ Target.module(
317+
name: "GeneralSettings",
318+
sourcesPrefix: "iOSScenes",
319+
resourceOptions: [.additional("Resources/iOSSupport/**")],
320+
dependencies: [
321+
.target(name: "iOSSupport"),
322+
.external(name: ExternalDependencyName.rxSwift),
323+
.external(name: ExternalDependencyName.rxCocoa),
324+
.external(name: ExternalDependencyName.rxUtilityDynamic),
325+
.external(name: ExternalDependencyName.reactorKit),
326+
.external(name: ExternalDependencyName.swinject),
327+
.external(name: ExternalDependencyName.swinjectExtension),
328+
],
329+
hasTests: true,
330+
additionalTestDependencies: [
331+
.target(name: "DomainTesting"),
332+
.external(name: ExternalDependencyName.rxBlocking),
333+
],
334+
appendSchemeTo: &schemes
335+
)
316336
+ Target.module(
317337
name: "iPhoneDriver",
318338
dependencies: [
@@ -324,6 +344,7 @@ func targets() -> [Target] {
324344
.target(name: "UserSettings"),
325345
.target(name: "LanguageSetting"),
326346
.target(name: "PushNotificationSettings"),
347+
.target(name: "GeneralSettings"),
327348
.external(name: ExternalDependencyName.swinject),
328349
.external(name: ExternalDependencyName.swinjectDIContainer),
329350
.external(name: ExternalDependencyName.sfSafeSymbols),

QA.md

Lines changed: 2 additions & 1 deletion

Resources/iOSSupport/Localization/en.lproj/Localizable.strings

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,8 @@ time = "Time";
6262
notifications = "Notifications";
6363
allow_notifications_is_required = "Allow notifications is required.";
6464
dailyReminderFooter = "Sends a daily push notification at the time you set.";
65+
66+
general = "General";
67+
haptics = "Haptics";
68+
hapticsSettingsFooterTextWhenHapticsIsOn = "Enable haptics for interactions.";
69+
hapticsSettingsFooterTextWhenHapticsIsOff = "Disable haptics for interactions";

Resources/iOSSupport/Localization/ko.lproj/Localizable.strings

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,8 @@ time = "시간";
6262
notifications = "알림";
6363
allow_notifications_is_required = "알림 허용이 필요합니다.";
6464
dailyReminderFooter = "설정한 시각에 매일 푸시 알림을 보냅니다.";
65+
66+
general = "일반";
67+
haptics = "진동";
68+
hapticsSettingsFooterTextWhenHapticsIsOn = "상호 작용에 대한 진동을 사용합니다.";
69+
hapticsSettingsFooterTextWhenHapticsIsOff = "상호 작용에 대한 진동을 사용하지 않습니다.";

Sources/DataDriver/UserDefaults/DomainImplement/UserSettingsRepository.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,24 @@ final class UserSettingsRepository: UserSettingsRepositoryProtocol {
3030
userDefaults.rx.setCodable(
3131
userSettings.translationTargetLocale,
3232
forKey: UserDefaultsKey.translationTargetLocale
33-
)
33+
),
34+
userDefaults.rx.setValue(userSettings.hapticsIsOn, forKey: UserDefaultsKey.hapticsIsOn)
3435
)
3536
.mapToVoid()
3637
}
3738

3839
func getUserSettings() -> RxSwift.Single<Domain.UserSettings> {
3940
return Single.zip(
4041
userDefaults.rx.object(TranslationLanguage.self, forKey: UserDefaultsKey.translationSourceLocale),
41-
userDefaults.rx.object(TranslationLanguage.self, forKey: UserDefaultsKey.translationTargetLocale)
42+
userDefaults.rx.object(TranslationLanguage.self, forKey: UserDefaultsKey.translationTargetLocale),
43+
userDefaults.rx.bool(forKey: UserDefaultsKey.hapticsIsOn)
4244
)
43-
.map { sourceLocale, targetLocale -> Domain.UserSettings in
44-
return .init(translationSourceLocale: sourceLocale, translationTargetLocale: targetLocale)
45+
.map { sourceLocale, targetLocale, hapticsIsOn -> Domain.UserSettings in
46+
return .init(
47+
translationSourceLocale: sourceLocale,
48+
translationTargetLocale: targetLocale,
49+
hapticsIsOn: hapticsIsOn
50+
)
4551
}
4652
}
4753

Sources/DataDriver/UserDefaults/UserDefaultsKey.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ enum UserDefaultsKey: UserDefaultsKeyProtocol, CaseIterable {
1717

1818
case dailyReminderTime
1919

20+
case hapticsIsOn
21+
2022
/// 테스트용 Key 입니다.
2123
case test
2224

Sources/Domain/DI/DomainAssembly.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ public final class DomainAssembly: Assembly {
1515
public func assemble(container: Container) {
1616
let assemblies: [Assembly] = [
1717
WordUseCaseAssembly(),
18-
WordRxUseCaseAssembly(),
1918
UserSettingsUseCaseAssembly(),
2019
ExternalStoreUseCaseAssembly(),
20+
NotificationsUseCaseAssembly(),
2121
]
2222

2323
assemblies.forEach { assembly in

Sources/Domain/DI/ExternalStoreUseCaseAssembly.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ final class ExternalStoreUseCaseAssembly: Assembly {
2121
wordRepository: wordRepository,
2222
googleDriveRepository: googleDriveRepository,
2323
unmemorizedWordListRepository: unmemorizedWordListRepository,
24-
userSettingsUseCase: resolver.resolve()
24+
notificationsUseCase: resolver.resolve()
2525
)
2626
}
2727
.inObjectScope(.container)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// NotificationsUseCaseAssembly.swift
3+
// Domain
4+
//
5+
// Created by Jaewon Yun on 1/24/24.
6+
// Copyright © 2024 woin2ee. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import Swinject
11+
import SwinjectExtension
12+
import UserNotifications
13+
14+
final class NotificationsUseCaseAssembly: Assembly {
15+
16+
func assemble(container: Container) {
17+
container.register(NotificationsUseCaseProtocol.self) { resolver in
18+
return NotificationsUseCase.init(
19+
notificationRepository: UNUserNotificationCenter.current(),
20+
wordRepository: resolver.resolve(),
21+
userSettingsRepository: resolver.resolve()
22+
)
23+
}
24+
.inObjectScope(.container)
25+
}
26+
27+
}

Sources/Domain/DI/UserSettingsUseCaseAssembly.swift

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,12 @@
88

99
import Swinject
1010
import SwinjectExtension
11-
import UserNotifications
1211

1312
final class UserSettingsUseCaseAssembly: Assembly {
1413

1514
func assemble(container: Container) {
1615
container.register(UserSettingsUseCaseProtocol.self) { resolver in
17-
let userSettingsRepository: UserSettingsRepositoryProtocol = resolver.resolve()
18-
19-
return UserSettingsUseCase.init(
20-
userSettingsRepository: userSettingsRepository,
21-
notificationRepository: UNUserNotificationCenter.current(),
22-
wordRepository: resolver.resolve()
23-
)
16+
return UserSettingsUseCase.init(userSettingsRepository: resolver.resolve())
2417
}
2518
.inObjectScope(.container)
2619
}

Sources/Domain/DI/WordRxUseCaseAssembly.swift

Lines changed: 0 additions & 24 deletions
This file was deleted.

Sources/Domain/DI/WordUseCaseAssembly.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ final class WordUseCaseAssembly: Assembly {
1919
return WordUseCase.init(
2020
wordRepository: wordRepository,
2121
unmemorizedWordListRepository: unmemorizedWordListRepository,
22-
userSettingsUseCase: resolver.resolve()
22+
notificationsUseCase: resolver.resolve()
2323
)
2424
}
2525
.inObjectScope(.container)

Sources/Domain/Interfaces/UseCases/ExternalStoreUseCaseProtocol.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,23 @@ import RxSwift
1111

1212
public protocol ExternalStoreUseCaseProtocol {
1313

14+
/// 외부 저장소에 로그인합니다.
1415
func signInWithAuthorization(presenting: PresentingConfiguration) -> RxSwift.Single<Void>
1516

17+
/// 외부 저장소에서 로그아웃합니다.
1618
func signOut()
1719

1820
var hasSigned: Bool { get }
1921

22+
/// 외부 저장소에 업로드합니다.
2023
/// - Parameter presenting: 외부 서비스에 로그인이 되어있지 않을 때 로그인 화면을 제시하는데 사용되는 구성
2124
func upload(presenting: PresentingConfiguration?) -> Observable<ProgressStatus>
2225

26+
/// 외부 저장소에서 다운로드합니다.
2327
/// - Parameter presenting: 외부 서비스에 로그인이 되어있지 않을 때 로그인 화면을 제시하는데 사용되는 구성
2428
func download(presenting: PresentingConfiguration?) -> Observable<ProgressStatus>
2529

30+
/// 이전에 로그인했던 사용자 복구를 시도합니다.
2631
func restoreSignIn() -> Observable<Void>
2732

2833
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//
2+
// NotificationsUseCaseProtocol.swift
3+
// Domain
4+
//
5+
// Created by Jaewon Yun on 1/24/24.
6+
// Copyright © 2024 woin2ee. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import RxSwift
11+
import UserNotifications
12+
13+
public protocol NotificationsUseCaseProtocol {
14+
15+
/// Requests the user’s authorization to allow local and remote notifications for your app.
16+
func requestNotificationAuthorization(with options: UNAuthorizationOptions) -> Single<Bool>
17+
18+
/// Retrieves the notification authorization status for your app.
19+
///
20+
/// 이 함수가 반환하는 Single 시퀀스는 error 를 방출하지 않습니다.
21+
func getNotificationAuthorizationStatus() -> Single<UNAuthorizationStatus>
22+
23+
/// 지정한 시각에 매일 알림을 설정합니다.
24+
func setDailyReminder(at time: DateComponents) -> Single<Void>
25+
26+
/// 현재 단어 갯수를 적용하여 알림 내용을 다시 설정합니다.
27+
///
28+
/// 매일 알림이 설정되어 있지 않거나 정상적으로 알림을 다시 설정하지 못했을 경우 Error 를 방출합니다.
29+
func resetDailyReminder() -> Completable
30+
31+
/// 설정된 매일 알림을 삭제합니다.
32+
func removeDailyReminder()
33+
34+
/// 설정되어 있는 매일 알림을 방출하는 시퀀스를 반환합니다.
35+
/// - Returns: 설정된 매일 알림이 있는 경우 알림 객체를 반환합니다. 설정된 매일 알림이 없거나 알림이 꺼져있는 경우 `error` 이벤트를 방출합니다.
36+
func getDailyReminder() -> Single<UNNotificationRequest>
37+
38+
/// 마지막으로 설정한 매일 알림의 시간을 반환합니다.
39+
func getLatestDailyReminderTime() throws -> DateComponents
40+
41+
}

Sources/Domain/Interfaces/UseCases/UserSettingsUseCaseProtocol.swift

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88

99
import Foundation
1010
import RxSwift
11-
import RxRelay
12-
import UserNotifications
1311

1412
public protocol UserSettingsUseCaseProtocol {
1513

@@ -19,30 +17,8 @@ public protocol UserSettingsUseCaseProtocol {
1917

2018
func getCurrentUserSettings() -> Single<UserSettings>
2119

22-
/// Requests the user’s authorization to allow local and remote notifications for your app.
23-
func requestNotificationAuthorization(with options: UNAuthorizationOptions) -> Single<Bool>
20+
func onHaptics() -> Single<Void>
2421

25-
/// Retrieves the notification authorization status for your app.
26-
///
27-
/// 이 함수가 반환하는 Single 시퀀스는 error 를 방출하지 않습니다.
28-
func getNotificationAuthorizationStatus() -> Single<UNAuthorizationStatus>
29-
30-
/// 지정한 시각에 매일 알림을 설정합니다.
31-
func setDailyReminder(at time: DateComponents) -> Single<Void>
32-
33-
/// 현재 단어 갯수를 적용하여 알림 내용을 다시 설정합니다.
34-
///
35-
/// 매일 알림이 설정되어 있지 않거나 정상적으로 알림을 다시 설정하지 못했을 경우 Error 를 방출합니다.
36-
func resetDailyReminder() -> Completable
37-
38-
/// 설정된 매일 알림을 삭제합니다.
39-
func removeDailyReminder()
40-
41-
/// 설정되어 있는 매일 알림을 방출하는 시퀀스를 반환합니다.
42-
/// - Returns: 설정된 매일 알림이 있는 경우 알림 객체를 반환합니다. 설정된 매일 알림이 없거나 알림이 꺼져있는 경우 `error` 이벤트를 방출합니다.
43-
func getDailyReminder() -> Single<UNNotificationRequest>
44-
45-
/// 마지막으로 설정한 매일 알림의 시간을 반환합니다.
46-
func getLatestDailyReminderTime() throws -> DateComponents
22+
func offHaptics() -> Single<Void>
4723

4824
}

Sources/Domain/Interfaces/UseCases/WordRxUseCaseProtocol.swift

Lines changed: 0 additions & 37 deletions
This file was deleted.

0 commit comments

Comments
 (0)