Skip to content

Commit 94b46e3

Browse files
authored
Merge pull request #606 from DeveloperAcademy-POSTECH/release/v1.7.0_1
[CHORE] v1.7.0 출시에 따라 main 브랜치를 업데이트합니다.
2 parents 9b0da19 + 895fa87 commit 94b46e3

File tree

390 files changed

+10167
-5745
lines changed

Some content is hidden

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

390 files changed

+10167
-5745
lines changed

.github/workflows/XCTestBuild.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
branches: [ develop, release, hotfix, feature, main ]
1010
jobs:
1111
build:
12-
runs-on: self-hosted
12+
runs-on: macos-latest
1313
steps:
1414
- uses: actions/checkout@v2
1515

Manito/Manito.xcodeproj/project.pbxproj

Lines changed: 867 additions & 377 deletions
Large diffs are not rendered by default.

Manito/Manito/App/AppDelegate.swift

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,42 +7,43 @@
77

88
import AuthenticationServices
99
import UIKit
10+
import UserNotifications
1011

1112
import Firebase
12-
import UserNotifications
13+
import MTResource
1314

1415
@main
1516
class AppDelegate: UIResponder, UIApplicationDelegate {
16-
17-
18-
17+
18+
19+
1920
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
2021
getCredentialState()
2122
FirebaseApp.configure()
22-
23+
2324
Messaging.messaging().delegate = self
2425
UNUserNotificationCenter.current().delegate = self
2526
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
26-
27+
2728
UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { _, _ in }
2829
application.registerForRemoteNotifications()
2930
return true
3031
}
31-
32+
3233
// MARK: UISceneSession Lifecycle
33-
34+
3435
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
3536
// Called when a new scene session is being created.
3637
// Use this method to select a configuration to create the new scene with.
3738
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
3839
}
39-
40+
4041
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
4142
// Called when the user discards a scene session.
4243
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
4344
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
4445
}
45-
46+
4647
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
4748
return UIInterfaceOrientationMask.portrait
4849
}
@@ -51,17 +52,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
5152
print("applicationWillEnterForeground")
5253
getCredentialState()
5354
}
54-
55+
5556
func applicationDidBecomeActive(_ application: UIApplication) {
5657
print("applicationDidBecomeActive")
5758
getCredentialState()
5859
}
5960

6061
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
61-
let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
62-
print("[Log] deviceToken :", deviceTokenString)
62+
let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
63+
print("[Log] deviceToken :", deviceTokenString)
6364

64-
Messaging.messaging().apnsToken = deviceToken
65+
Messaging.messaging().apnsToken = deviceToken
6566
}
6667
}
6768

@@ -93,14 +94,14 @@ extension AppDelegate: MessagingDelegate {
9394
print("파이어베이스 토큰: \(fcmToken ?? "")")
9495
guard let token = fcmToken else { return }
9596
UserDefaultHandler.setFcmToken(fcmToken: token)
96-
}
97+
}
9798
}
9899

99100
extension AppDelegate: UNUserNotificationCenterDelegate {
100101
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
101102
completionHandler([.badge, .sound])
102-
}
103-
103+
}
104+
104105
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
105106
guard let sceneDelegate = UIApplication.shared.connectedScenes.first?.delegate
106107
as? SceneDelegate else { return }

Manito/Manito/App/SceneDelegate.swift

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,37 @@
88
import UIKit
99

1010
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
11-
11+
1212
var window: UIWindow?
13-
13+
1414
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
1515
guard let windowScene = (scene as? UIWindowScene) else { return }
1616
let window = UIWindow(windowScene: windowScene)
17-
let storyboard = UIStoryboard(name: "Splash", bundle: nil)
18-
guard let viewController = storyboard.instantiateViewController(withIdentifier: SplashViewController.className) as? SplashViewController else { return }
19-
20-
window.rootViewController = viewController
17+
let usecase = SplashUsecaseImpl()
18+
let viewModel = SplashViewModel(usecase: usecase)
19+
window.rootViewController = SplashViewController(viewModel: viewModel)
2120
self.window = window
2221
window.makeKeyAndVisible()
2322
}
24-
23+
2524
func sceneDidDisconnect(_ scene: UIScene) { }
26-
25+
2726
func sceneDidBecomeActive(_ scene: UIScene) { }
28-
27+
2928
func sceneWillResignActive(_ scene: UIScene) { }
30-
29+
3130
func sceneWillEnterForeground(_ scene: UIScene) { }
32-
31+
3332
func sceneDidEnterBackground(_ scene: UIScene) { }
3433
}
3534

