Skip to content

Commit f8651c6

Browse files
authored
Merge pull request #78 from ApptiveDev/dev
[Testflight] 1.1.8 업데이트
2 parents 556886c + b443eba commit f8651c6

30 files changed

Lines changed: 3353 additions & 81 deletions

.claude/settings.local.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(awk '/private struct TutorialDiaryDetailScreen/,/private struct TutorialNotificationScreen/' /Users/ibyeongchan/Desktop/KillingPart/KillingPoint-iOS/KillingPart/Views/Screens/Setup/InitialSetupFlowView.swift)"
5+
]
6+
}
7+
}

KillingPart.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@
434434
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
435435
CODE_SIGN_ENTITLEMENTS = KillingPart/KillingPart.entitlements;
436436
CODE_SIGN_STYLE = Automatic;
437-
CURRENT_PROJECT_VERSION = 30;
437+
CURRENT_PROJECT_VERSION = 34;
438438
DEAD_CODE_STRIPPING = YES;
439439
DEVELOPMENT_TEAM = GQ89YG5G9R;
440440
ENABLE_APP_SANDBOX = YES;
@@ -459,7 +459,7 @@
459459
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
460460
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
461461
MACOSX_DEPLOYMENT_TARGET = 14.0;
462-
MARKETING_VERSION = 1.1.4;
462+
MARKETING_VERSION = 1.1.8;
463463
PRODUCT_BUNDLE_IDENTIFIER = com.killingpoint.killingpart;
464464
PRODUCT_NAME = "$(TARGET_NAME)";
465465
REGISTER_APP_GROUPS = YES;
@@ -479,7 +479,7 @@
479479
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
480480
CODE_SIGN_ENTITLEMENTS = KillingPart/KillingPart.entitlements;
481481
CODE_SIGN_STYLE = Automatic;
482-
CURRENT_PROJECT_VERSION = 30;
482+
CURRENT_PROJECT_VERSION = 34;
483483
DEAD_CODE_STRIPPING = YES;
484484
DEVELOPMENT_TEAM = GQ89YG5G9R;
485485
ENABLE_APP_SANDBOX = YES;
@@ -504,7 +504,7 @@
504504
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
505505
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
506506
MACOSX_DEPLOYMENT_TARGET = 14.0;
507-
MARKETING_VERSION = 1.1.4;
507+
MARKETING_VERSION = 1.1.8;
508508
PRODUCT_BUNDLE_IDENTIFIER = com.killingpoint.killingpart;
509509
PRODUCT_NAME = "$(TARGET_NAME)";
510510
REGISTER_APP_GROUPS = YES;

KillingPart/Info.plist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
<string>$(KAKAO_NATIVE_APP_KEY)</string>
1111
<key>MUSIC_BASE_URL</key>
1212
<string>$(MUSIC_BASE_URL)</string>
13+
<key>APP_STORE_URL</key>
14+
<string>$(APP_STORE_URL)</string>
1315
<key>LSApplicationQueriesSchemes</key>
1416
<array>
1517
<string>kakaokompassauth</string>

KillingPart/Models/AppFlowStep.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Foundation
22

33
enum AppFlowStep {
44
case splash
5-
case onboarding
65
case login
6+
case setup
77
case main
88
}

KillingPart/Models/UserModel.swift

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,55 @@ struct UpdateMyTagRequest: Encodable {
153153
let tag: String
154154
}
155155

