Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d8a7e3a
[추가] BaseVC 및 SOMTabBarC의 deinit 시 옵저버 제거
hyeonsik971029 Nov 3, 2025
f82259d
[수정] 상세화면 새로고침 시 api 2번 호출하는 문제 해결
hyeonsik971029 Nov 3, 2025
b894772
[변경] pulse 사용하는 것으로 변경
hyeonsik971029 Nov 3, 2025
01cb4c0
[수정] 상세 화면 위로 스크롤 시 하단 offset 생기는 문제 해결
hyeonsik971029 Nov 3, 2025
a4523cc
[수정] 상세 화면 좋아요 및 답카드 수 표시 방법 및 리로드 횟수 수정
hyeonsik971029 Nov 3, 2025
3d4216d
[수정] 상세 화면 뷰 레이아웃 수정
hyeonsik971029 Nov 4, 2025
3f2b377
[변경] 새로고침 시 offset 추가 방식 변경
hyeonsik971029 Nov 4, 2025
0ed227c
[수정] 알림 화면 읽지 않은 알림 선택 시 API 호출
hyeonsik971029 Nov 4, 2025
25c4a6b
[수정] 상세 화면 기본 프로필 이미지 border 추가
hyeonsik971029 Nov 4, 2025
3fb73f8
[수정] 상세 화면 좋아요 로직 변경
hyeonsik971029 Nov 4, 2025
5de4014
[추가] 상세 화면 차단 및 신고를 위한 이미지 및 버튼 변경
hyeonsik971029 Nov 4, 2025
b23f693
[수정] 차단 및 신고 로직 수정
hyeonsik971029 Nov 4, 2025
aca0feb
[변경] 알림 화면에서 상세 화면 전환 로직 변경
hyeonsik971029 Nov 4, 2025
8b9c5eb
[수정] API 호출 시 empty response 대응
hyeonsik971029 Nov 4, 2025
39ea83a
[버전] Develop 1.17.1(1017010) 버전 업데이트
hyeonsik971029 Nov 4, 2025
17d5909
[수정] 타이핑 시 줄바꿈 문제 해결
hyeonsik971029 Nov 5, 2025
c31d8d5
[변경] UILabel, UITextField, UITextView 타이포그래피 설정 시 키 변경
hyeonsik971029 Nov 5, 2025
a8e4f4c
[수정] placeholder 이미지 표시 문제 해결
hyeonsik971029 Nov 5, 2025
76a9c0d
[수정] SOMCard 표시 로직 수정
hyeonsik971029 Nov 5, 2025
24e04ae
[수정] 상세 화면 작성된 태그 간격 문제 해결
hyeonsik971029 Nov 5, 2025
8582e4d
[수정] 하단 탭바 아이콘 색상 수정
hyeonsik971029 Nov 5, 2025
20b7e4e
[변경] 카드 추가 rpeonse 변경
hyeonsik971029 Nov 5, 2025
6d35ef6
[수정] 카드 추가 성공 시 해당 카드 상세로 전환
hyeonsik971029 Nov 5, 2025
dc21448
[변경] 상세 화면 변경
hyeonsik971029 Nov 5, 2025
dbee11c
[수정] 알림 선택 시 로직 수정
hyeonsik971029 Nov 5, 2025
31c13b5
[변경] 카드 추가 화면 태그 입력 시 동작 변경
hyeonsik971029 Nov 5, 2025
aefb2ea
[버전] Develop 1.17.2(1017020) 버전 업데이트
hyeonsik971029 Nov 5, 2025
c78f9da
[수정] 상세 카드 삭제 시 뷰 로직 수정
hyeonsik971029 Nov 5, 2025
9eb2001
[추가] 사진 권한 추가
hyeonsik971029 Nov 5, 2025
89ae606
[버전] Develop 1.17.3(1017030) 버전 업데이트
hyeonsik971029 Nov 5, 2025
56020af
[수정] 탭바 아이콘 색상 수정
hyeonsik971029 Nov 5, 2025
ba34068
[변경] 태그 입력 방식 변경
hyeonsik971029 Nov 5, 2025
6445615
[변경] 상세 화면 백그라운드 색상 변경
hyeonsik971029 Nov 5, 2025
d9efc22
[수정] 카드 추가 시 s3 공간 확보 API 추가
hyeonsik971029 Nov 5, 2025
5fbbcf0
[버전] Develop 1.17.4(1017040) 버전 업데이트
hyeonsik971029 Nov 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions SOOUM/SOOUM.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,10 @@
38D2FBCF2E81B52F006DD739 /* SOMSwipableTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38D2FBCD2E81B529006DD739 /* SOMSwipableTabBar.swift */; };
38D2FBD12E81B9B7006DD739 /* SOMSwipableTabBarDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38D2FBD02E81B9B0006DD739 /* SOMSwipableTabBarDelegate.swift */; };
38D2FBD22E81B9B7006DD739 /* SOMSwipableTabBarDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38D2FBD02E81B9B0006DD739 /* SOMSwipableTabBarDelegate.swift */; };
38D478072EBBAA0B0041FF6C /* WriteCardResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38D478062EBBAA080041FF6C /* WriteCardResponse.swift */; };
38D478082EBBAA0B0041FF6C /* WriteCardResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38D478062EBBAA080041FF6C /* WriteCardResponse.swift */; };
38D4780A2EBBABF60041FF6C /* EntranceCardType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38D478092EBBABE40041FF6C /* EntranceCardType.swift */; };
38D4780B2EBBABF60041FF6C /* EntranceCardType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38D478092EBBABE40041FF6C /* EntranceCardType.swift */; };
38D488CA2D0C557300F2D38D /* SOMButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38D488C92D0C557300F2D38D /* SOMButton.swift */; };
38D488CB2D0C557300F2D38D /* SOMButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38D488C92D0C557300F2D38D /* SOMButton.swift */; };
38D522682E742F610044911B /* SOMLoadingIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38D522672E742F550044911B /* SOMLoadingIndicatorView.swift */; };
Expand Down Expand Up @@ -1095,6 +1099,8 @@
38D2FBCA2E81B0DE006DD739 /* SOMSwipableTabBarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SOMSwipableTabBarItem.swift; sourceTree = "<group>"; };
38D2FBCD2E81B529006DD739 /* SOMSwipableTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SOMSwipableTabBar.swift; sourceTree = "<group>"; };
38D2FBD02E81B9B0006DD739 /* SOMSwipableTabBarDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SOMSwipableTabBarDelegate.swift; sourceTree = "<group>"; };
38D478062EBBAA080041FF6C /* WriteCardResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WriteCardResponse.swift; sourceTree = "<group>"; };
38D478092EBBABE40041FF6C /* EntranceCardType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntranceCardType.swift; sourceTree = "<group>"; };
38D488C92D0C557300F2D38D /* SOMButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SOMButton.swift; sourceTree = "<group>"; };
38D522672E742F550044911B /* SOMLoadingIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SOMLoadingIndicatorView.swift; sourceTree = "<group>"; };
38D5637A2D16D72D006265AA /* SOMStickyTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SOMStickyTabBar.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2170,6 +2176,7 @@
38899E632E7938CD0030F7CA /* Responses */ = {
isa = PBXGroup;
children = (
38D478062EBBAA080041FF6C /* WriteCardResponse.swift */,
38E928BE2EB72D3600B3F00B /* DetailCardInfoResponse.swift */,
38EBA9102EB3999C008B28F4 /* PostingPermissionResponse.swift */,
38C9AF0D2E96601E00B401C0 /* DefaultImagesResponse.swift */,
Expand Down Expand Up @@ -2207,6 +2214,7 @@
38899E692E793AEA0030F7CA /* Models */ = {
isa = PBXGroup;
children = (
38D478092EBBABE40041FF6C /* EntranceCardType.swift */,
38E928B82EB715C300B3F00B /* ReortType.swift */,
38E928B52EB711DE00B3F00B /* DetailCardInfo.swift */,
38EBA90D2EB39917008B28F4 /* PostingPermission.swift */,
Expand Down Expand Up @@ -3253,6 +3261,7 @@
388D8AE02E73E6190044BA79 /* SwiftEntryKit.swift in Sources */,
38899E962E7953310030F7CA /* NotificationInfoResponse.swift in Sources */,
38FEBE5F2E86612C002916A8 /* NoticeViewCell.swift in Sources */,
38D4780A2EBBABF60041FF6C /* EntranceCardType.swift in Sources */,
2AFD055A2D008D23007C84AD /* TagDetailViewController.swift in Sources */,
2AFF95562CF3222400CBFB12 /* TagsViewController.swift in Sources */,
38C9AF182E96693600B401C0 /* TagRemoteDataSource.swift in Sources */,
Expand Down Expand Up @@ -3311,6 +3320,7 @@
3878D0862CFFED7800F9522F /* TermsOfServiceTextCellView.swift in Sources */,
38899E832E794C360030F7CA /* LoginResponse.swift in Sources */,
2ACBD41B2CCA03790057C013 /* ImageURLWithName.swift in Sources */,
38D478072EBBAA0B0041FF6C /* WriteCardResponse.swift in Sources */,
38E928C02EB72D3D00B3F00B /* DetailCardInfoResponse.swift in Sources */,
38B6AAE02CA4777200CE6DB6 /* UIViewController+Rx.swift in Sources */,
2ACBD41E2CCAB3490057C013 /* PresignedStorageResponse.swift in Sources */,
Expand Down Expand Up @@ -3634,6 +3644,7 @@
38FEBE5E2E86612C002916A8 /* NoticeViewCell.swift in Sources */,
38F3D9302D06C2370049F575 /* SOMAnimationTransitioning.swift in Sources */,
38C9AF172E96693600B401C0 /* TagRemoteDataSource.swift in Sources */,
38D4780B2EBBABF60041FF6C /* EntranceCardType.swift in Sources */,
385602B62D2FB18400118530 /* NotificationPlaceholderViewCell.swift in Sources */,
38E9CE192D37FED000E85A2D /* AddingTokenInterceptor.swift in Sources */,
380F42242E884AE5009AC59E /* CardRemoteDataSource.swift in Sources */,
Expand Down Expand Up @@ -3692,6 +3703,7 @@
2AFF955D2CF328DE00CBFB12 /* FavoriteTagTableViewCell.swift in Sources */,
38899E842E794C360030F7CA /* LoginResponse.swift in Sources */,
385053522C92DBE200C80B02 /* SOMTabBarItem.swift in Sources */,
38D478082EBBAA0B0041FF6C /* WriteCardResponse.swift in Sources */,
38E928BF2EB72D3D00B3F00B /* DetailCardInfoResponse.swift in Sources */,
38A5D1542C8CB11E00B68363 /* UIImage+SOOUM.swift in Sources */,
38601E182D31399400A465A9 /* CardRequest.swift in Sources */,
Expand Down Expand Up @@ -3788,7 +3800,7 @@
CODE_SIGN_ENTITLEMENTS = "SOOUM/Resources/SOOUM-Dev.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1017000;
CURRENT_PROJECT_VERSION = 1017040;
DEVELOPMENT_TEAM = 99FRG743RX;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "SOOUM/Resources/Develop/Info-dev.plist";
Expand All @@ -3811,7 +3823,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.17.0;
MARKETING_VERSION = 1.17.4;
OTHER_SWIFT_FLAGS = "$(inherited) -D DEVELOP";
PRODUCT_BUNDLE_IDENTIFIER = com.sooum.dev;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -3840,7 +3852,7 @@
CODE_SIGN_ENTITLEMENTS = "SOOUM/Resources/SOOUM-Dev.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1017000;
CURRENT_PROJECT_VERSION = 1017040;
DEVELOPMENT_TEAM = 99FRG743RX;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "SOOUM/Resources/Develop/Info-dev.plist";
Expand All @@ -3863,7 +3875,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.17.0;
MARKETING_VERSION = 1.17.4;
OTHER_SWIFT_FLAGS = "$(inherited) -D DEVELOP";
PRODUCT_BUNDLE_IDENTIFIER = com.sooum.dev;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
8 changes: 2 additions & 6 deletions SOOUM/SOOUM/Base/BaseViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,9 @@ class BaseViewController: UIViewController {
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
/// Show deinit class name
/// show deinit class name and remove all observer
deinit {
NotificationCenter.default.removeObserver(
self,
name: .hidesBottomBarWhenPushedDidChange,
object: nil
)
NotificationCenter.default.removeObserver(self)
Log.debug("Deinit: ", type(of: self).description().components(separatedBy: ".").last ?? "")
}

Expand Down
32 changes: 32 additions & 0 deletions SOOUM/SOOUM/Data/Models/Responses/WriteCardResponse.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// WriteCardResponse.swift
// SOOUM
//
// Created by 오현식 on 11/6/25.
//

import Alamofire

struct WriteCardResponse {

let cardId: String
}

extension WriteCardResponse: EmptyResponse {

static func emptyValue() -> WriteCardResponse {
WriteCardResponse(cardId: "")
}
}

extension WriteCardResponse: Decodable {

enum CodingKeys: CodingKey {
case cardId
}

init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.cardId = String(try container.decode(Int64.self, forKey: .cardId))
}
}
14 changes: 12 additions & 2 deletions SOOUM/SOOUM/Data/Repositories/CardRepositoryImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@ class CardRepositoryImpl: CardRepository {
return self.remoteDataSource.defaultImages()
}

func presignedURL() -> Observable<ImageUrlInfoResponse> {

return self.remoteDataSource.presignedURL()
}

func uploadImage(_ data: Data, with url: URL) -> Observable<Result<Void, Error>> {

return self.remoteDataSource.uploadImage(data, with: url)
}

func writeCard(
isDistanceShared: Bool,
latitude: String?,
Expand All @@ -86,7 +96,7 @@ class CardRepositoryImpl: CardRepository {
imgName: String,
isStory: Bool,
tags: [String]
) -> Observable<Int> {
) -> Observable<WriteCardResponse> {

return self.remoteDataSource.writeCard(
isDistanceShared: isDistanceShared,
Expand All @@ -111,7 +121,7 @@ class CardRepositoryImpl: CardRepository {
imgType: String,
imgName: String,
tags: [String]
) -> Observable<Int> {
) -> Observable<WriteCardResponse> {

return self.remoteDataSource.writeComment(
id: id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,17 @@ class CardRemoteDataSourceImpl: CardRemoteDataSource {
return self.provider.networkManager.fetch(DefaultImagesResponse.self, request: request)
}

func presignedURL() -> Observable<ImageUrlInfoResponse> {

let request: CardRequest = .presignedURL
return self.provider.networkManager.fetch(ImageUrlInfoResponse.self, request: request)
}

func uploadImage(_ data: Data, with url: URL) -> Observable<Result<Void, Error>> {

return self.provider.networkManager.upload(data, to: url)
}

func writeCard(
isDistanceShared: Bool,
latitude: String?,
Expand All @@ -96,7 +107,7 @@ class CardRemoteDataSourceImpl: CardRemoteDataSource {
imgName: String,
isStory: Bool,
tags: [String]
) -> Observable<Int> {
) -> Observable<WriteCardResponse> {

let request: CardRequest = .writeCard(
isDistanceShared: isDistanceShared,
Expand All @@ -109,7 +120,7 @@ class CardRemoteDataSourceImpl: CardRemoteDataSource {
isStory: isStory,
tags: tags
)
return self.provider.networkManager.perform(request)
return self.provider.networkManager.perform(WriteCardResponse.self, request: request)
}

func writeComment(
Expand All @@ -122,7 +133,7 @@ class CardRemoteDataSourceImpl: CardRemoteDataSource {
imgType: String,
imgName: String,
tags: [String]
) -> Observable<Int> {
) -> Observable<WriteCardResponse> {

let request: CardRequest = .writeComment(
id: id,
Expand All @@ -135,6 +146,6 @@ class CardRemoteDataSourceImpl: CardRemoteDataSource {
imgName: imgName,
tags: tags
)
return self.provider.networkManager.perform(request)
return self.provider.networkManager.perform(WriteCardResponse.self, request: request)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ protocol CardRemoteDataSource {
// MARK: Write

func defaultImages() -> Observable<DefaultImagesResponse>
func presignedURL() -> Observable<ImageUrlInfoResponse>
func uploadImage(_ data: Data, with url: URL) -> Observable<Result<Void, Error>>
func writeCard(
isDistanceShared: Bool,
latitude: String?,
Expand All @@ -42,7 +44,7 @@ protocol CardRemoteDataSource {
imgName: String,
isStory: Bool,
tags: [String]
) -> Observable<Int>
) -> Observable<WriteCardResponse>
func writeComment(
id: String,
isDistanceShared: Bool,
Expand All @@ -53,5 +55,5 @@ protocol CardRemoteDataSource {
imgType: String,
imgName: String,
tags: [String]
) -> Observable<Int>
) -> Observable<WriteCardResponse>
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class NotificationRemoteDataSoruceImpl: NotificationRemoteDataSource {
func requestRead(notificationId: String) -> Observable<Int> {

let request: NotificationRequest = .requestRead(notificationId: notificationId)
return self.provider.networkManager.perform(Int.self, request: request)
return self.provider.networkManager.perform(request)
}

func notices(lastId: String?, size: Int?) -> Observable<NoticeInfoResponse> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class UserRemoteDataSourceImpl: UserRemoteDataSource {
func presignedURL() -> Observable<ImageUrlInfoResponse> {

let request: UserRequest = .presignedURL
return self.provider.networkManager.perform(ImageUrlInfoResponse.self, request: request)
return self.provider.networkManager.fetch(ImageUrlInfoResponse.self, request: request)
}

func uploadImage(_ data: Data, with url: URL) -> Observable<Result<Void, Error>> {
Expand Down
5 changes: 5 additions & 0 deletions SOOUM/SOOUM/DesignSystem/Components/SOMBottomFloatView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ private extension SOMBottomFloatView {

$0.contentHorizontalAlignment = .left

$0.isEnabled = action.isEnabled

$0.tag = action.tag
$0.addTarget(self, action: #selector(self.tap(_:)), for: .touchUpInside)
}
Expand All @@ -116,19 +118,22 @@ extension SOMBottomFloatView {
let tag: Int
let image: UIImage?
let foregroundColor: UIColor
let isEnabled: Bool
let title: String
let action: (() -> Void)

init(
title: String,
image: UIImage? = nil,
foregroundColor: UIColor = .som.v2.gray500,
isEnabled: Bool = true,
action: @escaping (() -> Void)
) {
self.tag = UUID().hashValue
self.title = title
self.image = image
self.foregroundColor = foregroundColor
self.isEnabled = isEnabled
self.action = action
}
}
Expand Down
29 changes: 26 additions & 3 deletions SOOUM/SOOUM/DesignSystem/Components/SOMButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,14 @@ private extension SOMButton {
updatedConfig?.background.backgroundColor = self.backgroundColor
updatedConfig?.background.backgroundColorTransformer = UIConfigurationColorTransformer { _ in
// 비활성화 상태일 때, backgroundColor
if button.isEnabled == false { return .som.v2.gray200 }
if button.isEnabled == false {
switch self.backgroundColor {
case .som.v2.black: return .som.v2.gray200
case .som.v2.gray100: return .som.v2.gray200
case .som.v2.white: return .som.v2.white
default: return .clear
}
}
// 선택된 상태일 때, backgroundColor
if button.isSelected { return .som.v2.pLight1 }
// 하이라이트 상태일 때, backgroundColor
Expand All @@ -115,7 +122,14 @@ private extension SOMButton {
updatedConfig?.background.strokeColor = self.backgroundColor ?? .clear
updatedConfig?.background.strokeColorTransformer = UIConfigurationColorTransformer { _ in
// 비활성화 상태일 때, backgroundColor
if button.isEnabled == false { return .som.v2.gray200 }
if button.isEnabled == false {
switch self.backgroundColor {
case .som.v2.black: return .som.v2.gray200
case .som.v2.gray100: return .som.v2.gray200
case .som.v2.white: return .som.v2.white
default: return .clear
}
}
// 선택된 상태일 때, backgroundColor
if button.isSelected { return .som.v2.pMain }
// 하이라이트 상태일 때, backgroundColor
Expand All @@ -141,7 +155,16 @@ private extension SOMButton {
func applyConfiguration(to configuration: inout UIButton.Configuration?) {

var foregroundColor: UIColor {
return self.isEnabled ? (self.foregroundColor ?? .som.v2.white) : .som.v2.gray400
if self.isEnabled == false {
switch self.foregroundColor {
case .som.v2.white: return .som.v2.gray400
case .som.v2.gray600: return .som.v2.gray400
case .som.v2.gray500: return .som.v2.gray300
default: return .som.v2.gray300
}
}

return self.foregroundColor ?? .som.v2.white
}

if let image = self.image {
Expand Down
Loading
Loading