Skip to content

Commit a75d260

Browse files
authored
Merge pull request #107 from YAPP-Github/TNT-303-TrainerMyPageEdit
[TNT-303] ํŠธ๋ ˆ์ด๋„ˆ ๋งˆ์ดํŽ˜์ด์ง€ ์ •๋ณด ์ˆ˜์ • ํ™”๋ฉด ๊ตฌํ˜„ ์™„๋ฃŒ
2 parents 4fb63ad + 119d126 commit a75d260

File tree

26 files changed

+1436
-99
lines changed

26 files changed

+1436
-99
lines changed

โ€Ž.gitignoreโ€Ž

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,4 @@ Signing/
7777
master.key
7878

7979
# PList
80-
GoogleService-Info.plist
81-
82-
# CLAUDE
83-
CLAUDE.md
80+
GoogleService-Info.plist

โ€ŽTnT/Projects/Data/Sources/Network/Service/User/UserTargetType.swiftโ€Ž

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//
88

99
import Foundation
10+
import UIKit
1011

1112
import Domain
1213

@@ -77,24 +78,10 @@ extension UserTargetType: TargetType {
7778
return .requestJSONEncodable(encodable: reqDto)
7879

7980
case let .postSignUp(reqDto, imgData):
80-
let jsons: [MultipartJSON] = [.init(jsonName: "request", json: reqDto)]
81-
82-
// ํ”„๋กœํ•„ ์ด๋ฏธ์ง€๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ๋ฉ€ํ‹ฐํŒŒํŠธ ์—…๋กœ๋“œ ์ฒ˜๋ฆฌ
83-
let files: [MultipartFile] = imgData.map {
84-
[.init(fieldName: "profileImage", fileName: "profile.png", mimeType: "image/png", data: $0)]
85-
} ?? []
86-
87-
return .uploadMultipart(jsons: jsons, files: files, additionalFields: [:])
81+
return makeProfileMultipartUpload(dto: reqDto, imageData: imgData)
8882

8983
case let .putUpdateUserInfo(reqDto, imgData):
90-
let jsons: [MultipartJSON] = [.init(jsonName: "request", json: reqDto)]
91-
92-
// ํ”„๋กœํ•„ ์ด๋ฏธ์ง€๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ๋ฉ€ํ‹ฐํŒŒํŠธ ์—…๋กœ๋“œ ์ฒ˜๋ฆฌ
93-
let files: [MultipartFile] = imgData.map {
94-
[.init(fieldName: "profileImage", fileName: "profile.png", mimeType: "image/png", data: $0)]
95-
} ?? []
96-
97-
return .uploadMultipart(jsons: jsons, files: files, additionalFields: [:])
84+
return makeProfileMultipartUpload(dto: reqDto, imageData: imgData)
9885
}
9986
}
10087

@@ -130,4 +117,37 @@ extension UserTargetType: TargetType {
130117
]
131118
}
132119
}
120+
121+
/// ํ”„๋กœํ•„ ๋ฉ€ํ‹ฐํŒŒํŠธ ์—…๋กœ๋“œ (DTO + ์„ ํƒ ์ด๋ฏธ์ง€)
122+
private func makeProfileMultipartUpload<T: Encodable>(dto: T, imageData: Data?) -> RequestTask {
123+
let jsons: [MultipartJSON] = [.init(jsonName: "request", json: dto)]
124+
var files: [MultipartFile] = []
125+
126+
if let imageData {
127+
let format = imageData.imageFormat
128+
let fileInfo = (
129+
name: "profile.\(format.fileExtension)",
130+
mime: format.mimeType
131+
)
132+
133+
let compressedData: Data
134+
if let image = UIImage(data: imageData),
135+
let data = image.compressedData(maxSizeMB: 10.0, isPNG: format == .png) {
136+
compressedData = data
137+
} else {
138+
compressedData = imageData
139+
}
140+
141+
files = [
142+
.init(
143+
fieldName: "profileImage",
144+
fileName: fileInfo.name,
145+
mimeType: fileInfo.mime,
146+
data: compressedData
147+
)
148+
]
149+
}
150+
151+
return .uploadMultipart(jsons: jsons, files: files, additionalFields: [:])
152+
}
133153
}