156+
struct UpdateMyUsernameRequest: Encodable {
157+
let username: String
158+
}
159+
160+
struct UserInitSettingsResponse: Decodable {
161+
let app: UserAppUpdateStatus
162+
let needsPolicyAgreement: Bool
163+
let needsTagSetup: Bool
164+
let policies: [UserPolicyStatus]
165+
}
166+
167+
struct UserAppUpdateStatus: Decodable {
168+
let needsForceUpdate: Bool
169+
let needsOptionalUpdate: Bool
170+
}
171+
172+
struct UserPolicyStatus: Decodable, Identifiable {
173+
let policyType: UserPolicyType
174+
let required: Bool
175+
let agreed: Bool
176+
let currentRevision: Int
177+
let latestRevision: Int
178+
179+
var id: UserPolicyType { policyType }
180+
}
181+
182+
enum UserPolicyType: String, Codable, CaseIterable {
183+
case serviceTerms = "SERVICE_TERMS"
184+
case privacy = "PRIVACY"
185+
186+
var displayTitle: String {
187+
switch self {
188+
case .serviceTerms:
189+
return "서비스 이용약관"
190+
case .privacy:
191+
return "개인정보 처리방침"
192+
}
193+
}
194+
}
195+
196+
struct PolicyAgreementRequest: Encodable {
197+
let agreements: [PolicyAgreementItem]
198+
}
199+
200+
struct PolicyAgreementItem: Encodable {
201+
let policyType: UserPolicyType
202+
let agreed: Bool
203+
}
204+
156205
private extension KeyedDecodingContainer {
157206
func decodeFlexibleBoolIfPresent(forKey key: K) -> Bool? {
158207
if let boolValue = try? decodeIfPresent(Bool.self, forKey: key) {

KillingPart/Services/UserService.swift

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ import Foundation
22

33
protocol UserServicing {
44
func fetchMyUser() async throws -> UserModel
5+
func fetchInitSettings() async throws -> UserInitSettingsResponse
6+
func submitPolicyAgreement(agreements: [PolicyAgreementItem]) async throws
57
func fetchUserStatics(userId: Int) async throws -> UserStaticsModel
68
func searchUsers(searchCond: String?, page: Int, size: Int) async throws -> UserSearchResponse
79
func deleteMyProfileImage() async throws -> UserModel
810
func issuePresignedURL() async throws -> PresignedURLResponse
911
func uploadImageToPresignedURL(imageData: Data, presignedURL: URL) async throws
1012
func updateMyProfileImage(request: UpdateMyProfileImageRequest) async throws -> UserModel
13+
func updateMyUsername(username: String) async throws -> UserModel
1114
func updateMyTag(tag: String) async throws -> UserModel
1215
}
1316

@@ -70,6 +73,47 @@ struct UserService: UserServicing {
7073
}
7174
}
7275

76+
func fetchInitSettings() async throws -> UserInitSettingsResponse {
77+
do {
78+
let request = APIRequest(
79+
path: "/users/init-settings",
80+
method: .get,
81+
queryItems: [
82+
URLQueryItem(name: "clientVersion", value: Self.clientVersion),
83+
URLQueryItem(name: "clientType", value: Self.clientType)
84+
],
85+
requiresAuthorization: true
86+
)
87+
return try await apiClient.request(request, responseType: UserInitSettingsResponse.self)
88+
} catch {
89+
throw mapError(error)
90+
}
91+
}
92+
93+
func submitPolicyAgreement(agreements: [PolicyAgreementItem]) async throws {
94+
let requestBody: Data
95+
do {
96+
requestBody = try JSONEncoder().encode(PolicyAgreementRequest(agreements: agreements))
97+
} catch {
98+
throw UserServiceError.requestEncodingFailed
99+
}
100+
101+
do {
102+
var request = APIRequest(
103+
path: "/users/policy-agreement",
104+
method: .post,
105+
requiresAuthorization: true,
106+
body: requestBody
107+
)
108+
request.headers["Accept"] = "application/json"
109+
request.headers["Content-Type"] = "application/json"
110+
try await apiClient.request(request)
111+
} catch {
112+
if isRequestCancelled(error) { throw error }
113+
throw mapError(error)
114+
}
115+
}
116+
73117
func fetchUserStatics(userId: Int) async throws -> UserStaticsModel {
74118
do {
75119
let request = APIRequest(
@@ -221,6 +265,31 @@ struct UserService: UserServicing {
221265
}
222266
}
223267

268+
func updateMyUsername(username: String) async throws -> UserModel {
269+
let requestBody: Data
270+
do {
271+
requestBody = try JSONEncoder().encode(UpdateMyUsernameRequest(username: username))
272+
} catch {
273+
throw UserServiceError.requestEncodingFailed
274+
}
275+
276+
do {
277+
var request = APIRequest(
278+
path: "/users/my/names",
279+
method: .patch,
280+
requiresAuthorization: true,
281+
body: requestBody
282+
)
283+
request.headers["Accept"] = "application/json"
284+
request.headers["Content-Type"] = "application/json"
285+
let response = try await apiClient.request(request, responseType: UserResponseDTO.self)
286+
return response.toModel()
287+
} catch {
288+
if isRequestCancelled(error) { throw error }
289+
throw mapError(error)
290+
}
291+
}
292+
224293
private func mapError(_ error: Error) -> UserServiceError {
225294
if let userServiceError = error as? UserServiceError {
226295
return userServiceError
@@ -299,6 +368,17 @@ struct UserService: UserServicing {
299368
let nsError = error as NSError
300369
return nsError.domain == NSURLErrorDomain && nsError.code == NSURLErrorCancelled
301370
}
371+
372+
private static var clientVersion: String {
373+
let shortVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String
374+
let buildVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as? String
375+
let resolved = (shortVersion?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false
376+
? shortVersion
377+
: buildVersion) ?? "0.0.0"
378+
return resolved
379+
}
380+
381+
private static let clientType = "IOS"
302382
}
303383

304384
private struct UserServiceErrorResponse: Decodable {

0 commit comments

Comments
 (0)