3635
extension SceneDelegate {
3736
func moveToLoginViewController() {
38-
let viewController = UINavigationController(rootViewController: LoginViewController())
39-
window?.rootViewController = viewController
37+
let repository = LoginRepositoryImpl()
38+
let usecase = LoginUsecaseImpl(repository: repository)
39+
let viewModel = LoginViewModel(usecase: usecase)
40+
let viewController = LoginViewController(viewModel: viewModel)
41+
window?.rootViewController = UINavigationController(rootViewController: viewController)
4042
}
4143

4244
func changeRootViewWithLetterView(roomId: Int) {

Manito/Manito/Data/DTO/Response/FriendListDTO.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,39 @@
77

88
import Foundation
99

10+
///
11+
/// 방에 참여한 멤버들의 정보를 반환하는 데이터 모델 DTO입니다.
12+
///
13+
1014
struct FriendListDTO: Decodable {
15+
/// 멤버 수
1116
let count: Int?
17+
/// 멤버들 정보
1218
let members: [MemberInfoDTO]?
1319
}
1420

21+
extension FriendListDTO {
22+
func toFriendList() -> FriendList {
23+
return FriendList(count: self.count ?? 0,
24+
members: self.members?.compactMap { $0.toMemberInfo() } ?? [])
25+
}
26+
}
27+
1528
struct MemberInfoDTO: Decodable {
29+
/// 닉네임
1630
let nickname: String?
31+
/// 선택한 컬러 인덱스
1732
let colorIndex: Int?
1833

1934
enum CodingKeys: String, CodingKey {
2035
case nickname
2136
case colorIndex = "colorIdx"
2237
}
2338
}
39+
40+
extension MemberInfoDTO {
41+
func toMemberInfo() -> MemberInfo {
42+
return MemberInfo(nickname: self.nickname ?? "",
43+
colorIndex: self.colorIndex ?? 0)
44+
}
45+
}

Manito/Manito/Data/DTO/Response/LoginDTO.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,15 @@ struct LoginDTO: Decodable {
1414
let isNewMember: Bool?
1515
let userSettingDone: Bool?
1616
}
17+
18+
extension LoginDTO {
19+
func toLoginInfo() -> LoginInfo {
20+
return LoginInfo(
21+
accessToken: self.accessToken ?? "",
22+
refreshToken: self.refreshToken ?? "",
23+
nickname: self.nickname ?? "",
24+
isNewMember: self.isNewMember ?? true,
25+
userSettingDone: self.userSettingDone ?? false
26+
)
27+
}
28+
}

Manito/Manito/Data/DTO/Response/MemoryDTO.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,41 @@
77

88
import Foundation
99

10+
///
11+
/// 함께 했던 기억 화면 관련 내용을 반환하는
12+
/// 데이터 모델 DTO입니다.
13+
///
14+
1015
struct MemoryDTO: Decodable {
16+
/// 마니또와의 추억
1117
let memoriesWithManitto: MemoryItemDTO?
18+
/// 마니띠와의 추억
1219
let memoriesWithManittee: MemoryItemDTO?
1320
}
1421

22+
extension MemoryDTO {
23+
func toMemory() async -> Memory {
24+
return await Memory(memoriesWithManitto: (self.memoriesWithManitto?.toMemoryItem())!,
25+
memoriesWithManittee: (self.memoriesWithManittee?.toMemoryItem())!)
26+
}
27+
}
28+
1529
struct MemoryItemDTO: Decodable {
30+
/// 마니또나 마니띠의 정보
1631
let member: MemberInfoDTO?
32+
/// 마니또, 마니띠와 주고 받았던 쪽지 내용
1733
let messages: [MessageListItemDTO]?
1834
}
35+
36+
extension MemoryItemDTO {
37+
func toMemoryItem() async -> MemoryItem {
38+
let memberInfo = MemberInfo(nickname: member?.nickname ?? "",
39+
colorIndex: member?.colorIndex ?? 0)
40+
var resultMessages: [MessageListItem] = []
41+
for message in self.messages ?? [] {
42+
resultMessages.append(await message.toMessageListItem(canReport: false))
43+
}
44+
return MemoryItem(member: memberInfo,
45+
messages: resultMessages)
46+
}
47+
}

Manito/Manito/Data/DTO/Response/MessageListItemDTO.swift

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,32 @@ struct MessageListItemDTO: Decodable {
2626
}
2727

2828
extension MessageListItemDTO {
29-
func toMessageListItem(canReport: Bool) -> MessageListItem {
30-
return MessageListItem(id: self.id ?? 0,
29+
func toMessageListItem(canReport: Bool) async -> MessageListItem {
30+
return await MessageListItem(id: self.id ?? 0,
3131
content: self.content,
32-
imageUrl: self.imageUrl,
32+
imageUrl: self.verifiedImageURL(),
3333
createdDate: self.createdDate ?? "",
3434
missionInfo: self.missionInfo,
3535
canReport: canReport)
3636
}
37+
38+
// MARK: - Private - func
39+
40+
/// DB에 이미지가 없는 imageURL를 걸러내고 검증된 imageURL만 반환
41+
private func verifiedImageURL() async -> String? {
42+
do {
43+
guard let imageURL = self.imageUrl else { return nil }
44+
guard let url = URL(string: imageURL) else { return nil }
45+
46+
let (_, response) = try await URLSession.shared.data(from: url)
47+
guard let urlResponse = response as? HTTPURLResponse else { return nil }
48+
49+
switch urlResponse.statusCode {
50+
case 200..<300: return self.imageUrl
51+
default: return nil
52+
}
53+
} catch {
54+
return nil
55+
}
56+
}
3757
}

Manito/Manito/Data/DTO/Response/ParticipatedRoomInfoDTO.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,32 @@
77

88
import Foundation
99

10+
///
11+
/// 방 참가시 그 방의 정보들을 반환하는 데이터 모델 DTO 입니다.
12+
///
13+
1014
struct ParticipatedRoomInfoDTO: Decodable {
15+
/// 방 id
1116
let id: Int?
17+
/// 방 제목
1218
let title: String?
19+
/// 방 참여 가능 인원 수
1320
let capacity: Int?
21+
/// 현재 방 참가 인원 수
1422
let participatingCount: Int?
23+
/// 방 시작 날짜
1524
let startDate: String?
25+
/// 방 종료 날짜
1626
let endDate: String?
1727
}
28+
29+
extension ParticipatedRoomInfoDTO {
30+
func toParticipateRoomInfo() -> ParticipatedRoomInfo {
31+
return ParticipatedRoomInfo(id: self.id ?? 0,
32+
title: self.title ?? "",
33+
capacity: self.capacity ?? 0,
34+
participatingCount: self.participatingCount ?? 0,
35+
startDate: self.startDate ?? "",
36+
endDate: self.endDate ?? "")
37+
}
38+
}

Manito/Manito/Data/DTO/Response/RoomInfoDTO.swift

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ extension RoomInfoDTO {
5252
}
5353
}
5454

55+
extension RoomInfoDTO: Equatable {
56+
static let testDummyRoomDTO = RoomInfoDTO(
57+
roomInformation: RoomListItemDTO.testDummyRoomListItemDTO,
58+
participants: ParticipantListDTO.testDummyParticipantListDTO,
59+
manittee: UserInfoDTO.testDummyUserManittee,
60+
manitto: UserInfoDTO.testDummyUserManitto,
61+
invitation: InvitationCodeDTO.testDummyInvitationCodeDTO,
62+
didViewRoulette: false,
63+
mission: IndividualMissionDTO.testDummyIndividualMissionDTO,
64+
admin: false,
65+
messages: MessageCountInfoDTO.testDummyMessageInfoDTO
66+
)
67+
}
68+
5569
struct ParticipantListDTO: Decodable {
5670
let count: Int?
5771
let members: [UserInfoDTO]?
@@ -64,6 +78,13 @@ extension ParticipantListDTO {
6478
}
6579
}
6680

81+
extension ParticipantListDTO: Equatable {
82+
static let testDummyParticipantListDTO = ParticipantListDTO(
83+
count: 5,
84+
members: UserInfoDTO.testDummyUserList
85+
)
86+
}
87+
6788
struct InvitationCodeDTO: Decodable {
6889
let code: String?
6990
}
@@ -74,6 +95,10 @@ extension InvitationCodeDTO {
7495
}
7596
}
7697

98+
extension InvitationCodeDTO: Equatable {
99+
static let testDummyInvitationCodeDTO = InvitationCodeDTO(code: "ABCDEF")
100+
}
101+
77102
/// 개별 미션에 대한 정보들을 반환하는 데이터 모델 DTO입니다.
78103
struct IndividualMissionDTO: Decodable, Hashable {
79104
/// 개별 미션 identifier
@@ -88,12 +113,20 @@ extension IndividualMissionDTO {
88113
}
89114
}
90115

116+
extension IndividualMissionDTO: Equatable {
117+
static let testDummyIndividualMissionDTO = IndividualMissionDTO(id: 1, content: "테스트미션")
118+
}
119+
91120
struct MessageCountInfoDTO: Decodable {
92121
let count: Int?
93122
}
94123

95-
extension MessageCountInfoDTO: Equatable {
124+
extension MessageCountInfoDTO {
96125
func toMessageCountInfo() -> MessageCountInfo {
97126
return MessageCountInfo(count: self.count ?? 0)
98127
}
99128
}
129+
130+
extension MessageCountInfoDTO: Equatable {
131+
static let testDummyMessageInfoDTO = MessageCountInfoDTO(count: 3)
132+
}

0 commit comments

Comments
 (0)