โ€ŽTnT/Projects/Data/Sources/Network/Utility/UIImage+.swiftโ€Ž

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ extension UIImage {
1515
/// - isPNG: ์›๋ณธ์ด PNG์ธ ๊ฒฝ์šฐ, PNG๋กœ ์••์ถ•ํ• ์ง€ ์—ฌ๋ถ€ (๊ธฐ๋ณธ๊ฐ’: true)
1616
/// - Returns: ์••์ถ•๋œ ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ (JPEG ๋˜๋Š” PNG)
1717
/// - Note: PNG ์••์ถ•์€ ๋ฌด์†์‹ค์ด์ง€๋งŒ, ํฌ๊ธฐ ๊ฐ์†Œ ํšจ๊ณผ๊ฐ€ ์ ๊ณ  ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
18-
/// JPEG ์••์ถ•์€ ์†์‹ค ์••์ถ•์ด์ง€๋งŒ ํฌ๊ธฐ๋ฅผ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค..
18+
/// JPEG ์••์ถ•์€ ์†์‹ค ์••์ถ•์ด์ง€๋งŒ ํฌ๊ธฐ๋ฅผ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1919
func compressedData(maxSizeMB: Double = 10.0, isPNG: Bool = false) -> Data? {
2020
let maxSizeBytes: Int = Int(maxSizeMB * 1024 * 1024)
2121

@@ -35,4 +35,43 @@ extension UIImage {
3535

3636
return imageData
3737
}
38+
39+
}
40+
41+
extension Data {
42+
enum ImageFormat {
43+
case jpeg
44+
case png
45+
case unknown
46+
47+
var fileExtension: String {
48+
switch self {
49+
case .jpeg, .unknown:
50+
return "jpg"
51+
case .png:
52+
return "png"
53+
}
54+
}
55+
56+
var mimeType: String {
57+
switch self {
58+
case .jpeg, .unknown:
59+
return "image/jpeg"
60+
case .png:
61+
return "image/png"
62+
}
63+
}
64+
}
65+
66+
var imageFormat: ImageFormat {
67+
let pngSignature: [UInt8] = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]
68+
69+
if self.starts(with: [0xFF, 0xD8]) {
70+
return .jpeg
71+
} else if self.starts(with: pngSignature) {
72+
return .png
73+
}
74+
75+
return .unknown
76+
}
3877
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"images" : [
3+
{
4+
"filename" : "icn_check_mark_light_green.svg",
5+
"idiom" : "universal"
6+
}
7+
],
8+
"info" : {
9+
"author" : "xcode",
10+
"version" : 1
11+
}
12+
}
Lines changed: 4 additions & 0 deletions
Loading
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"images" : [
3+
{
4+
"filename" : "icn_question_mark.svg",
5+
"idiom" : "universal"
6+
}
7+
],
8+
"info" : {
9+
"author" : "xcode",
10+
"version" : 1
11+
}
12+
}
Lines changed: 5 additions & 0 deletions
Loading

โ€ŽTnT/Projects/DesignSystem/Sources/Components/PopUp/TPopUpAlertState.swiftโ€Ž

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public struct TPopupAlertState: Equatable {
1717
public var message: String?
1818
/// ํŒ์—…์˜ ๊ฒฝ๊ณ  ์•„์ด์ฝ˜ ํ‘œ์‹œ (์˜ต์…˜)
1919
public var showAlertIcon: Bool
20+
/// ํŒ์—…์— ํ‘œ์‹œํ•  ์ปค์Šคํ…€ ์•„์ด์ฝ˜ (์˜ต์…˜)
21+
public var icon: PopupIcon?
2022
/// ํŒ์—…์— ํ‘œ์‹œ๋  ๋ฒ„ํŠผ ๋ฐฐ์—ด
2123
public var buttons: [ButtonState]
2224

@@ -25,20 +27,42 @@ public struct TPopupAlertState: Equatable {
2527
/// - title: ํŒ์—…์˜ ์ œ๋ชฉ
2628
/// - message: ํŒ์—…์˜ ๋ฉ”์‹œ์ง€ (์„ ํƒ ์‚ฌํ•ญ, ๊ธฐ๋ณธ๊ฐ’: `nil`)
2729
/// - showAlertIcon: ํŒ์—…์˜ ๊ฒฝ๊ณ  ์•„์ด์ฝ˜ ํ‘œ์‹œ (๊ธฐ๋ณธ๊ฐ’: `false`)
30+
/// - icon: ํŒ์—…์— ํ‘œ์‹œํ•  ์ปค์Šคํ…€ ์•„์ด์ฝ˜ (๊ธฐ๋ณธ๊ฐ’: `nil`)
2831
/// - buttons: ํŒ์—…์— ํ‘œ์‹œํ•  ๋ฒ„ํŠผ ๋ฐฐ์—ด (๊ธฐ๋ณธ๊ฐ’: ๋นˆ ๋ฐฐ์—ด)
2932
public init(
3033
title: String,
3134
message: String? = nil,
3235
showAlertIcon: Bool = false,
36+
icon: PopupIcon? = nil,
3337
buttons: [ButtonState] = []
3438
) {
3539
self.title = title
3640
self.message = message
3741
self.showAlertIcon = showAlertIcon
42+
self.icon = icon
3843
self.buttons = buttons
3944
}
4045
}
4146

47+
public extension TPopupAlertState {
48+
enum PopupIcon {
49+
case warning
50+
case checkMarkLightGreen
51+
case questionMark
52+
53+
var imageResource: ImageResource {
54+
switch self {
55+
case .warning:
56+
return .icnWarning
57+
case .checkMarkLightGreen:
58+
return .icnCheckMarkLightGreen
59+
case .questionMark:
60+
return .icnQuestionMark
61+
}
62+
}
63+
}
64+
}
65+
4266
public extension TPopupAlertState {
4367
// TODO: ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ ์™„์„ฑ ์‹œ ์ˆ˜์ •
4468
/// TPopUpAlertView.AlertButton์— ํ‘œ์‹œํ•˜๋Š” ์ •๋ณด์ž…๋‹ˆ๋‹ค.

โ€ŽTnT/Projects/DesignSystem/Sources/Components/PopUp/TPopUpAlertView.swiftโ€Ž

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ public struct TPopUpAlertView: View {
2424
// ํ…์ŠคํŠธ Section
2525
VStack(spacing: 8) {
2626
VStack(spacing: 0) {
27-
if alertState.showAlertIcon {
27+
if let icon = alertState.icon {
28+
Image(icon.imageResource)
29+
.resizable()
30+
.frame(width: 80, height: 80)
31+
} else if alertState.showAlertIcon {
2832
Image(.icnWarning)
2933
.resizable()
3034
.frame(width: 80, height: 80)
31-
} else {
32-
Color.clear
33-
.frame(height: 20)
3435
}
3536
Text(alertState.title)
3637
.typographyStyle(.heading3, with: .neutral900)

0 commit comments

Comments
ย (0)