diff --git a/Poppool/CoreLayer/Infrastructure/Infrastructure.xcodeproj/project.pbxproj b/Poppool/CoreLayer/Infrastructure/Infrastructure.xcodeproj/project.pbxproj index d5ab556c..75cc80c7 100644 --- a/Poppool/CoreLayer/Infrastructure/Infrastructure.xcodeproj/project.pbxproj +++ b/Poppool/CoreLayer/Infrastructure/Infrastructure.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 0522C1D72DB67B4F00B141FF /* RxSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 0522C1D62DB67B4F00B141FF /* RxSwift */; }; 05EC93D92DB6605100771CB3 /* RxCocoa in Frameworks */ = {isa = PBXBuildFile; productRef = 05EC93D82DB6605100771CB3 /* RxCocoa */; }; 05EC93DE2DB6612100771CB3 /* RxGesture in Frameworks */ = {isa = PBXBuildFile; productRef = 05EC93DD2DB6612100771CB3 /* RxGesture */; }; + 4EBC91D32DB8039800495C3B /* OSLog.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EBC91D22DB8039800495C3B /* OSLog.framework */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -27,6 +28,7 @@ /* Begin PBXFileReference section */ 058CC9182DB5383C0084221A /* Infrastructure.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Infrastructure.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4EBC91D22DB8039800495C3B /* OSLog.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OSLog.framework; path = System/Library/Frameworks/OSLog.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ @@ -42,6 +44,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4EBC91D32DB8039800495C3B /* OSLog.framework in Frameworks */, 0522C1D72DB67B4F00B141FF /* RxSwift in Frameworks */, 05EC93DE2DB6612100771CB3 /* RxGesture in Frameworks */, 05EC93D92DB6605100771CB3 /* RxCocoa in Frameworks */, @@ -54,6 +57,7 @@ 05125B6A2DB56C32001342A2 /* Frameworks */ = { isa = PBXGroup; children = ( + 4EBC91D22DB8039800495C3B /* OSLog.framework */, ); name = Frameworks; sourceTree = ""; diff --git a/Poppool/CoreLayer/Infrastructure/Infrastructure/Logger/Logger.swift b/Poppool/CoreLayer/Infrastructure/Infrastructure/Logger/Logger.swift index 16360c15..c636a5e6 100644 --- a/Poppool/CoreLayer/Infrastructure/Infrastructure/Logger/Logger.swift +++ b/Poppool/CoreLayer/Infrastructure/Infrastructure/Logger/Logger.swift @@ -1,13 +1,16 @@ import Foundation +import OSLog public struct Logger { - public enum Level { + private static let subsystem = Bundle.main.bundleIdentifier ?? "com.poppoolIOS.poppool" + + public enum Level: Hashable { case info case debug case network case error case event - case custom(categoryName: String) + case custom(name: String) var categoryName: String { switch self { @@ -21,8 +24,7 @@ public struct Logger { return "Error" case .event: return "Event" - case .custom(let categoryName): - return categoryName + case .custom(let name): return name } } @@ -44,26 +46,62 @@ public struct Logger { } } - static var isShowFileName: Bool = false - static var isShowLine: Bool = false - static var isShowLog: Bool = true + public enum LogLevel { + case debug + case info + case error + case fault + + var osLogType: OSLogType { + switch self { + case .debug: + return .debug + case .info: + return .info + case .error: return .error + case .fault: return .fault + } + } + } + + private static var isShowFileName: Bool = false + private static var isShowLine: Bool = true + private static var isShowLog: Bool = true + + private static var loggers: [Level: os.Logger] = [:] + private static func getLogger(for category: Level) -> os.Logger { + let categoryName = category.categoryName + + if let cachedLogger = loggers[category] { + return cachedLogger + } + + let logger = os.Logger(subsystem: subsystem, category: categoryName) + loggers[category] = logger + return logger + } public static func log( - message: Any, + _ message: Any, category: Level, - fileName: String = "Input is not found", - line: Int? = nil + level: LogLevel = .info, + file: String = #file, + line: Int = #line ) { - if isShowLog { - print("\(category.categoryIcon) [\(category.categoryName)]: \(message)") - if isShowFileName { - guard let fileName = fileName.components(separatedBy: "/").last else { return } - print(" \(category.categoryIcon) [FileName]: \(fileName)") - } - if isShowLine { - guard let line = line else { return } - print(" \(category.categoryIcon) [Line]: \(line)") - } + guard isShowLog else { return } + + let logger = getLogger(for: category) + var fullMessage = "\(category.categoryIcon) \(message)" + + if isShowFileName { + let fileNameOnly = (file as NSString).lastPathComponent + fullMessage += " | ๐Ÿ“ \(fileNameOnly)" } + + if isShowLine { + fullMessage += " | ๐Ÿ“ \(line)" + } + + logger.log(level: level.osLogType, "\(fullMessage, privacy: .public)") } } diff --git a/Poppool/CoreLayer/Infrastructure/Infrastructure/Service/KeyChainService.swift b/Poppool/CoreLayer/Infrastructure/Infrastructure/Service/KeyChainService.swift index bc44ded4..822263e7 100644 --- a/Poppool/CoreLayer/Infrastructure/Infrastructure/Service/KeyChainService.swift +++ b/Poppool/CoreLayer/Infrastructure/Infrastructure/Service/KeyChainService.swift @@ -43,10 +43,8 @@ public final class KeyChainService { if let data = dataTypeRef as? Data { if let value = String(data: data, encoding: .utf8) { Logger.log( - message: "Successfully fetched \(type.rawValue) from KeyChain: \(value)", - category: .info, - fileName: #file, - line: #line + "Successfully fetched \(type.rawValue) from KeyChain", + category: .info ) return .success(value) } else { @@ -84,10 +82,9 @@ public final class KeyChainService { let status = SecItemAdd(keyChainQuery, nil) if status == errSecSuccess { Logger.log( - message: "Successfully saved \(type.rawValue) to KeyChain: \(value)", - category: .info, - fileName: #file, - line: #line + "Successfully fetched \(type.rawValue) from KeyChain: \(value)", + category: .info + ) return .success(()) } else { @@ -111,10 +108,8 @@ public final class KeyChainService { if status == errSecSuccess { Logger.log( - message: "Successfully deleted \(type.rawValue) from KeyChain", - category: .info, - fileName: #file, - line: #line + "Successfully deleted \(type.rawValue) from KeyChain", + category: .info ) return .success(()) } else { diff --git a/Poppool/DataLayer/Data/Data/Network/API/PreSignedAPI/PreSignedAPIEndPoint.swift b/Poppool/DataLayer/Data/Data/Network/API/PreSignedAPI/PreSignedAPIEndPoint.swift index 21d930f2..47bd16a8 100644 --- a/Poppool/DataLayer/Data/Data/Network/API/PreSignedAPI/PreSignedAPIEndPoint.swift +++ b/Poppool/DataLayer/Data/Data/Network/API/PreSignedAPI/PreSignedAPIEndPoint.swift @@ -4,7 +4,7 @@ import Infrastructure struct PreSignedAPIEndPoint { static func presigned_upload(request: PresignedURLRequestDTO) -> Endpoint { - Logger.log(message: "Presigned URL ์ƒ์„ฑ - Request: \(request)", category: .debug) + Logger.log("Presigned URL ์ƒ์„ฑ - Request: \(request)", category: .debug) return Endpoint( baseURL: Secrets.popPoolBaseURL, path: "/files/upload-preSignedUrl", @@ -14,7 +14,7 @@ struct PreSignedAPIEndPoint { } static func presigned_download(request: PresignedURLRequestDTO) -> Endpoint { - Logger.log(message: "Presigned Download URL ์ƒ์„ฑ - Request: \(request)", category: .debug) + Logger.log("Presigned Download URL ์ƒ์„ฑ - Request: \(request)", category: .debug) return Endpoint( baseURL: Secrets.popPoolBaseURL, path: "/files/download-preSignedUrl", @@ -24,7 +24,7 @@ struct PreSignedAPIEndPoint { } static func presigned_delete(request: PresignedURLRequestDTO) -> RequestEndpoint { - Logger.log(message: "Presigned Delete ์ƒ์„ฑ - Request: \(request)", category: .debug) + Logger.log("Presigned Delete ์ƒ์„ฑ - Request: \(request)", category: .debug) return RequestEndpoint( baseURL: Secrets.popPoolBaseURL, path: "/files/delete", diff --git a/Poppool/DataLayer/Data/Data/Network/Common/Requestable.swift b/Poppool/DataLayer/Data/Data/Network/Common/Requestable.swift index 2709e94c..2172c43b 100644 --- a/Poppool/DataLayer/Data/Data/Network/Common/Requestable.swift +++ b/Poppool/DataLayer/Data/Data/Network/Common/Requestable.swift @@ -21,10 +21,8 @@ extension Requestable { let url = try url() Logger.log( - message: "\(url) URL ์ƒ์„ฑ", - category: .network, - fileName: #file, - line: #line + "\(url) URL ์ƒ์„ฑ", + category: .network ) var urlRequest = URLRequest(url: url) diff --git a/Poppool/DataLayer/Data/Data/Network/EndPoint/MultipartEndPoint.swift b/Poppool/DataLayer/Data/Data/Network/EndPoint/MultipartEndPoint.swift index 00a5bf3c..4c9e7011 100644 --- a/Poppool/DataLayer/Data/Data/Network/EndPoint/MultipartEndPoint.swift +++ b/Poppool/DataLayer/Data/Data/Network/EndPoint/MultipartEndPoint.swift @@ -34,7 +34,7 @@ public class MultipartEndPoint: URLRequestConvertible { public func asURLRequest() throws -> URLRequest { let url = try baseURL.asURL().appendingPathComponent(path) var request = URLRequest(url: url) - Logger.log(message: "\(request) URL ์ƒ์„ฑ", category: .network) + Logger.log("\(request) URL ์ƒ์„ฑ", category: .network) request.method = method if let headers = headers { @@ -57,7 +57,7 @@ public class MultipartEndPoint: URLRequestConvertible { multipartFormData.append(jsonString.data(using: .utf8)!, withName: "data") } } catch { - Logger.log(message: "JSON ๋ณ€ํ™˜ ์˜ค๋ฅ˜: \(error)", category: .network) + Logger.log("JSON ๋ณ€ํ™˜ ์˜ค๋ฅ˜: \(error)", category: .network) } } diff --git a/Poppool/DataLayer/Data/Data/Network/Interceptor/TokenInterceptor.swift b/Poppool/DataLayer/Data/Data/Network/Interceptor/TokenInterceptor.swift index 5dc2418b..2f1c68dc 100644 --- a/Poppool/DataLayer/Data/Data/Network/Interceptor/TokenInterceptor.swift +++ b/Poppool/DataLayer/Data/Data/Network/Interceptor/TokenInterceptor.swift @@ -11,7 +11,7 @@ final class TokenInterceptor: RequestInterceptor { _ urlRequest: URLRequest, for session: Session, completion: @escaping (Result) -> Void) { - Logger.log(message: "TokenInterceptor Adapt Token", category: .network) + Logger.log("TokenInterceptor Adapt Token", category: .network) @Dependency var keyChainService: KeyChainService var urlRequest = urlRequest let accessTokenResult = keyChainService.fetchToken(type: .accessToken) @@ -32,7 +32,7 @@ final class TokenInterceptor: RequestInterceptor { dueTo error: any Error, completion: @escaping (RetryResult) -> Void ) { - Logger.log(message: "TokenInterceptor Retry Start", category: .network) + Logger.log("TokenInterceptor Retry Start", category: .network) completion(.doNotRetry) } } diff --git a/Poppool/DataLayer/Data/Data/Network/Provider/ProviderImpl.swift b/Poppool/DataLayer/Data/Data/Network/Provider/ProviderImpl.swift index e3d925ed..e46126b9 100644 --- a/Poppool/DataLayer/Data/Data/Network/Provider/ProviderImpl.swift +++ b/Poppool/DataLayer/Data/Data/Network/Provider/ProviderImpl.swift @@ -22,22 +22,11 @@ public final class ProviderImpl: Provider { /// 1) endpoint -> urlRequest ์ƒ์„ฑ let urlRequest = try endpoint.getUrlRequest() - Logger.log( - message: """ - [Provider] ์ตœ์ข… ์š”์ฒญ URL: - - URL: \(urlRequest.url?.absoluteString ?? "URL์ด ์—†์Šต๋‹ˆ๋‹ค.") - - Method: \(urlRequest.httpMethod ?? "์•Œ ์ˆ˜ ์—†์Œ") - - Headers: \(urlRequest.allHTTPHeaderFields ?? [:]) - ์š”์ฒญ ์‹œ๊ฐ: \(Date()) - """, - category: .debug - ) - let request = AF.request(urlRequest, interceptor: interceptor) .validate() .responseData { [weak self] response in Logger.log( - message: """ + """ [Provider] ์‘๋‹ต ์ˆ˜์‹ : - URL: \(urlRequest.url?.absoluteString ?? "URL์ด ์—†์Šต๋‹ˆ๋‹ค.") - ์‘๋‹ต ์‹œ๊ฐ: \(Date()) @@ -63,14 +52,14 @@ public final class ProviderImpl: Provider { observer.onCompleted() } catch { Logger.log( - message: "๋””์ฝ”๋”ฉ ์‹คํŒจ: \(error.localizedDescription)", + "๋””์ฝ”๋”ฉ ์‹คํŒจ: \(error.localizedDescription)", category: .error ) observer.onError(NetworkError.decodeError) } case .failure(let error): - Logger.log(message: "์š”์ฒญ ์‹คํŒจ Error:\(error)", category: .error) + Logger.log("์š”์ฒญ ์‹คํŒจ Error:\(error)", category: .error) observer.onError(error) } } @@ -80,7 +69,7 @@ public final class ProviderImpl: Provider { } } catch { - Logger.log(message: "[Provider] URLRequest ์ƒ์„ฑ ์‹คํŒจ: \(error.localizedDescription)", category: .error) + Logger.log("[Provider] URLRequest ์ƒ์„ฑ ์‹คํŒจ: \(error.localizedDescription)", category: .error) observer.onError(NetworkError.urlRequest(error)) return Disposables.create() } @@ -101,19 +90,9 @@ public final class ProviderImpl: Provider { do { let urlRequest = try request.getUrlRequest() - Logger.log( - message: """ - [Provider] ์ตœ์ข… ์š”์ฒญ URL(Completable): - - URL: \(urlRequest.url?.absoluteString ?? "URL์ด ์—†์Šต๋‹ˆ๋‹ค.") - - Method: \(urlRequest.httpMethod ?? "์•Œ ์ˆ˜ ์—†์Œ") - ์š”์ฒญ ์‹œ๊ฐ: \(Date()) - """, - category: .debug - ) - self.executeRequest(urlRequest, interceptor: interceptor) { response in Logger.log( - message: "์‘๋‹ต ์‹œ๊ฐ :\(Date())", + "์‘๋‹ต ์‹œ๊ฐ :\(Date())", category: .network ) @@ -132,12 +111,12 @@ public final class ProviderImpl: Provider { case .success: observer(.completed) case .failure(let error): - Logger.log(message: "์š”์ฒญ ์‹คํŒจ Error:\(error)", category: .error) + Logger.log("์š”์ฒญ ์‹คํŒจ Error:\(error)", category: .error) observer(.error(self.handleRequestError(response: response, error: error))) } } } catch { - Logger.log(message: "[Provider] URLRequest ์ƒ์„ฑ ์‹คํŒจ (Completable): \(error.localizedDescription)", category: .error) + Logger.log("[Provider] URLRequest ์ƒ์„ฑ ์‹คํŒจ (Completable): \(error.localizedDescription)", category: .error) observer(.error(NetworkError.urlRequest(error))) } @@ -158,23 +137,15 @@ public final class ProviderImpl: Provider { do { let urlRequest = try request.asURLRequest() - Logger.log( - message: """ - [Provider] ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์š”์ฒญ: - - URL: \(urlRequest.url?.absoluteString ?? "URL์ด ์—†์Šต๋‹ˆ๋‹ค.") - - Method: \(urlRequest.httpMethod ?? "์•Œ ์ˆ˜ ์—†์Œ") - """, - category: .network - ) AF.upload(multipartFormData: { multipartFormData in request.asMultipartFormData(multipartFormData: multipartFormData) - Logger.log(message: "์—…๋กœ๋“œ ์‹œ๊ฐ :\(Date())", category: .network) + Logger.log("์—…๋กœ๋“œ ์‹œ๊ฐ :\(Date())", category: .network) }, with: urlRequest, interceptor: interceptor) .validate() .response { response in Logger.log( - message: "์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์‘๋‹ต ์‹œ๊ฐ :\(Date())", + "์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์‘๋‹ต ์‹œ๊ฐ :\(Date())", category: .network ) switch response.result { @@ -200,15 +171,6 @@ private extension ProviderImpl { interceptor: RequestInterceptor?, completion: @escaping (AFDataResponse) -> Void ) { - // ์—ฌ๊ธฐ์„œ๋„ ์ตœ์ข… URL ์ฐ์„ ์ˆ˜ ์žˆ์Œ - Logger.log( - message: """ - [Provider] executeRequest: - - URL: \(urlRequest.url?.absoluteString ?? "URL์ด ์—†์Šต๋‹ˆ๋‹ค.") - ์š”์ฒญ ์‹œ๊ฐ: \(Date()) - """, - category: .debug - ) AF.request(urlRequest, interceptor: interceptor) .validate() diff --git a/Poppool/DataLayer/Data/Data/Network/Service/AppleLoginService.swift b/Poppool/DataLayer/Data/Data/Network/Service/AppleLoginService.swift index 18458103..a119d861 100644 --- a/Poppool/DataLayer/Data/Data/Network/Service/AppleLoginService.swift +++ b/Poppool/DataLayer/Data/Data/Network/Service/AppleLoginService.swift @@ -37,10 +37,8 @@ extension AppleLoginService: ASAuthorizationControllerPresentationContextProvidi let windowSecne = scenes.first as? UIWindowScene guard let window = windowSecne?.windows.first else { Logger.log( - message: "\(#function) UIWindow fetch Fail", - category: .error, - fileName: #file, - line: #line + "\(#function) UIWindow fetch Fail", + category: .error ) return UIWindow() } @@ -71,8 +69,8 @@ extension AppleLoginService: ASAuthorizationControllerPresentationContextProvidi guard let convertAuthorizationCode = String(data: authorizationCode, encoding: .utf8) else { return } - Logger.log(message: "IDToken: \(idToken)", category: .info) - Logger.log(message: "Auth Code: \(convertAuthorizationCode)", category: .info) + Logger.log("IDToken: \(idToken)", category: .info) + Logger.log("Auth Code: \(convertAuthorizationCode)", category: .info) authServiceResponse.onNext(.init(idToken: idToken, authorizationCode: convertAuthorizationCode)) default: break @@ -84,10 +82,8 @@ extension AppleLoginService: ASAuthorizationControllerPresentationContextProvidi didCompleteWithError error: Error ) { Logger.log( - message: "AppleLogin Fail", - category: .error, - fileName: #file, - line: #line + "AppleLogin Fail", + category: .error ) authServiceResponse.onError(error) } diff --git a/Poppool/DataLayer/Data/Data/Network/Service/KakaoLoginService.swift b/Poppool/DataLayer/Data/Data/Network/Service/KakaoLoginService.swift index 634cf838..4427a467 100644 --- a/Poppool/DataLayer/Data/Data/Network/Service/KakaoLoginService.swift +++ b/Poppool/DataLayer/Data/Data/Network/Service/KakaoLoginService.swift @@ -16,7 +16,7 @@ public final class KakaoLoginService: AuthServiceable { UserApi.shared.unlink { error in if let error = error { observer.onNext(()) - Logger.log(message: error.localizedDescription, category: .error) + Logger.log(error.localizedDescription, category: .error) } else { observer.onNext(()) observer.onCompleted() @@ -31,10 +31,8 @@ public final class KakaoLoginService: AuthServiceable { return Observable.create { [weak self] observer in guard let self else { Logger.log( - message: "KakaoTalk login Error", - category: .error, - fileName: #file, - line: #line + "KakaoTalk login Error", + category: .error ) return Disposables.create() } @@ -42,10 +40,8 @@ public final class KakaoLoginService: AuthServiceable { // ์นด์นด์˜คํ†ก ์„ค์น˜ ์œ ๋ฌด ํ™•์ธ guard UserApi.isKakaoTalkLoginAvailable() else { Logger.log( - message: "KakaoTalk is not install", - category: .error, - fileName: #file, - line: #line + "KakaoTalk is not install", + category: .error ) // ์นด์นด์˜คํ†ก ๋ฏธ์„ค์น˜์‹œ ์›น์œผ๋กœ ์ธ์ฆ ์‹œ๋„ diff --git a/Poppool/DataLayer/Data/Data/Network/Service/PreSignedService.swift b/Poppool/DataLayer/Data/Data/Network/Service/PreSignedService.swift index 3609bc2b..017c76c4 100644 --- a/Poppool/DataLayer/Data/Data/Network/Service/PreSignedService.swift +++ b/Poppool/DataLayer/Data/Data/Network/Service/PreSignedService.swift @@ -29,20 +29,20 @@ class PreSignedService { } func tryUpload(datas: [PresignedURLRequest]) -> Single { - Logger.log(message: "tryUpload ํ˜ธ์ถœ๋จ - ์š”์ฒญ ๋ฐ์ดํ„ฐ ์ˆ˜: \(datas.count)", category: .debug) + Logger.log("tryUpload ํ˜ธ์ถœ๋จ - ์š”์ฒญ ๋ฐ์ดํ„ฐ ์ˆ˜: \(datas.count)", category: .debug) return Single.create { [weak self] observer in - Logger.log(message: "tryUpload ๋‚ด๋ถ€ ํ๋ฆ„ ์‹œ์ž‘", category: .debug) + Logger.log("tryUpload ๋‚ด๋ถ€ ํ๋ฆ„ ์‹œ์ž‘", category: .debug) guard let self = self else { - Logger.log(message: "self๊ฐ€ nil์ž…๋‹ˆ๋‹ค. ์ž‘์—…์„ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค.", category: .error) + Logger.log("self๊ฐ€ nil์ž…๋‹ˆ๋‹ค. ์ž‘์—…์„ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค.", category: .error) return Disposables.create() } // 1. ์—…๋กœ๋“œ ๋งํฌ ์š”์ฒญ self.getUploadLinks(request: .init(objectKeyList: datas.map { $0.filePath })) .subscribe { response in - Logger.log(message: "getUploadLinks ์„ฑ๊ณต: \(response.preSignedUrlList)", category: .debug) + Logger.log("getUploadLinks ์„ฑ๊ณต: \(response.preSignedUrlList)", category: .debug) let responseList = response.preSignedUrlList let inputList = datas @@ -51,23 +51,23 @@ class PreSignedService { let requestList = zip(responseList, inputList).compactMap { zipResponse in let urlResponse = zipResponse.0 let inputResponse = zipResponse.1 - Logger.log(message: "์—…๋กœ๋“œ ์ค€๋น„ - URL: \(urlResponse.preSignedUrl)", category: .debug) + Logger.log("์—…๋กœ๋“œ ์ค€๋น„ - URL: \(urlResponse.preSignedUrl)", category: .debug) return self.uploadFromS3(url: urlResponse.preSignedUrl, image: inputResponse.image) } // 3. ๋ณ‘๋ ฌ ์—…๋กœ๋“œ ์‹คํ–‰ Single.zip(requestList) .subscribe(onSuccess: { _ in - Logger.log(message: "๋ชจ๋“  ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์„ฑ๊ณต", category: .info) + Logger.log("๋ชจ๋“  ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์„ฑ๊ณต", category: .info) observer(.success(())) }, onFailure: { error in - Logger.log(message: "์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์‹คํŒจ: \(error.localizedDescription)", category: .error) + Logger.log("์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์‹คํŒจ: \(error.localizedDescription)", category: .error) observer(.failure(error)) }) .disposed(by: self.disposeBag) } onError: { error in - Logger.log(message: "getUploadLinks ์‹คํŒจ: \(error.localizedDescription)", category: .error) + Logger.log("getUploadLinks ์‹คํŒจ: \(error.localizedDescription)", category: .error) observer(.failure(error)) } .disposed(by: self.disposeBag) @@ -123,16 +123,16 @@ class PreSignedService { return filePaths.compactMap { imageMap[$0] } } .subscribe(onSuccess: { sortedImages in - Logger.log(message: "All images downloaded successfully", category: .info) + Logger.log("All images downloaded successfully", category: .info) observer(.success(sortedImages)) }, onFailure: { error in - Logger.log(message: "Image download failed: \(error.localizedDescription)", category: .error) + Logger.log("Image download failed: \(error.localizedDescription)", category: .error) observer(.failure(error)) }) .disposed(by: self.disposeBag) } onError: { error in - Logger.log(message: "getDownloadLinks Fail: \(error.localizedDescription)", category: .error) + Logger.log("getDownloadLinks Fail: \(error.localizedDescription)", category: .error) observer(.failure(error)) } .disposed(by: disposeBag) @@ -148,7 +148,7 @@ private extension PreSignedService { return Single.create { single in if let imageData = image.jpegData(compressionQuality: 0), let url = URL(string: url) { - Logger.log(message: "S3 ์—…๋กœ๋“œ ์š”์ฒญ URL: \(url.absoluteString)", category: .debug) + Logger.log("S3 ์—…๋กœ๋“œ ์š”์ฒญ URL: \(url.absoluteString)", category: .debug) let headers: HTTPHeaders = [ "Content-Type": "image/jpeg" @@ -156,19 +156,19 @@ private extension PreSignedService { AF.upload(imageData, to: url, method: .put, headers: headers) .response { response in - Logger.log(message: "S3 ์—…๋กœ๋“œ ์‘๋‹ต ์ƒํƒœ: \(response.response?.statusCode ?? -1)", category: .debug) + Logger.log("S3 ์—…๋กœ๋“œ ์‘๋‹ต ์ƒํƒœ: \(response.response?.statusCode ?? -1)", category: .debug) switch response.result { case .success: - Logger.log(message: "S3 ์—…๋กœ๋“œ ์„ฑ๊ณต - URL: \(url.absoluteString)", category: .info) + Logger.log("S3 ์—…๋กœ๋“œ ์„ฑ๊ณต - URL: \(url.absoluteString)", category: .info) single(.success(())) case .failure(let error): - Logger.log(message: "S3 ์—…๋กœ๋“œ ์‹คํŒจ: \(error.localizedDescription)", category: .error) + Logger.log("S3 ์—…๋กœ๋“œ ์‹คํŒจ: \(error.localizedDescription)", category: .error) single(.failure(error)) } } return Disposables.create() } else { - Logger.log(message: "S3 ์—…๋กœ๋“œ ์‹คํŒจ - ์ž˜๋ชป๋œ URL ๋˜๋Š” ๋ฐ์ดํ„ฐ", category: .error) + Logger.log("S3 ์—…๋กœ๋“œ ์‹คํŒจ - ์ž˜๋ชป๋œ URL ๋˜๋Š” ๋ฐ์ดํ„ฐ", category: .error) single(.failure(NSError(domain: "InvalidDataOrURL", code: -1, userInfo: nil))) return Disposables.create() } @@ -197,13 +197,13 @@ private extension PreSignedService { } func getUploadLinks(request: PresignedURLRequestDTO) -> Observable { - Logger.log(message: "Presigned URL ์ƒ์„ฑ ์š”์ฒญ ๋ฐ์ดํ„ฐ: \(request)", category: .debug) + Logger.log("Presigned URL ์ƒ์„ฑ ์š”์ฒญ ๋ฐ์ดํ„ฐ: \(request)", category: .debug) let endPoint = PreSignedAPIEndPoint.presigned_upload(request: request) return provider.requestData(with: endPoint, interceptor: tokenInterceptor) .do(onNext: { response in - Logger.log(message: "Presigned URL ์‘๋‹ต ๋ฐ์ดํ„ฐ: \(response.preSignedUrlList)", category: .debug) + Logger.log("Presigned URL ์‘๋‹ต ๋ฐ์ดํ„ฐ: \(response.preSignedUrlList)", category: .debug) }, onError: { error in - Logger.log(message: "Presigned URL ์š”์ฒญ ์‹คํŒจ: \(error.localizedDescription)", category: .error) + Logger.log("Presigned URL ์š”์ฒญ ์‹คํŒจ: \(error.localizedDescription)", category: .error) }) } @@ -214,18 +214,18 @@ private extension PreSignedService { } extension PreSignedService { func deleteImage(filePath: String, completion: @escaping (Result) -> Void) { - Logger.log(message: "์ด๋ฏธ์ง€ ์‚ญ์ œ ์‹œ์ž‘ - ๊ฒฝ๋กœ: \(filePath)", category: .debug) + Logger.log("์ด๋ฏธ์ง€ ์‚ญ์ œ ์‹œ์ž‘ - ๊ฒฝ๋กœ: \(filePath)", category: .debug) let request = PresignedURLRequestDTO(objectKeyList: [filePath]) tryDelete(targetPaths: request) .subscribe( onCompleted: { - Logger.log(message: "์ด๋ฏธ์ง€ ์‚ญ์ œ ์„ฑ๊ณต: \(filePath)", category: .debug) + Logger.log("์ด๋ฏธ์ง€ ์‚ญ์ œ ์„ฑ๊ณต: \(filePath)", category: .debug) completion(.success(())) }, onError: { error in - Logger.log(message: "์ด๋ฏธ์ง€ ์‚ญ์ œ ์‹คํŒจ: \(error.localizedDescription)", category: .error) + Logger.log("์ด๋ฏธ์ง€ ์‚ญ์ œ ์‹คํŒจ: \(error.localizedDescription)", category: .error) completion(.failure(error)) } ) @@ -285,12 +285,12 @@ extension PreSignedService { guard let encodedPath = filePath .addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)? .replacingOccurrences(of: "+", with: "%2B") else { - Logger.log(message: "URL ์ธ์ฝ”๋”ฉ ์‹คํŒจ: \(filePath)", category: .error) + Logger.log("URL ์ธ์ฝ”๋”ฉ ์‹คํŒจ: \(filePath)", category: .error) return nil } let fullString = baseURL + encodedPath - Logger.log(message: "์ƒ์„ฑ๋œ URL: \(fullString)", category: .debug) + Logger.log("์ƒ์„ฑ๋œ URL: \(fullString)", category: .debug) return URL(string: fullString) } diff --git a/Poppool/DataLayer/Data/Data/RepositoryImpl/MapRepositoryImpl.swift b/Poppool/DataLayer/Data/Data/RepositoryImpl/MapRepositoryImpl.swift index 236aad21..74f1b2ea 100644 --- a/Poppool/DataLayer/Data/Data/RepositoryImpl/MapRepositoryImpl.swift +++ b/Poppool/DataLayer/Data/Data/RepositoryImpl/MapRepositoryImpl.swift @@ -48,7 +48,7 @@ public final class MapRepositoryImpl: MapRepository { } public func fetchCategories() -> Observable<[CategoryResponse]> { - Logger.log(message: "์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์š”์ฒญ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.", category: .network) + Logger.log("์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์š”์ฒญ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.", category: .network) return provider.requestData( with: SignUpAPIEndpoint.signUp_getCategoryList(), @@ -56,7 +56,7 @@ public final class MapRepositoryImpl: MapRepository { ) .do(onNext: { _ in Logger.log( - message: "์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์‘๋‹ต ์„ฑ๊ณต", + "์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์‘๋‹ต ์„ฑ๊ณต", category: .debug ) }) @@ -65,7 +65,7 @@ public final class MapRepositoryImpl: MapRepository { } .catch { error in Logger.log( - message: "์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์š”์ฒญ ์‹คํŒจ: \(error.localizedDescription)", + "์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์š”์ฒญ ์‹คํŒจ: \(error.localizedDescription)", category: .error ) throw error diff --git a/Poppool/DomainLayer/Domain/Domain/UseCaseImpl/AdminUseCaseImpl.swift b/Poppool/DomainLayer/Domain/Domain/UseCaseImpl/AdminUseCaseImpl.swift index de49b176..c2482298 100644 --- a/Poppool/DomainLayer/Domain/Domain/UseCaseImpl/AdminUseCaseImpl.swift +++ b/Poppool/DomainLayer/Domain/Domain/UseCaseImpl/AdminUseCaseImpl.swift @@ -22,26 +22,26 @@ public final class AdminUseCaseImpl: AdminUseCase { } public func createStore(params: CreateStoreParams) -> Completable { - Logger.log(message: "createStore ํ˜ธ์ถœ - ์Šคํ† ์–ด๋ช…: \(params.name)", category: .debug) + Logger.log("createStore ํ˜ธ์ถœ - ์Šคํ† ์–ด๋ช…: \(params.name)", category: .debug) return repository.createStore(params: params) .do(onError: { error in - Logger.log(message: "createStore ์‹คํŒจ - Error: \(error)", category: .error) + Logger.log("createStore ์‹คํŒจ - Error: \(error)", category: .error) }, onCompleted: { - Logger.log(message: "createStore ์„ฑ๊ณต", category: .info) + Logger.log("createStore ์„ฑ๊ณต", category: .info) }) } public func updateStore(params: UpdateStoreParams) -> Completable { - Logger.log(message: """ + Logger.log(""" Updating store with location: Latitude: \(params.latitude) Longitude: \(params.longitude) """, category: .debug) return repository.updateStore(params: params) .do(onError: { error in - Logger.log(message: "Store update failed: \(error)", category: .error) + Logger.log("Store update failed: \(error)", category: .error) }, onCompleted: { - Logger.log(message: "Store update successful", category: .debug) + Logger.log("Store update successful", category: .debug) }) } diff --git a/Poppool/DomainLayer/Domain/Domain/UseCaseImpl/MapUseCaseImpl.swift b/Poppool/DomainLayer/Domain/Domain/UseCaseImpl/MapUseCaseImpl.swift index 5253690e..457d8a8c 100644 --- a/Poppool/DomainLayer/Domain/Domain/UseCaseImpl/MapUseCaseImpl.swift +++ b/Poppool/DomainLayer/Domain/Domain/UseCaseImpl/MapUseCaseImpl.swift @@ -32,9 +32,9 @@ public final class MapUseCaseImpl: MapUseCase { categories: categories ) .do(onNext: { stores in - Logger.log(message: "๋งต ๋ฒ”์œ„ ๋‚ด ์Šคํ† ์–ด \(stores.count)๊ฐœ ๋กœ๋“œ๋จ", category: .debug) + Logger.log("๋งต ๋ฒ”์œ„ ๋‚ด ์Šคํ† ์–ด \(stores.count)๊ฐœ ๋กœ๋“œ๋จ", category: .debug) }, onError: { error in - Logger.log(message: "๋งต ๋ฒ”์œ„ ๋‚ด ์Šคํ† ์–ด ๋กœ๋“œ ์‹คํŒจ: \(error)", category: .error) + Logger.log("๋งต ๋ฒ”์œ„ ๋‚ด ์Šคํ† ์–ด ๋กœ๋“œ ์‹คํŒจ: \(error)", category: .error) }) } @@ -47,9 +47,9 @@ public final class MapUseCaseImpl: MapUseCase { categories: categories ) .do(onNext: { stores in - Logger.log(message: "'\(query)' ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ \(stores.count)๊ฐœ ๋กœ๋“œ๋จ", category: .debug) + Logger.log("'\(query)' ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ \(stores.count)๊ฐœ ๋กœ๋“œ๋จ", category: .debug) }, onError: { error in - Logger.log(message: "์Šคํ† ์–ด ๊ฒ€์ƒ‰ ์‹คํŒจ: \(error)", category: .error) + Logger.log("์Šคํ† ์–ด ๊ฒ€์ƒ‰ ์‹คํŒจ: \(error)", category: .error) }) } diff --git a/Poppool/Poppool.xcodeproj/project.pbxproj b/Poppool/Poppool.xcodeproj/project.pbxproj index db866640..a858dfe7 100644 --- a/Poppool/Poppool.xcodeproj/project.pbxproj +++ b/Poppool/Poppool.xcodeproj/project.pbxproj @@ -58,7 +58,6 @@ isa = PBXFileSystemSynchronizedBuildFileExceptionSet; membershipExceptions = ( /Localized/Resource/LaunchScreen.storyboard, - Resource/Debug.xcconfig, Resource/Info.plist, ); target = BDCA41BC2CF35AC0005EECF6 /* Poppool */; diff --git a/Poppool/Poppool.xcodeproj/xcshareddata/xcschemes/Poppool.xcscheme b/Poppool/Poppool.xcodeproj/xcshareddata/xcschemes/Poppool.xcscheme index 9b875b57..77d7ce2e 100644 --- a/Poppool/Poppool.xcodeproj/xcshareddata/xcschemes/Poppool.xcscheme +++ b/Poppool/Poppool.xcodeproj/xcshareddata/xcschemes/Poppool.xcscheme @@ -63,7 +63,9 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" - allowLocationSimulation = "YES"> + allowLocationSimulation = "YES" + consoleMode = "0" + structuredConsoleMode = "1"> + + + diff --git a/Poppool/Poppool/Resource/Assets.xcassets/Marker/TapMarker.imageset/Contents.json b/Poppool/Poppool/Resource/Assets.xcassets/Marker/TapMarker.imageset/Contents.json index fb8ebfdd..b1cb08ba 100644 --- a/Poppool/Poppool/Resource/Assets.xcassets/Marker/TapMarker.imageset/Contents.json +++ b/Poppool/Poppool/Resource/Assets.xcassets/Marker/TapMarker.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "solid.png", + "filename" : "solid.svg", "idiom" : "universal", "scale" : "1x" }, diff --git a/Poppool/Poppool/Resource/Assets.xcassets/Marker/TapMarker.imageset/solid.png b/Poppool/Poppool/Resource/Assets.xcassets/Marker/TapMarker.imageset/solid.png deleted file mode 100644 index 39f13b31..00000000 Binary files a/Poppool/Poppool/Resource/Assets.xcassets/Marker/TapMarker.imageset/solid.png and /dev/null differ diff --git a/Poppool/Poppool/Resource/Assets.xcassets/Marker/TapMarker.imageset/solid.svg b/Poppool/Poppool/Resource/Assets.xcassets/Marker/TapMarker.imageset/solid.svg new file mode 100644 index 00000000..1fef9bf7 --- /dev/null +++ b/Poppool/Poppool/Resource/Assets.xcassets/Marker/TapMarker.imageset/solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminBottomSheet/AdminBottomSheetView.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminBottomSheet/AdminBottomSheetView.swift index 69a94cbe..d8e74495 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminBottomSheet/AdminBottomSheetView.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminBottomSheet/AdminBottomSheetView.swift @@ -212,7 +212,7 @@ final class AdminBottomSheetView: UIView { // MARK: - Public Methods func updateContentVisibility(isCategorySelected: Bool) { - Logger.log(message: "๋†’์ด ๋ณ€๊ฒฝ ์‹œ์ž‘: \(isCategorySelected ? "์นดํ…Œ๊ณ ๋ฆฌ" : "์ƒํƒœ๊ฐ’")", category: .debug) + Logger.log("๋†’์ด ๋ณ€๊ฒฝ ์‹œ์ž‘: \(isCategorySelected ? "์นดํ…Œ๊ณ ๋ฆฌ" : "์ƒํƒœ๊ฐ’")", category: .debug) let newHeight: CGFloat = isCategorySelected ? 200 : 160 @@ -223,6 +223,6 @@ final class AdminBottomSheetView: UIView { setNeedsLayout() layoutIfNeeded() - Logger.log(message: "๋†’์ด ๋ณ€๊ฒฝ ์™„๋ฃŒ", category: .debug) + Logger.log("๋†’์ด ๋ณ€๊ฒฝ ์™„๋ฃŒ", category: .debug) } } diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminBottomSheet/AdminBottomSheetViewController.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminBottomSheet/AdminBottomSheetViewController.swift index 89ee0c06..a143fbe3 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminBottomSheet/AdminBottomSheetViewController.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminBottomSheet/AdminBottomSheetViewController.swift @@ -42,7 +42,7 @@ final class AdminBottomSheetViewController: BaseViewController, View { private func setupViews() { view.backgroundColor = .clear - Logger.log(message: "์ดˆ๊ธฐ ๋ทฐ ๊ณ„์ธต:", category: .debug) + Logger.log("์ดˆ๊ธฐ ๋ทฐ ๊ณ„์ธต:", category: .debug) view.addSubview(mainView) mainView.isUserInteractionEnabled = true @@ -57,7 +57,7 @@ final class AdminBottomSheetViewController: BaseViewController, View { containerViewBottomConstraint = make.bottom.equalTo(view.snp.bottom).constraint } - Logger.log(message: "mainView ์ถ”๊ฐ€ ํ›„ ๊ณ„์ธต:", category: .debug) + Logger.log("mainView ์ถ”๊ฐ€ ํ›„ ๊ณ„์ธต:", category: .debug) dimmedView.backgroundColor = .black.withAlphaComponent(0.4) dimmedView.alpha = 0 @@ -72,7 +72,7 @@ final class AdminBottomSheetViewController: BaseViewController, View { make.edges.equalToSuperview() } - Logger.log(message: "์ตœ์ข… ๋ทฐ ๊ณ„์ธต:", category: .debug) + Logger.log("์ตœ์ข… ๋ทฐ ๊ณ„์ธต:", category: .debug) } private func setupCollectionView() { @@ -214,6 +214,6 @@ final class AdminBottomSheetViewController: BaseViewController, View { } deinit { - Logger.log(message: "BottomSheet deinit", category: .debug) + Logger.log("BottomSheet deinit", category: .debug) } } diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminReactor.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminReactor.swift index 33da143f..b023363b 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminReactor.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminReactor.swift @@ -56,9 +56,9 @@ final class AdminReactor: Reactor { .just(.setIsLoading(true)), adminUseCase.fetchStoreList(query: query, page: 0, size: 100) .do(onNext: { response in - Logger.log(message: "์กฐํšŒ ์„ฑ๊ณต - ์‘๋‹ต ๋ฐ์ดํ„ฐ: \(response)", category: .info) + Logger.log("์กฐํšŒ ์„ฑ๊ณต - ์‘๋‹ต ๋ฐ์ดํ„ฐ: \(response)", category: .info) }, onError: { error in - Logger.log(message: "์กฐํšŒ ์‹คํŒจ - ์—๋Ÿฌ: \(error.localizedDescription)", category: .error) + Logger.log("์กฐํšŒ ์‹คํŒจ - ์—๋Ÿฌ: \(error.localizedDescription)", category: .error) }) .map { .setStores($0) }, .just(.setIsLoading(false)) diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminRegister/PopUpStoreRegisterReactor.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminRegister/PopUpStoreRegisterReactor.swift index 324f2183..5ec2c51c 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminRegister/PopUpStoreRegisterReactor.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminRegister/PopUpStoreRegisterReactor.swift @@ -401,76 +401,76 @@ final class PopUpStoreRegisterReactor: Reactor { // ํผ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ private func validateForm(state: State) -> Bool { - Logger.log(message: "ํผ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹œ์ž‘", category: .debug) + Logger.log("ํผ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹œ์ž‘", category: .debug) // ์ด๋ฆ„ ํ•„๋“œ ๊ฒ€์‚ฌ guard !state.name.isEmpty else { - Logger.log(message: "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์ด๋ฆ„ ๋น„์–ด์žˆ์Œ", category: .debug) + Logger.log("์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์ด๋ฆ„ ๋น„์–ด์žˆ์Œ", category: .debug) return false } // ์ฃผ์†Œ ํ•„๋“œ ๊ฒ€์‚ฌ guard !state.address.isEmpty else { - Logger.log(message: "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์ฃผ์†Œ ๋น„์–ด์žˆ์Œ", category: .debug) + Logger.log("์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์ฃผ์†Œ ๋น„์–ด์žˆ์Œ", category: .debug) return false } // ์œ„๋„/๊ฒฝ๋„ ํ•„๋“œ ๊ฒ€์‚ฌ guard !state.lat.isEmpty else { - Logger.log(message: "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์œ„๋„ ๋น„์–ด์žˆ์Œ", category: .debug) + Logger.log("์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์œ„๋„ ๋น„์–ด์žˆ์Œ", category: .debug) return false } guard !state.lon.isEmpty else { - Logger.log(message: "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ๊ฒฝ๋„ ๋น„์–ด์žˆ์Œ", category: .debug) + Logger.log("์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ๊ฒฝ๋„ ๋น„์–ด์žˆ์Œ", category: .debug) return false } // ์„ค๋ช… ํ•„๋“œ ๊ฒ€์‚ฌ guard !state.description.isEmpty else { - Logger.log(message: "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์„ค๋ช… ๋น„์–ด์žˆ์Œ", category: .debug) + Logger.log("์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์„ค๋ช… ๋น„์–ด์žˆ์Œ", category: .debug) return false } // ์นดํ…Œ๊ณ ๋ฆฌ ํ•„๋“œ ๊ฒ€์‚ฌ guard !state.category.isEmpty else { - Logger.log(message: "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์นดํ…Œ๊ณ ๋ฆฌ ๋น„์–ด์žˆ์Œ", category: .debug) + Logger.log("์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์นดํ…Œ๊ณ ๋ฆฌ ๋น„์–ด์žˆ์Œ", category: .debug) return false } // ์ด๋ฏธ์ง€ ๊ฒ€์‚ฌ guard !state.images.isEmpty else { - Logger.log(message: "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์ด๋ฏธ์ง€ ์—†์Œ", category: .debug) + Logger.log("์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์ด๋ฏธ์ง€ ์—†์Œ", category: .debug) return false } // ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ ๊ฒ€์‚ฌ guard state.images.contains(where: { $0.isMain }) else { - Logger.log(message: "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ ์—†์Œ", category: .debug) + Logger.log("์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ ์—†์Œ", category: .debug) return false } // ๋‚ ์งœ ๊ฒ€์‚ฌ guard state.selectedStartDate != nil else { - Logger.log(message: "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์‹œ์ž‘ ๋‚ ์งœ ์—†์Œ", category: .debug) + Logger.log("์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์‹œ์ž‘ ๋‚ ์งœ ์—†์Œ", category: .debug) return false } guard state.selectedEndDate != nil else { - Logger.log(message: "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์ข…๋ฃŒ ๋‚ ์งœ ์—†์Œ", category: .debug) + Logger.log("์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์ข…๋ฃŒ ๋‚ ์งœ ์—†์Œ", category: .debug) return false } // ์œ„๋„/๊ฒฝ๋„ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ guard let latVal = Double(state.lat), let lonVal = Double(state.lon) else { - Logger.log(message: "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์œ„๋„/๊ฒฝ๋„ ํ˜•์‹ ์˜ค๋ฅ˜", category: .debug) + Logger.log("์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์œ„๋„/๊ฒฝ๋„ ํ˜•์‹ ์˜ค๋ฅ˜", category: .debug) return false } // ์œ„๋„/๊ฒฝ๋„ ๊ฐ’์ด ์œ ํšจํ•œ์ง€ ๊ฒ€์‚ฌ guard latVal != 0 || lonVal != 0 else { - Logger.log(message: "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์œ„๋„/๊ฒฝ๋„ ๊ฐ’์ด ๋ชจ๋‘ 0", category: .debug) + Logger.log("์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์œ„๋„/๊ฒฝ๋„ ๊ฐ’์ด ๋ชจ๋‘ 0", category: .debug) return false } @@ -478,17 +478,17 @@ final class PopUpStoreRegisterReactor: Reactor { if let startDate = state.selectedStartDate, let endDate = state.selectedEndDate, startDate > endDate { - Logger.log(message: "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์‹œ์ž‘์ผ์ด ์ข…๋ฃŒ์ผ๋ณด๋‹ค ๋Šฆ์Œ", category: .debug) + Logger.log("์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ: ์‹œ์ž‘์ผ์ด ์ข…๋ฃŒ์ผ๋ณด๋‹ค ๋Šฆ์Œ", category: .debug) return false } - Logger.log(message: "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์„ฑ๊ณต", category: .debug) + Logger.log("์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์„ฑ๊ณต", category: .debug) return true } // ์ฃผ์†Œ ์ง€์˜ค์ฝ”๋”ฉ private func geocodeAddress(address: String) -> Observable { - Logger.log(message: "์ง€์˜ค์ฝ”๋”ฉ ํ•จ์ˆ˜ ํ˜ธ์ถœ: \(address)", category: .debug) + Logger.log("์ง€์˜ค์ฝ”๋”ฉ ํ•จ์ˆ˜ ํ˜ธ์ถœ: \(address)", category: .debug) return Observable.create { observer in let geocoder = CLGeocoder() @@ -500,7 +500,7 @@ final class PopUpStoreRegisterReactor: Reactor { preferredLocale: Locale(identifier: "ko_KR") ) { placemarks, error in if let error = error { - Logger.log(message: "Geocoding error: \(error.localizedDescription)", category: .error) + Logger.log("Geocoding error: \(error.localizedDescription)", category: .error) observer.onNext(nil) observer.onCompleted() return @@ -525,10 +525,10 @@ final class PopUpStoreRegisterReactor: Reactor { preSignedUseCase.tryDelete(objectKeyList: imagePaths) .subscribe( onCompleted: { - Logger.log(message: "S3์—์„œ ๋ชจ๋“  ์ด๋ฏธ์ง€ ์‚ญ์ œ ์„ฑ๊ณต: \(imagePaths.count)๊ฐœ", category: .info) + Logger.log("S3์—์„œ ๋ชจ๋“  ์ด๋ฏธ์ง€ ์‚ญ์ œ ์„ฑ๊ณต: \(imagePaths.count)๊ฐœ", category: .info) }, onError: { error in - Logger.log(message: "S3์—์„œ ์ด๋ฏธ์ง€ ์‚ญ์ œ ์‹คํŒจ: \(error.localizedDescription)", category: .error) + Logger.log("S3์—์„œ ์ด๋ฏธ์ง€ ์‚ญ์ œ ์‹คํŒจ: \(error.localizedDescription)", category: .error) } ) .disposed(by: disposeBag) @@ -537,7 +537,7 @@ final class PopUpStoreRegisterReactor: Reactor { // ์นดํ…Œ๊ณ ๋ฆฌ ID ๋งคํ•‘ private func getCategoryId(from title: String) -> Int { let cleanTitle = title.replacingOccurrences(of: " โ–พ", with: "") - Logger.log(message: "์นดํ…Œ๊ณ ๋ฆฌ ๋งคํ•‘ ์‹œ์ž‘ - ํƒ€์ดํ‹€: \(cleanTitle)", category: .debug) + Logger.log("์นดํ…Œ๊ณ ๋ฆฌ ๋งคํ•‘ ์‹œ์ž‘ - ํƒ€์ดํ‹€: \(cleanTitle)", category: .debug) let categoryMap: [String: Int64] = [ "ํŒจ์…˜": 1, @@ -555,10 +555,10 @@ final class PopUpStoreRegisterReactor: Reactor { ] if let id = categoryMap[cleanTitle] { - Logger.log(message: "์นดํ…Œ๊ณ ๋ฆฌ ๋งคํ•‘ ์„ฑ๊ณต: \(cleanTitle) -> \(id)", category: .debug) + Logger.log("์นดํ…Œ๊ณ ๋ฆฌ ๋งคํ•‘ ์„ฑ๊ณต: \(cleanTitle) -> \(id)", category: .debug) return Int(id) } else { - Logger.log(message: "์นดํ…Œ๊ณ ๋ฆฌ ๋งคํ•‘ ์‹คํŒจ: \(cleanTitle)์— ํ•ด๋‹นํ•˜๋Š” ID๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Œ", category: .error) + Logger.log("์นดํ…Œ๊ณ ๋ฆฌ ๋งคํ•‘ ์‹คํŒจ: \(cleanTitle)์— ํ•ด๋‹นํ•˜๋Š” ID๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Œ", category: .error) return 1 // ๊ธฐ๋ณธ๊ฐ’ } } @@ -655,13 +655,13 @@ final class PopUpStoreRegisterReactor: Reactor { defer { dispatchGroup.leave() } if let error = error { - Logger.log(message: "์ด๋ฏธ์ง€ ๋กœ๋“œ ์˜ค๋ฅ˜: \(error.localizedDescription)", category: .error) + Logger.log("์ด๋ฏธ์ง€ ๋กœ๋“œ ์˜ค๋ฅ˜: \(error.localizedDescription)", category: .error) return } guard let data = data, let image = UIImage(data: data) else { - Logger.log(message: "์ด๋ฏธ์ง€ ๋ณ€ํ™˜ ์‹คํŒจ", category: .error) + Logger.log("์ด๋ฏธ์ง€ ๋ณ€ํ™˜ ์‹คํŒจ", category: .error) return } diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminStoreCell.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminStoreCell.swift index 2abf1f73..fca9ddfa 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminStoreCell.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminStoreCell.swift @@ -81,14 +81,14 @@ final class AdminStoreCell: UITableViewCell { // MARK: - Configure func configure(with store: AdminStore) { - Logger.log(message: "์…€ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ: \(store)", category: .debug) + Logger.log("์…€ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ: \(store)", category: .debug) titleLabel.text = store.name categoryLabel.text = store.categoryName statusChip.text = "์šด์˜" let imagePath = store.mainImageUrl.replacingOccurrences(of: Secrets.popPoolS3BaseURL, with: "") - Logger.log(message: "์ด๋ฏธ์ง€ ๊ฒฝ๋กœ: \(imagePath)", category: .debug) + Logger.log("์ด๋ฏธ์ง€ ๊ฒฝ๋กœ: \(imagePath)", category: .debug) storeImageView.setPPImage(path: imagePath) } } diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminViewController.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminViewController.swift index ddf71a45..6e31f7e6 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminViewController.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Admin/AdminViewController.swift @@ -223,7 +223,7 @@ final class AdminViewController: BaseViewController, View { allImageUrls = Array(Set(allImageUrls)) - Logger.log(message: "์‚ญ์ œํ•  ์ด๋ฏธ์ง€: \(allImageUrls.count)๊ฐœ", category: .debug) + Logger.log("์‚ญ์ œํ•  ์ด๋ฏธ์ง€: \(allImageUrls.count)๊ฐœ", category: .debug) @Dependency var preSignedUseCase: PreSignedUseCase preSignedUseCase.tryDelete(objectKeyList: allImageUrls) diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/CommentDetail/CommentDetailReactor.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/CommentDetail/CommentDetailReactor.swift index 510d5841..ba634aef 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/CommentDetail/CommentDetailReactor.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/CommentDetail/CommentDetailReactor.swift @@ -94,14 +94,14 @@ final class CommentDetailReactor: Reactor { newState.commentData.likeCount += 1 userAPIUseCase.postCommentLike(commentId: newState.commentData.commentID) .subscribe(onDisposed: { - Logger.log(message: "CommentLike", category: .info) + Logger.log("CommentLike", category: .info) }) .disposed(by: disposeBag) } else { newState.commentData.likeCount -= 1 userAPIUseCase.deleteCommentLike(commentId: newState.commentData.commentID) .subscribe(onDisposed: { - Logger.log(message: "CommentLikeDelete", category: .info) + Logger.log("CommentLikeDelete", category: .info) }) .disposed(by: disposeBag) } diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/CommentList/CommentListReactor.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/CommentList/CommentListReactor.swift index e0b71792..5f88d677 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/CommentList/CommentListReactor.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/CommentList/CommentListReactor.swift @@ -303,7 +303,7 @@ final class CommentListReactor: Reactor { let commentList = comment.imageList.compactMap { $0 } self.preSignedUseCase.tryDelete(objectKeyList: commentList) .subscribe(onDisposed: { - Logger.log(message: "S3 Image Delete ์™„๋ฃŒ", category: .info) + Logger.log("S3 Image Delete ์™„๋ฃŒ", category: .info) }) .disposed(by: self.disposeBag) case .edit: diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/NormalCommentAdd/NormalCommentAddReactor.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/NormalCommentAdd/NormalCommentAddReactor.swift index b68f78ed..9ff04140 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/NormalCommentAdd/NormalCommentAddReactor.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/NormalCommentAdd/NormalCommentAddReactor.swift @@ -223,11 +223,11 @@ extension NormalCommentAddReactor: PHPickerViewControllerDelegate { if let image = image as? UIImage { originImageList[index] = image // ๋กœ๋“œ๋œ ์ด๋ฏธ์ง€๋ฅผ ํ•ด๋‹น ์ธ๋ฑ์Šค์— ์ €์žฅ } else { - Logger.log(message: "Failed to load image", category: .error) + Logger.log("Failed to load image", category: .error) } } } else { - Logger.log(message: "ItemProvider Can Not Load Object", category: .error) + Logger.log("ItemProvider Can Not Load Object", category: .error) } } diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/NormalCommentEdit/NormalCommentEditReactor.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/NormalCommentEdit/NormalCommentEditReactor.swift index 1ad07a70..dc616f45 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/NormalCommentEdit/NormalCommentEditReactor.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Comment/NormalCommentEdit/NormalCommentEditReactor.swift @@ -261,11 +261,11 @@ extension NormalCommentEditReactor: PHPickerViewControllerDelegate { if let image = image as? UIImage { originImageList[index] = image // ๋กœ๋“œ๋œ ์ด๋ฏธ์ง€๋ฅผ ํ•ด๋‹น ์ธ๋ฑ์Šค์— ์ €์žฅ } else { - Logger.log(message: "Failed to load image", category: .error) + Logger.log("Failed to load image", category: .error) } } } else { - Logger.log(message: "ItemProvider Can Not Load Object", category: .error) + Logger.log("ItemProvider Can Not Load Object", category: .error) } } diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Detail/DetailReactor.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Detail/DetailReactor.swift index 43b3121c..6c766d50 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Detail/DetailReactor.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Detail/DetailReactor.swift @@ -426,23 +426,23 @@ extension DetailReactor { // URL ์ธ์ฝ”๋”ฉ ํ›„ ์ƒ์„ฑ guard let encodedPath = imagePath.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), let url = URL(string: encodedPath) else { - Logger.log(message: "URL ์ƒ์„ฑ ์‹คํŒจ", category: .error) + Logger.log("URL ์ƒ์„ฑ ์‹คํŒจ", category: .error) return } // ๐Ÿ”น ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ URLSession.shared.dataTask(with: url) { data, _, error in if let error = error { - Logger.log(message: "๋‹ค์šด๋กœ๋“œ ์‹คํŒจ", category: .error) + Logger.log("๋‹ค์šด๋กœ๋“œ ์‹คํŒจ", category: .error) return } guard let data = data, let image = UIImage(data: data) else { - Logger.log(message: "์ด๋ฏธ์ง€ ๋ณ€ํ™˜ ์‹คํŒจ", category: .error) + Logger.log("์ด๋ฏธ์ง€ ๋ณ€ํ™˜ ์‹คํŒจ", category: .error) return } - Logger.log(message: "์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ ์„ฑ๊ณต", category: .info) + Logger.log("์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ ์„ฑ๊ณต", category: .info) let sharedText = "[ํŒํ’€] \(storeName) ํŒ์—… ์–ด๋•Œ์š”?\n์ง€๊ธˆ ๋ฐ”๋กœ ํŒํ’€์—์„œ ํ™•์ธํ•ด๋ณด์„ธ์š”!" // UI ์—…๋ฐ์ดํŠธ๋Š” ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰ @@ -545,7 +545,7 @@ extension DetailReactor { let commentList = comment.imageList.compactMap { $0 } self.preSignedUseCase.tryDelete(objectKeyList: commentList) .subscribe(onDisposed: { - Logger.log(message: "S3 Image Delete ์™„๋ฃŒ", category: .info) + Logger.log("S3 Image Delete ์™„๋ฃŒ", category: .info) }) .disposed(by: self.disposeBag) diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FillterSheetView/BalloonBackgroundView.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FillterSheetView/BalloonBackgroundView.swift index 45161c19..e5cc9467 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FillterSheetView/BalloonBackgroundView.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FillterSheetView/BalloonBackgroundView.swift @@ -27,15 +27,15 @@ final class BalloonBackgroundView: UIView { let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) group.interItemSpacing = .fixed(8) let section = NSCollectionLayoutSection(group: group) - section.contentInsets = .init(top: 20, leading: 20, bottom: 19, trailing: 20) + section.contentInsets = .init(top: 18, leading: 20, bottom: 19, trailing: 20) section.interGroupSpacing = 8 return section } - let cv = UICollectionView(frame: .zero, collectionViewLayout: layout) - cv.backgroundColor = .clear - cv.isScrollEnabled = false - cv.register(BalloonChipCell.self, forCellWithReuseIdentifier: BalloonChipCell.identifier) - return cv + let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.backgroundColor = .clear + collectionView.isScrollEnabled = false + collectionView.register(BalloonChipCell.self, forCellWithReuseIdentifier: BalloonChipCell.identifier) + return collectionView }() // "๊ทธ ์™ธ ์ง€์—ญ" ์ „์šฉ UI: ์•„์ด์ฝ˜๊ณผ ์•ˆ๋‚ด๋ฌธ๊ตฌ @@ -104,7 +104,7 @@ final class BalloonBackgroundView: UIView { containerView.snp.makeConstraints { make in make.left.right.equalToSuperview() make.top.equalToSuperview().offset(arrowHeight) - make.bottom.equalToSuperview().priority(.high) + make.bottom.equalToSuperview() } containerView.addSubview(collectionView) @@ -114,7 +114,7 @@ final class BalloonBackgroundView: UIView { collectionView.snp.makeConstraints { make in make.top.left.right.equalToSuperview() - make.bottom.equalToSuperview().priority(.high) + make.bottom.equalToSuperview() } singleRegionIcon.snp.makeConstraints { make in diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FillterSheetView/BalloonChipCell.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FillterSheetView/BalloonChipCell.swift index 964e5995..81b1f4b5 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FillterSheetView/BalloonChipCell.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FillterSheetView/BalloonChipCell.swift @@ -41,7 +41,7 @@ final class BalloonChipCell: UICollectionViewCell { button.setImage(resizedImage, for: .normal) button.semanticContentAttribute = .forceRightToLeft button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 2, bottom: 0, right: 0) - button.contentEdgeInsets = UIEdgeInsets(top: 6, left: 10, bottom: 6, right: 12) + button.contentEdgeInsets = UIEdgeInsets(top: 4, left: 10, bottom: 6, right: 12) button.setBackgroundColor(.blu500, for: .normal) button.setTitleColor(.white, for: .normal) button.layer.borderWidth = 0 @@ -51,7 +51,7 @@ final class BalloonChipCell: UICollectionViewCell { button.setImage(nil, for: .normal) button.semanticContentAttribute = .unspecified button.imageEdgeInsets = .zero - button.contentEdgeInsets = UIEdgeInsets(top: 6, left: 12, bottom: 6, right: 12) + button.contentEdgeInsets = UIEdgeInsets(top: 4, left: 12, bottom: 6, right: 12) button.setBackgroundColor(.white, for: .normal) button.setTitleColor(.g400, for: .normal) button.layer.borderWidth = 1 diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FillterSheetView/FilterChip.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FillterSheetView/FilterChip.swift index 3ad18fc0..ec0fa088 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FillterSheetView/FilterChip.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FillterSheetView/FilterChip.swift @@ -72,7 +72,7 @@ final class FilterChip: UIButton { } let rightPadding: CGFloat = closeButton.isHidden ? 12 : 34 - contentEdgeInsets = UIEdgeInsets(top: 7, left: 12, bottom: 7, right: rightPadding) + contentEdgeInsets = UIEdgeInsets(top: 5, left: 12, bottom: 7, right: rightPadding) } // MARK: - Actions diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FindMap/MapGuideView/FullScreenMapViewController.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FindMap/MapGuideView/FullScreenMapViewController.swift index b6f8989a..66be0ba2 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FindMap/MapGuideView/FullScreenMapViewController.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FindMap/MapGuideView/FullScreenMapViewController.swift @@ -34,10 +34,10 @@ class FullScreenMapViewController: MapViewController { setupNavigation() // configureInitialMapPosition() self.navigationController?.navigationBar.isHidden = false - Logger.log(message: "๐Ÿ’ก ์ดˆ๊ธฐ ์œ„์น˜ ๊ตฌ์„ฑ ์ง์ „: initialStore=\(String(describing: initialStore?.name))", category: .debug) + Logger.log("๐Ÿ’ก ์ดˆ๊ธฐ ์œ„์น˜ ๊ตฌ์„ฑ ์ง์ „: initialStore=\(String(describing: initialStore?.name))", category: .debug) configureInitialMapPosition() - Logger.log(message: "โœ… FullScreenMapViewController - viewDidLoad ์™„๋ฃŒ", category: .debug) + Logger.log("โœ… FullScreenMapViewController - viewDidLoad ์™„๋ฃŒ", category: .debug) mainView.mapView.touchDelegate = self } diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FindMap/MapGuideView/MapGuideReactor.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FindMap/MapGuideView/MapGuideReactor.swift index a51aa8ab..2bff7fda 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FindMap/MapGuideView/MapGuideReactor.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FindMap/MapGuideView/MapGuideReactor.swift @@ -121,11 +121,8 @@ final class MapGuideReactor: Reactor { return Observable.just(.showToast("์ง€์›ํ•˜์ง€ ์•Š๋Š” ๋งต ์•ฑ์ž…๋‹ˆ๋‹ค.")) } - Logger.log(message: "๐Ÿ—บ ๋งต ์•ฑ ์—ด๊ธฐ ์‹œ๋„: \(urlScheme)", category: .debug) - if let url = URL(string: urlScheme) { if UIApplication.shared.canOpenURL(url) { - Logger.log(message: "โœ… \(appType) ์•ฑ ์‹คํ–‰", category: .debug) UIApplication.shared.open(url, options: [:], completionHandler: nil) return Observable.empty() } else { @@ -133,7 +130,7 @@ final class MapGuideReactor: Reactor { if appType.lowercased() == "apple" { return Observable.just(.showToast("์• ํ”Œ ์ง€๋„ ์•ฑ์„ ์—ด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")) } else { - Logger.log(message: "โŒ \(appType) ์•ฑ ๋ฏธ์„ค์น˜ - ์•ฑ์Šคํ† ์–ด๋กœ ์ด๋™", category: .debug) + Logger.log("โŒ \(appType) ์•ฑ ๋ฏธ์„ค์น˜ - ์•ฑ์Šคํ† ์–ด๋กœ ์ด๋™", category: .debug) if let appStoreURL = URL(string: appStoreUrl) { UIApplication.shared.open(appStoreURL, options: [:], completionHandler: nil) } diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/MapView/MapMarker.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/MapView/MapMarker.swift index be525bb3..a79bf643 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/MapView/MapMarker.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/MapView/MapMarker.swift @@ -65,7 +65,7 @@ final class MapMarker: UIView { // MARK: - Init init() { - super.init(frame: CGRect(x: 0, y: 0, width: 80, height: 32)) + super.init(frame: CGRect(x: 0, y: 0, width: 32, height: 32)) setUpConstraints() } @@ -86,10 +86,8 @@ private extension MapMarker { labelStackView.addArrangedSubview(countLabel) countBadgeView.addSubview(badgeCountLabel) - self.snp.makeConstraints { make in - make.width.equalTo(200) - make.height.equalTo(70) - } + // ๊ณ ์ •๋œ ํฌ๊ธฐ ์ œ์•ฝ์กฐ๊ฑด ์ œ๊ฑฐ + // ๋Œ€์‹  ๋‚ด๋ถ€ ์ปจํ…์ธ ์— ๋งž๊ฒŒ ํฌ๊ธฐ๊ฐ€ ์กฐ์ •๋˜๋„๋ก ๋ณ€๊ฒฝ markerImageView.snp.makeConstraints { make in make.centerX.equalToSuperview() @@ -99,12 +97,12 @@ private extension MapMarker { clusterContainer.snp.makeConstraints { make in make.center.equalToSuperview() - make.height.equalTo(24) - make.width.equalTo(80) + make.height.equalTo(32) + make.width.greaterThanOrEqualTo(80) } labelStackView.snp.makeConstraints { make in - make.edges.equalToSuperview().inset(UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)) + make.edges.equalToSuperview().inset(UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 12)) } countBadgeView.snp.makeConstraints { make in @@ -140,10 +138,14 @@ private extension MapMarker { countBadgeView.snp.remakeConstraints { make in make.width.height.equalTo(20) - make.top.equalTo(markerImageView.snp.top).offset(isSelected ? 0 : -4) - make.right.equalTo(markerImageView.snp.right).offset(isSelected ? 0 : 4) + if isSelected { + make.top.equalTo(markerImageView.snp.top).offset(-4) + make.right.equalTo(markerImageView.snp.right).offset(4) + } else { + make.top.equalTo(markerImageView.snp.top).offset(-4) + make.right.equalTo(markerImageView.snp.right).offset(4) + } } - self.layoutIfNeeded() CATransaction.commit() } @@ -188,8 +190,10 @@ extension MapMarker: Inputable { regionLabel.text = input.regionName countLabel.text = " \(input.count)" + // ํด๋Ÿฌ์Šคํ„ฐ ๋งˆ์ปค ํฌ๊ธฐ ๊ณ„์‚ฐ - ํ…์ŠคํŠธ ๋‚ด์šฉ์— ๋งž๊ฒŒ ๋™์ ์œผ๋กœ ์กฐ์ • + labelStackView.layoutIfNeeded() let stackSize = labelStackView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) - let requiredWidth = stackSize.width + 24 + let requiredWidth = max(stackSize.width + 24, 80) // ์ตœ์†Œ ๋„ˆ๋น„ ๋ณด์žฅ clusterContainer.snp.remakeConstraints { make in make.center.equalToSuperview() @@ -200,18 +204,33 @@ extension MapMarker: Inputable { labelStackView.snp.remakeConstraints { make in make.edges.equalToSuperview().inset(UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 12)) } + + self.frame.size = CGSize(width: requiredWidth, height: 32) } private func setupSingleMarker(_ input: Input) { markerImageView.isHidden = false clusterContainer.isHidden = true + updateMarkerImage(isSelected: input.isSelected) + let size = input.isSelected ? 44 : 32 + if input.count > 1 { countBadgeView.isHidden = false badgeCountLabel.text = "\(input.count)" + + countBadgeView.snp.remakeConstraints { make in + make.width.height.equalTo(20) + make.top.equalTo(markerImageView.snp.top).offset(input.isSelected ? 0 : -4) + make.right.equalTo(markerImageView.snp.right).offset(input.isSelected ? 2 : 4) + } + + self.frame.size = CGSize(width: size + 8, height: size) } else { countBadgeView.isHidden = true + + self.frame.size = CGSize(width: size, height: size) } } } @@ -222,6 +241,18 @@ extension MapMarker { } func asImage() -> UIImage? { + if let input = currentInput { + if input.isCluster { + self.layoutIfNeeded() + let clusterSize = clusterContainer.bounds.size + self.frame = CGRect(x: 0, y: 0, width: clusterSize.width + 8, height: clusterSize.height + 8) + } else { + let size = input.isSelected ? 44 : 32 + let extraWidth = (input.count > 1) ? 10 : 0 + self.frame = CGRect(x: 0, y: 0, width: size + extraWidth, height: size + 4) + } + } + self.layoutIfNeeded() UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, UIScreen.main.scale) defer { UIGraphicsEndImageContext() } diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/MapView/MapReactor.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/MapView/MapReactor.swift index dd6d5db1..3c8405c9 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/MapView/MapReactor.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/MapView/MapReactor.swift @@ -225,7 +225,7 @@ final class MapReactor: Reactor { }, onError: { error in Logger.log( - message: "โŒ [์—๋Ÿฌ]: ์š”์ฒญ ์‹คํŒจ - \(error.localizedDescription)", + "โŒ [์—๋Ÿฌ]: ์š”์ฒญ ์‹คํŒจ - \(error.localizedDescription)", category: .error ) }, @@ -353,7 +353,7 @@ final class MapReactor: Reactor { } Logger.log( - message: """ + """ Updated viewport stores: - Total: \(updatedStores.count) - Selected Store: \(state.selectedStore?.name ?? "None") @@ -370,7 +370,7 @@ final class MapReactor: Reactor { newState.error = error if let error = error { Logger.log( - message: """ + """ Error occurred in MapReactor: - Description: \(error.localizedDescription) - Domain: \(String(describing: (error as NSError).domain)) diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/MapView/MapViewController.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/MapView/MapViewController.swift index 39e20a31..6e6923b8 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/MapView/MapViewController.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/MapView/MapViewController.swift @@ -59,7 +59,7 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM private var filterChipsTopY: CGFloat = 0 private var filterContainerBottomY: CGFloat { let frameInView = mainView.filterChips.convert(mainView.filterChips.bounds, to: view) - return frameInView.maxY // ํ•„ํ„ฐ ์ปจํ…Œ์ด๋„ˆ์˜ ๋ฐ”๋‹ฅ ๋†’์ด + return frameInView.maxY } enum ModalState { @@ -70,6 +70,7 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM private var modalState: ModalState = .bottom private let idleSubject = PublishSubject() + private let cameraIdle = PublishSubject() // MARK: - Lifecycle override func viewDidAppear(_ animated: Bool) { @@ -99,8 +100,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM if let reactor = self.reactor { reactor.action.onNext(.fetchCategories) - - // ํ•œ๊ตญ ์ „์ฒด ์˜์—ญ์— ๋Œ€ํ•œ ๊ฒฝ๊ณ„๊ฐ’ ์„ค์ • let koreaRegion = ( northEast: NMGLatLng(lat: 38.0, lng: 132.0), southWest: NMGLatLng(lat: 33.0, lng: 124.0) @@ -113,7 +112,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM southWestLon: koreaRegion.southWest.lng )) } - setupMapViewRxObservables() carouselView.rx.observe(Bool.self, "hidden") @@ -146,21 +144,15 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM pageIndex < self.currentCarouselStores.count else { return } let store = self.currentCarouselStores[pageIndex] - - // ์ด์ „ ์„ ํƒ ๋งˆ์ปค ์ƒํƒœ ์ดˆ๊ธฐํ™” if let previousMarker = self.currentMarker { self.updateMarkerStyle(marker: previousMarker, selected: false, isCluster: false, count: 1) } - // ์Šค์™€์ดํ”„ํ•œ ์Šคํ† ์–ด์— ํ•ด๋‹นํ•˜๋Š” ๋งˆ์ปค ์ฐพ๊ธฐ let markerToFocus = self.findMarkerForStore(for: store) if let markerToFocus = markerToFocus { - // ๋งˆ์ปค ์„ ํƒ ์ƒํƒœ๋กœ ์—…๋ฐ์ดํŠธ self.updateMarkerStyle(marker: markerToFocus, selected: true, isCluster: false, count: 1) self.currentMarker = markerToFocus - - // ๋งˆ์ดํฌ๋กœ ํด๋Ÿฌ์Šคํ„ฐ์ธ ๊ฒฝ์šฐ ํˆดํŒ ์ฒ˜๋ฆฌ let userData = markerToFocus.userInfo["storeData"] as? [MapPopUpStore] if let storeArray = userData, storeArray.count > 1 { if self.currentTooltipView == nil || @@ -187,10 +179,21 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM } } - // NMF ์ด๋ฒคํŠธ ์„ค์ •์„ ์œ„ํ•œ ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ private func setupMapViewRxObservables() { - // ์ง€๋„ ์ด๋™ ์™„๋ฃŒ ๊ฐ์ง€ mainView.mapView.addCameraDelegate(delegate: self) + cameraIdle + .debounce(.milliseconds(300), scheduler: MainScheduler.instance) + .map { [unowned self] in + let bounds = self.getVisibleBounds() + return MapReactor.Action.viewportChanged( + northEastLat: bounds.northEast.lat, + northEastLon: bounds.northEast.lng, + southWestLat: bounds.southWest.lat, + southWestLon: bounds.southWest.lng + ) + } + .bind(to: reactor!.action) + .disposed(by: disposeBag) idleSubject .observe(on: MainScheduler.instance) @@ -211,13 +214,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM } private func configureTooltip(for marker: NMFMarker, stores: [MapPopUpStore]) { - Logger.log(message: """ - ํˆดํŒ ์„ค์ •: - - ํ˜„์žฌ ์บ๋Ÿฌ์…€ ์Šคํ† ์–ด: \(currentCarouselStores.map { $0.name }) - - ๋งˆ์ปค ์Šคํ† ์–ด: \(stores.map { $0.name }) - """, category: .debug) - - // ๊ธฐ์กด ํˆดํŒ ์ œ๊ฑฐ self.currentTooltipView?.removeFromSuperview() let tooltipView = MarkerTooltipView() @@ -233,12 +229,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM self.updateMarkerStyle(marker: marker, selected: true, isCluster: false, count: stores.count) tooltipView.selectStore(at: index) - - Logger.log(message: """ - ํˆดํŒ ์„ ํƒ: - - ์„ ํƒ๋œ ์Šคํ† ์–ด: \(stores[index].name) - - ํˆดํŒ ์ธ๋ฑ์Šค: \(index) - """, category: .debug) } let markerPoint = self.mainView.mapView.projection.point(from: marker.position) @@ -289,8 +279,7 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM setupPanAndSwipeGestures() let mapViewTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleMapViewTap(_:))) -// mapViewTapGesture.cancelsTouchesInView = false // ์ค‘์š”: ๋‹ค๋ฅธ ํ„ฐ์น˜ ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉํ•ดํ•˜์ง€ ์•Š์Œ - mapViewTapGesture.delaysTouchesBegan = false // ํ„ฐ์น˜ ์ง€์—ฐ ์—†์Œ + mapViewTapGesture.delaysTouchesBegan = false mainView.mapView.addGestureRecognizer(mapViewTapGesture) mapViewTapGesture.delegate = self } @@ -301,7 +290,7 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM .skip(1) .withUnretained(self) .subscribe { owner, _ in - Logger.log(message: "โฌ†๏ธ ์œ„๋กœ ์Šค์™€์ดํ”„ ๊ฐ์ง€", category: .debug) + Logger.log("โฌ†๏ธ ์œ„๋กœ ์Šค์™€์ดํ”„ ๊ฐ์ง€", category: .debug) switch owner.modalState { case .bottom: owner.animateToState(.middle) @@ -317,7 +306,7 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM .skip(1) .withUnretained(self) .subscribe { owner, _ in - Logger.log(message: "โฌ‡๏ธ ์•„๋ž˜๋กœ ์Šค์™€์ดํ”„ ๊ฐ์ง€๋จ", category: .debug) + Logger.log("โฌ‡๏ธ ์•„๋ž˜๋กœ ์Šค์™€์ดํ”„ ๊ฐ์ง€๋จ", category: .debug) switch owner.modalState { case .top: owner.animateToState(.middle) @@ -332,7 +321,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM // MARK: - Bind func bind(reactor: Reactor) { - // ํ•„ํ„ฐ ๊ด€๋ จ ๋ฐ”์ธ๋”ฉ mainView.filterChips.locationChip.rx.tap .map { Reactor.Action.filterTapped(.location) } .bind(to: reactor.action) @@ -343,11 +331,10 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM .bind(to: reactor.action) .disposed(by: disposeBag) - // ๋ฆฌ์ŠคํŠธ ๋ฒ„ํŠผ ํƒญ mainView.listButton.rx.tap .withUnretained(self) .subscribe { owner, _ in - owner.animateToState(.middle) // ๋ฒ„ํŠผ ๋ˆŒ๋ €์„ ๋•Œ ์ƒํƒœ๋ฅผ middle๋กœ ๋ณ€๊ฒฝ + owner.animateToState(.middle) } .disposed(by: disposeBag) @@ -356,8 +343,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM .bind { [weak self] _ in guard let self = self, let location = self.locationManager.location else { return } - - // ํ˜„์žฌ ์œ„์น˜๋กœ ์นด๋ฉ”๋ผ ์ด๋™ let cameraUpdate = NMFCameraUpdate(scrollTo: NMGLatLng( lat: location.coordinate.latitude, lng: location.coordinate.longitude @@ -369,10 +354,7 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM mainView.filterChips.onRemoveLocation = { [weak self] in guard let self = self else { return } - // ํ•„ํ„ฐ ์ œ๊ฑฐ ์•ก์…˜ self.reactor?.action.onNext(.clearFilters(.location)) - - // ํ˜„์žฌ ๋ทฐํฌํŠธ์˜ ๋ฐ”์šด๋“œ๋กœ ๋งˆ์ปค ์—…๋ฐ์ดํŠธ ์š”์ฒญ let bounds = self.getVisibleBounds() self.reactor?.action.onNext(.viewportChanged( northEastLat: bounds.northEast.lat, @@ -385,7 +367,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM self.clusterMarkerDictionary.values.forEach { $0.mapView = nil } self.clusterMarkerDictionary.removeAll() - // ์บ๋Ÿฌ์…€ ์ˆจ๊ธฐ๊ธฐ ์ถ”๊ฐ€ self.carouselView.isHidden = true self.carouselView.updateCards([]) self.currentCarouselStores = [] @@ -396,10 +377,7 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM mainView.filterChips.onRemoveCategory = { [weak self] in guard let self = self else { return } - // ํ•„ํ„ฐ ์ œ๊ฑฐ ์•ก์…˜ self.reactor?.action.onNext(.clearFilters(.category)) - - // ํ˜„์žฌ ๋ทฐํฌํŠธ์˜ ๋ฐ”์šด๋“œ๋กœ ๋งˆ์ปค ์—…๋ฐ์ดํŠธ ์š”์ฒญ let bounds = self.getVisibleBounds() self.reactor?.action.onNext(.viewportChanged( northEastLat: bounds.northEast.lat, @@ -419,7 +397,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM reactor.state.map { $0.selectedLocationFilters }.distinctUntilChanged(), reactor.state.map { $0.selectedCategoryFilters }.distinctUntilChanged() ) { locationFilters, categoryFilters -> (String, String) in - // ์ง€์—ญ ํ•„ํ„ฐ ํ…์ŠคํŠธ ํฌ๋งทํŒ… let locationText: String if locationFilters.isEmpty { locationText = "์ง€์—ญ์„ ํƒ" @@ -428,8 +405,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM } else { locationText = locationFilters[0] } - - // ์นดํ…Œ๊ณ ๋ฆฌ ํ•„ํ„ฐ ํ…์ŠคํŠธ ํฌ๋งทํŒ… let categoryText: String if categoryFilters.isEmpty { categoryText = "์นดํ…Œ๊ณ ๋ฆฌ" @@ -469,7 +444,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM .bind { [weak self] store in guard let self = self else { return } - // ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ์œ„์น˜๋กœ ์นด๋ฉ”๋ผ ์ด๋™ let cameraUpdate = NMFCameraUpdate(scrollTo: NMGLatLng( lat: store.latitude, lng: store.longitude @@ -499,25 +473,19 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM .bind { [weak self] results in guard let self = self else { return } - // ์ด์ „ ์„ ํƒ๋œ ๋งˆ์ปค, ํˆดํŒ, ์บ๋Ÿฌ์…€ ์ดˆ๊ธฐํ™” self.clearAllMarkers() self.storeListViewController.reactor?.action.onNext(.setStores([])) self.carouselView.updateCards([]) self.carouselView.isHidden = true self.resetSelectedMarker() // ์ถ”๊ฐ€๋œ ๋ถ€๋ถ„ - // ๊ฒฐ๊ณผ๊ฐ€ ์—†์œผ๋ฉด ์Šคํ† ์–ด ์นด๋“œ ์ˆจ๊น€ ํ›„ ์ข…๋ฃŒ if results.isEmpty { self.mainView.setStoreCardHidden(true, animated: true) return } else { self.mainView.setStoreCardHidden(false, animated: true) } - - // ์ƒˆ ๊ฒฐ๊ณผ๋กœ ๋งˆ์ปค ์ถ”๊ฐ€ ๋ฐ ์—…๋ฐ์ดํŠธ self.addMarkers(for: results) - - // ์Šคํ† ์–ด ๋ฆฌ์ŠคํŠธ ์—…๋ฐ์ดํŠธ let storeItems = results.map { store in StoreItem( id: store.id, @@ -530,13 +498,9 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM ) } self.storeListViewController.reactor?.action.onNext(.setStores(storeItems)) - - // ์บ๋Ÿฌ์…€ ์—…๋ฐ์ดํŠธ self.carouselView.updateCards(results) self.carouselView.isHidden = false self.currentCarouselStores = results - - // ์ฒซ ๋ฒˆ์งธ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋กœ ์ง€๋„ ์ด๋™ if let firstStore = results.first { let cameraUpdate = NMFCameraUpdate(scrollTo: NMGLatLng( lat: firstStore.latitude, @@ -573,9 +537,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM // ์ค‘์š”: ๋งˆ์ปค์— ์ง์ ‘ ํ„ฐ์น˜ ํ•ธ๋“ค๋Ÿฌ ์ถ”๊ฐ€ marker.touchHandler = { [weak self] (_) -> Bool in guard let self = self else { return false } - - Logger.log(message: "๋งˆ์ปค ํ„ฐ์น˜๋จ! ์œ„์น˜: \(marker.position), ์Šคํ† ์–ด: \(store.name)", category: .debug) - // ๋‹จ์ผ ์Šคํ† ์–ด ๋งˆ์ปค ์ฒ˜๋ฆฌ return self.handleSingleStoreTap(marker, store: store) } @@ -584,34 +545,42 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM markerDictionary[store.id] = marker } - func updateMarkerStyle(marker: NMFMarker, selected: Bool, isCluster: Bool, count: Int = 1, regionName: String = "") { - if selected { - marker.width = 44 - marker.height = 44 - marker.iconImage = NMFOverlayImage(name: "TapMarker") - } else if isCluster { - marker.width = 36 - marker.height = 36 - marker.iconImage = NMFOverlayImage(name: "cluster_marker") + func updateMarkerStyle( + marker: NMFMarker, + selected: Bool, + isCluster: Bool, + count: Int = 1, + regionName: String = "" + ) { + let mapMarkerView: MapMarker + if let cachedView = marker.userInfo["mapMarkerView"] as? MapMarker { + mapMarkerView = cachedView } else { - marker.width = 32 - marker.height = 32 - marker.iconImage = NMFOverlayImage(name: "Marker") + mapMarkerView = MapMarker() + marker.userInfo["mapMarkerView"] = mapMarkerView } - if count > 1 { - marker.captionText = "\(count)" - } else { - marker.captionText = "" - } + let wasMultiMarker = (mapMarkerView.currentInput?.count ?? 0) > 1 - marker.anchor = CGPoint(x: 0.5, y: 1.0) + let input = MapMarker.Input( + isSelected: selected, + isCluster: isCluster, + regionName: regionName, + count: count, + isMultiMarker: count > 1 && !isCluster + ) + mapMarkerView.injection(with: input) + + if let img = mapMarkerView.asImage() { + marker.iconImage = NMFOverlayImage(image: img) + marker.width = img.size.width + marker.height = img.size.height + marker.anchor = CGPoint(x: 0.5, y: isCluster ? 0.5 : 1.0) + } } @objc private func handleMapViewTap(_ gesture: UITapGestureRecognizer) { - // ๋ฆฌ์ŠคํŠธ๋ทฐ๊ฐ€ ํ˜„์žฌ ๋ณด์ด๋Š” ์ƒํƒœ(์ค‘๊ฐ„ ๋˜๋Š” ์ƒ๋‹จ)์ผ ๋•Œ๋งŒ ๋‚ด๋ฆผ if modalState == .middle || modalState == .top { - Logger.log(message: "๋งต๋ทฐ ํƒญ ๊ฐ์ง€: ๋ฆฌ์ŠคํŠธ๋ทฐ ๋‚ด๋ฆผ", category: .debug) animateToState(.bottom) } } @@ -626,9 +595,8 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM let currentOffset = constraint.layoutConstraints.first?.constant ?? 0 let newOffset = currentOffset + translation.y - // ์˜คํ”„์…‹ ์ œํ•œ ๋ฒ”์œ„ ์„ค์ • - let minOffset: CGFloat = filterContainerBottomY // ํ•„ํ„ฐ ์ปจํ…Œ์ด๋„ˆ ๋ฐ”๋‹ฅ ์ œํ•œ - let maxOffset: CGFloat = view.frame.height // ์ตœํ•˜๋‹จ ์ œํ•œ + let minOffset: CGFloat = filterContainerBottomY + let maxOffset: CGFloat = view.frame.height let clampedOffset = min(max(newOffset, minOffset), maxOffset) constraint.update(offset: clampedOffset) @@ -642,13 +610,12 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM case .ended: if let constraint = listViewTopConstraint { let currentOffset = constraint.layoutConstraints.first?.constant ?? 0 - let middleY = view.frame.height * 0.3 // ์ค‘๊ฐ„ ์ง€์  ๊ธฐ์ค€ ๋†’์ด + let middleY = view.frame.height * 0.3 let targetState: ModalState - // ์†๋„์™€ ์œ„์น˜๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒํƒœ ๊ฒฐ์ • - if velocity.y > 500 { // ์•„๋ž˜๋กœ ๋น ๋ฅด๊ฒŒ ๋“œ๋ž˜๊ทธ + if velocity.y > 500 { targetState = .bottom - } else if velocity.y < -500 { // ์œ„๋กœ ๋น ๋ฅด๊ฒŒ ๋“œ๋ž˜๊ทธ + } else if velocity.y < -500 { targetState = .top } else if currentOffset < middleY * 0.7 { targetState = .top @@ -670,9 +637,9 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM let middleOffset = view.frame.height * 0.3 if offset <= minOffset { - mainView.mapView.alpha = 0 // ํƒ‘์—์„œ๋Š” ์™„์ „ํžˆ ์ˆจ๊น€ + mainView.mapView.alpha = 0 } else if offset >= maxOffset { - mainView.mapView.alpha = 1 // ๋ฐ”ํ…€์—์„œ๋Š” ์™„์ „ํžˆ ๋ณด์ž„ + mainView.mapView.alpha = 1 } else if offset <= middleOffset { let progress = (offset - minOffset) / (middleOffset - minOffset) mainView.mapView.alpha = progress @@ -697,7 +664,7 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM self.mainView.filterChips.bounds, to: self.view ) - self.mainView.mapView.alpha = 0 // ํƒ‘ ์ƒํƒœ์—์„œ๋Š” ์ˆจ๊น€ + self.mainView.mapView.alpha = 0 self.storeListViewController.setGrabberHandleVisible(false) self.listViewTopConstraint?.update(offset: filterChipsFrame.maxY) self.mainView.searchInput.setBackgroundColor(.g50) @@ -726,7 +693,7 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM self.fetchStoreDetails(for: stores) Logger.log( - message: "โœ… ์ „์ฒด ์Šคํ† ์–ด ๋ชฉ๋ก์œผ๋กœ ๋ฆฌ์ŠคํŠธ๋ทฐ ์—…๋ฐ์ดํŠธ: \(stores.count)๊ฐœ", + "โœ… ์ „์ฒด ์Šคํ† ์–ด ๋ชฉ๋ก์œผ๋กœ ๋ฆฌ์ŠคํŠธ๋ทฐ ์—…๋ฐ์ดํŠธ: \(stores.count)๊ฐœ", category: .debug ) }) @@ -744,7 +711,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM self.view.layoutIfNeeded() }) { _ in self.modalState = state - Logger.log(message: ". ํ˜„์žฌ ์ƒํƒœ: \(state)", category: .debug) } } @@ -760,15 +726,13 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM // MARK: - Helper: ํด๋Ÿฌ์Šคํ„ฐ์šฉ ์ปค์Šคํ…€ ๋งˆ์ปค ์ด๋ฏธ์ง€ ์ƒ์„ฑ (MapMarker๋ฅผ ์‚ฌ์šฉ) func createClusterMarkerImage(regionName: String, count: Int) -> UIImage? { - // MapMarker์˜ ์ž…๋ ฅ๊ฐ’์— ํด๋Ÿฌ์Šคํ„ฐ ์ƒํƒœ๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. - let markerView = MapMarker() // ๊ธฐ์กด ์ปค์Šคํ…€ ๋ทฐ, ๋„ค์ด๋ฒ„๋งต์šฉ์œผ๋กœ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋„๋ก ๊ตฌํ˜„๋จ. + let markerView = MapMarker() let input = MapMarker.Input(isSelected: false, isCluster: true, regionName: regionName, count: count, isMultiMarker: false) markerView.injection(with: input) - // ํ”„๋ ˆ์ž„์ด ์„ค์ •๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค๋ฉด ์ ๋‹นํ•œ ํฌ๊ธฐ๋กœ ์ง€์ • (์˜ˆ: 80x32) if markerView.frame == .zero { markerView.frame = CGRect(x: 0, y: 0, width: 80, height: 32) } @@ -778,23 +742,16 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM private func updateMapWithClustering() { let currentZoom = mainView.mapView.zoomLevel let level = MapZoomLevel.getLevel(from: Float(currentZoom)) - // ํด๋Ÿฌ์Šคํ„ฐ ์ฒ˜๋ฆฌ ์‹œ ํ˜„์žฌ ์Šคํ† ์–ด ๋ชฉ๋ก(currentStores)์„ ์‚ฌ์šฉ - Logger.log(message: "ํ˜„์žฌ ์คŒ ๋ ˆ๋ฒจ: \(currentZoom), ๋ชจ๋“œ: \(level), ์Šคํ† ์–ด ์ˆ˜: \(currentStores.count)", category: .debug) - CATransaction.begin() CATransaction.setDisableActions(true) switch level { case .detailed: - // ์ƒ์„ธ ๋ ˆ๋ฒจ์—์„œ๋Š” ๊ฐœ๋ณ„ ๋งˆ์ปค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. let newStoreIds = Set(currentStores.map { $0.id }) let groupedDict = groupStoresByExactLocation(currentStores) - - // ํด๋Ÿฌ์Šคํ„ฐ ๋งˆ์ปค ์ œ๊ฑฐ clusterMarkerDictionary.values.forEach { $0.mapView = nil } clusterMarkerDictionary.removeAll() - // ๊ทธ๋ฃน๋ณ„๋กœ ๊ฐœ๋ณ„ ๋งˆ์ปค ์ƒ์„ฑ/์—…๋ฐ์ดํŠธ for (coordinate, storeGroup) in groupedDict { if storeGroup.count == 1, let store = storeGroup.first { if let existingMarker = individualMarkerDictionary[store.id] { @@ -814,8 +771,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM // ์ง์ ‘ ํ„ฐ์น˜ ํ•ธ๋“ค๋Ÿฌ ์ถ”๊ฐ€ marker.touchHandler = { [weak self] (_) -> Bool in guard let self = self else { return false } - - print("๊ฐœ๋ณ„ ๋งˆ์ปค ํ„ฐ์น˜๋จ! ์Šคํ† ์–ด: \(store.name)") return self.handleSingleStoreTap(marker, store: store) } @@ -823,7 +778,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM individualMarkerDictionary[store.id] = marker } } else { - // ์—ฌ๋Ÿฌ ์Šคํ† ์–ด๊ฐ€ ๋™์ผ ์œ„์น˜์— ์žˆ์œผ๋ฉด ๋‹จ์ผ ๋งˆ์ปค๋กœ ํ‘œ์‹œํ•˜๋ฉด์„œ count ๊ฐฑ์‹  guard let firstStore = storeGroup.first else { continue } let markerKey = firstStore.id if let existingMarker = individualMarkerDictionary[markerKey] { @@ -837,11 +791,8 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM marker.anchor = CGPoint(x: 0.5, y: 1.0) updateMarkerStyle(marker: marker, selected: false, isCluster: false, count: storeGroup.count) - // ์ง์ ‘ ํ„ฐ์น˜ ํ•ธ๋“ค๋Ÿฌ ์ถ”๊ฐ€ marker.touchHandler = { [weak self] (_) -> Bool in guard let self = self else { return false } - - print("๋งˆ์ดํฌ๋กœ ํด๋Ÿฌ์Šคํ„ฐ ๋งˆ์ปค ํ„ฐ์น˜๋จ! ์Šคํ† ์–ด ์ˆ˜: \(storeGroup.count)๊ฐœ") return self.handleMicroClusterTap(marker, storeArray: storeGroup) } @@ -851,7 +802,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM } } - // ๊ธฐ์กด์— ๋ณด์ด์ง€ ์•Š๋Š” ๊ฐœ๋ณ„ ๋งˆ์ปค ์ œ๊ฑฐ individualMarkerDictionary = individualMarkerDictionary.filter { id, marker in if newStoreIds.contains(id) { return true @@ -862,11 +812,9 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM } case .district, .city, .country: - // ๊ฐœ๋ณ„ ๋งˆ์ปค ์ˆจ๊ธฐ๊ธฐ individualMarkerDictionary.values.forEach { $0.mapView = nil } individualMarkerDictionary.removeAll() - // ํด๋Ÿฌ์Šคํ„ฐ ์ƒ์„ฑ let clusters = clusteringManager.clusterStores(currentStores, at: Float(currentZoom)) let activeClusterKeys = Set(clusters.map { $0.cluster.name }) @@ -875,7 +823,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM var marker: NMFMarker if let existingMarker = clusterMarkerDictionary[clusterKey] { marker = existingMarker - // ์œ„์น˜ ์—…๋ฐ์ดํŠธ๊ฐ€ ํ•„์š”ํ•˜๋ฉด ์ˆ˜์ • if marker.position.lat != cluster.cluster.coordinate.lat || marker.position.lng != cluster.cluster.coordinate.lng { marker.position = NMGLatLng(lat: cluster.cluster.coordinate.lat, lng: cluster.cluster.coordinate.lng) @@ -886,17 +833,14 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM } marker.position = NMGLatLng(lat: cluster.cluster.coordinate.lat, lng: cluster.cluster.coordinate.lng) - marker.userInfo = ["clusterData": cluster] // ์ค‘์š”: userInfo์— cluster ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ €์žฅ + marker.userInfo = ["clusterData": cluster] - // ์—ฌ๊ธฐ์„œ ์ปค์Šคํ…€ ํด๋Ÿฌ์Šคํ„ฐ ๋งˆ์ปค ๋ทฐ๋ฅผ ์ด๋ฏธ์ง€๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. if let clusterImage = createClusterMarkerImage(regionName: cluster.cluster.name, count: cluster.storeCount) { marker.iconImage = NMFOverlayImage(image: clusterImage) } else { - // ๊ธฐ๋ณธ ์—์…‹ fallback (์›ํ•˜๋Š” ๊ฒฝ์šฐ) marker.iconImage = NMFOverlayImage(name: "cluster_marker") } - // ํ„ฐ์น˜ ํ•ธ๋“ค๋Ÿฌ ์ถ”๊ฐ€ - userInfo์—์„œ ํด๋Ÿฌ์Šคํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๊ธฐ marker.touchHandler = { [weak self] (overlay) -> Bool in guard let self = self, let tappedMarker = overlay as? NMFMarker, @@ -912,7 +856,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM marker.mapView = mainView.mapView } - // ํ™œ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ์•„๋‹Œ ๋งˆ์ปค ์ œ๊ฑฐ for (key, marker) in clusterMarkerDictionary { if !activeClusterKeys.contains(key) { marker.mapView = nil @@ -1045,7 +988,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM currentFilterBottomSheet = nil } - // ๊ธฐ๋ณธ ๋งˆ์ปค private func addMarkers(for stores: [MapPopUpStore]) { markerDictionary.values.forEach { $0.mapView = nil } markerDictionary.removeAll() @@ -1057,7 +999,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM updateMarkerStyle(marker: marker, selected: false, isCluster: false) - // ์ง์ ‘ ํ„ฐ์น˜ ํ•ธ๋“ค๋Ÿฌ ์ถ”๊ฐ€ marker.touchHandler = { [weak self] (_) -> Bool in guard let self = self else { return false } @@ -1070,7 +1011,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM } } private func updateListView(with results: [MapPopUpStore]) { - // MapPopUpStore ๋ฐฐ์—ด์„ StoreItem ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜ let storeItems = results.map { store in StoreItem( id: store.id, @@ -1115,8 +1055,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM northEast: bounds.northEast ) } - - // ํ˜„์žฌ ๋ณด์ด๋Š” ์ง€๋„ ์˜์—ญ์˜ ๊ฒฝ๊ณ„๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ํ•จ์ˆ˜ private func getVisibleBounds() -> (northEast: NMGLatLng, southWest: NMGLatLng) { let mapBounds = mainView.mapView.contentBounds @@ -1136,10 +1074,10 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM mainView.mapView.positionMode = .direction // ๋‚ด ์œ„์น˜ ํŠธ๋ž˜ํ‚น ๋ชจ๋“œ ํ™œ์„ฑํ™” case .denied, .restricted: Logger.log( - message: "์œ„์น˜ ์„œ๋น„์Šค๊ฐ€ ๋น„ํ™œ์„ฑํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์„ค์ •์—์„œ ๊ถŒํ•œ์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”.", + "์œ„์น˜ ์„œ๋น„์Šค๊ฐ€ ๋น„ํ™œ์„ฑํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์„ค์ •์—์„œ ๊ถŒํ•œ์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”.", category: .error ) - mainView.mapView.positionMode = .disabled // ๋‚ด ์œ„์น˜ ํŠธ๋ž˜ํ‚น ๋ชจ๋“œ ๋น„ํ™œ์„ฑํ™” + mainView.mapView.positionMode = .disabled @unknown default: break } @@ -1147,15 +1085,11 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM private func updateTooltipPosition() { guard let marker = currentMarker, let tooltip = currentTooltipView else { return } - - // ๋งˆ์ปค ์œ„์น˜๋ฅผ ํ™”๋ฉด ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜ let markerPoint = mainView.mapView.projection.point(from: marker.position) var markerCenter = markerPoint - // ๋งˆ์ปค ๋†’์ด ๊ณ ๋ ค (๋„ค์ด๋ฒ„ ๋งˆ์ปค๋Š” ํฌ๊ธฐ๊ฐ€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Œ) - markerCenter.y = markerPoint.y - 20 // ๋งˆ์ปค ์ด๋ฏธ์ง€ ๋†’์ด์˜ ์ ˆ๋ฐ˜ ์ •๋„ + markerCenter.y = markerPoint.y - 20 - // ์˜คํ”„์…‹ ๊ฐ’ (๋””์ž์ธ์— ๋งž๊ฒŒ ์กฐ์ •) let offsetX: CGFloat = -10 let offsetY: CGFloat = -10 @@ -1167,7 +1101,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM private func resetSelectedMarker() { if let currentMarker = currentMarker { - // ๋งˆ์ปค ์Šคํƒ€์ผ ์—…๋ฐ์ดํŠธ updateMarkerStyle(marker: currentMarker, selected: false, isCluster: false) } @@ -1219,7 +1152,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM } private func findMarkerForStore(for store: MapPopUpStore) -> NMFMarker? { - // individualMarkerDictionary์— ์ €์žฅ๋œ ๋ชจ๋“  ๋งˆ์ปค๋ฅผ ์ˆœํšŒ for marker in individualMarkerDictionary.values { if let singleStore = marker.userInfo["storeData"] as? MapPopUpStore, singleStore.id == store.id { return marker @@ -1229,7 +1161,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM return marker } } - // ์ƒ์„ธ ๋ ˆ๋ฒจ์ด ์•„๋‹ ๊ฒฝ์šฐ clusterMarkerDictionary์—๋„ ๋™์ผํ•˜๊ฒŒ ๊ฒ€์ƒ‰ for marker in clusterMarkerDictionary.values { if let clusterData = marker.userInfo["clusterData"] as? ClusterMarkerData, clusterData.cluster.stores.contains(where: { $0.id == store.id }) { @@ -1240,10 +1171,7 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM } private func fetchStoreDetails(for stores: [MapPopUpStore]) { - // ๋นˆ ๋ชฉ๋ก์ด๋ฉด ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Œ guard !stores.isEmpty else { return } - - // ๋จผ์ € ๊ธฐ๋ณธ ์ •๋ณด๋กœ StoreItem ์ƒ์„ฑํ•˜์—ฌ ์ˆœ์„œ ์œ ์ง€ let initialStoreItems = stores.map { store in StoreItem( id: store.id, @@ -1255,11 +1183,7 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM isBookmarked: false ) } - - // ๋ฆฌ์ŠคํŠธ์—๋Š” ๋ชจ๋“  ์Šคํ† ์–ด ์ •๋ณด ํ‘œ์‹œ (ํ•„ํ„ฐ๋ง๋œ ๋ชจ๋“  ์Šคํ† ์–ด) self.storeListViewController.reactor?.action.onNext(.setStores(initialStoreItems)) - - // ๊ฐ ์Šคํ† ์–ด์˜ ์ƒ์„ธ ์ •๋ณด๋ฅผ ๋ณ‘๋ ฌ๋กœ ๊ฐ€์ ธ์™€์„œ ์—…๋ฐ์ดํŠธ (๋ถ๋งˆํฌ ์ •๋ณด ๋“ฑ) stores.forEach { store in self.popUpAPIUseCase.getPopUpDetail( commentType: "NORMAL", @@ -1279,12 +1203,8 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM } func bindViewport(reactor: MapReactor) { - // ์นด๋ฉ”๋ผ ์ด๋™ ์™„๋ฃŒ ์‹œ ์ด๋ฒคํŠธ ๋ฐœ์ƒ๋˜๋Š” Subject let cameraObservable = PublishSubject() - // NMFMapViewCameraDelegate ๋ฉ”์„œ๋“œ์—์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ • - - // ์นด๋ฉ”๋ผ ๋ณ€๊ฒฝ ๊ฐ์ง€ํ•ด์„œ ์•ก์…˜ ์ „๋‹ฌ cameraObservable .throttle(.milliseconds(200), scheduler: MainScheduler.instance) .map { [unowned self] _ -> MapReactor.Action in @@ -1299,7 +1219,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM .bind(to: reactor.action) .disposed(by: disposeBag) - // ํ˜„์žฌ ๋ทฐํฌํŠธ ๋‚ด์˜ ์Šคํ† ์–ด ์—…๋ฐ์ดํŠธ - ์ดˆ๊ธฐ 1ํšŒ reactor.state .map { $0.viewportStores } .distinctUntilChanged() @@ -1309,7 +1228,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM .subscribe(onNext: { [weak self] stores in guard let self = self else { return } - // ํ˜„์žฌ ์œ„์น˜๊ฐ€ ์žˆ์œผ๋ฉด ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์Šคํ† ์–ด, ์—†์œผ๋ฉด ์ฒซ ๋ฒˆ์งธ ์Šคํ† ์–ด ํ‘œ์‹œ if let location = self.locationManager.location { self.findAndShowNearestStore(from: location) } else if let firstStore = stores.first, @@ -1317,13 +1235,11 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM _ = self.handleSingleStoreTap(marker, store: firstStore) } - // ํ˜„์žฌ ์Šคํ† ์–ด ๋ชฉ๋ก ์—…๋ฐ์ดํŠธ ๋ฐ ํด๋Ÿฌ์Šคํ„ฐ๋ง self.currentStores = stores self.updateMapWithClustering() }) .disposed(by: disposeBag) - // ๋ทฐํฌํŠธ ๋‚ด ๋งˆ์ปค ์—…๋ฐ์ดํŠธ ๋ฐ ์บ๋Ÿฌ์…€ ํ‘œ์‹œ reactor.state .map { $0.viewportStores } .distinctUntilChanged() @@ -1335,19 +1251,16 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM let effectiveViewport = self.getEffectiveViewport() let bounds = self.getVisibleBounds() - // ํ™”๋ฉด์— ๋ณด์ด๋Š” ์Šคํ† ์–ด๋งŒ ํ•„ํ„ฐ๋ง let visibleStores = stores.filter { store in let storePosition = NMGLatLng(lat: store.latitude, lng: store.longitude) return NMGLatLngBounds(southWest: bounds.southWest, northEast: bounds.northEast).contains(storePosition) } self.currentStores = visibleStores - // ๊ฐœ๋ณ„ ๋งˆ์ปค ๋ ˆ๋ฒจ์ธ์ง€ ํ™•์ธ let currentZoom = self.mainView.mapView.zoomLevel let level = MapZoomLevel.getLevel(from: Float(currentZoom)) if level == .detailed && !visibleStores.isEmpty { - // ์บ๋Ÿฌ์…€์— ๋ชจ๋“  ๋งˆ์ปค ์ •๋ณด ํ‘œ์‹œ let effectiveStores = visibleStores.filter { store in let storePosition = NMGLatLng(lat: store.latitude, lng: store.longitude) return effectiveViewport.contains(storePosition) @@ -1358,9 +1271,7 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM self.carouselView.isHidden = false self.mainView.setStoreCardHidden(false, animated: true) - // ํ˜„์žฌ ์„ ํƒ๋œ ๋งˆ์ปค๊ฐ€ ์žˆ์œผ๋ฉด ํ•ด๋‹น ์œ„์น˜๋กœ ์Šคํฌ๋กค if let currentMarker = self.currentMarker { - // ๋งˆ์ปค์˜ ์Šคํ† ์–ด ์ •๋ณด ์ฒดํฌ if let currentStore = currentMarker.userInfo["storeData"] as? MapPopUpStore, let index = visibleStores.firstIndex(where: { $0.id == currentStore.id }) { self.carouselView.scrollToCard(index: index) @@ -1383,7 +1294,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM self.carouselView.scrollToCard(index: 0) } } else { - // ์„ ํƒ๋œ ๋งˆ์ปค๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ, ์ฒซ ๋ฒˆ์งธ ์Šคํ† ์–ด๋กœ ์„ค์ • if let firstStore = visibleStores.first, let marker = self.findMarkerForStore(for: firstStore) { self.updateMarkerStyle(marker: marker, selected: true, isCluster: false) @@ -1411,7 +1321,7 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM private func findAndShowNearestStore(from location: CLLocation) { guard !currentStores.isEmpty else { - Logger.log(message: "ํ˜„์žฌ์œ„์น˜ ํ‘œ๊ธฐํ•  ์Šคํ† ์–ด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค", category: .debug) + Logger.log("ํ˜„์žฌ์œ„์น˜ ํ‘œ๊ธฐํ•  ์Šคํ† ์–ด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค", category: .debug) return } @@ -1424,17 +1334,13 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM } if let store = nearestStore, let marker = findMarkerForStore(for: store) { - // ์นด๋ฉ”๋ผ ์ด๋™ ์—†์ด ์„ ํƒ๋œ ๋งˆ์ปค๋งŒ ์—…๋ฐ์ดํŠธ _ = handleSingleStoreTap(marker, store: store) - } - // ๋งˆ์ปค๊ฐ€ ์—†๋‹ค๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑ - else if let store = nearestStore { + } else if let store = nearestStore { let marker = NMFMarker() marker.position = NMGLatLng(lat: store.latitude, lng: store.longitude) marker.userInfo = ["storeData": store] marker.anchor = CGPoint(x: 0.5, y: 1.0) - // ๋งˆ์ปค ์Šคํƒ€์ผ ์„ค์ • updateMarkerStyle(marker: marker, selected: true, isCluster: false) marker.mapView = mainView.mapView @@ -1451,18 +1357,12 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM func handleSingleStoreTap(_ marker: NMFMarker, store: MapPopUpStore) -> Bool { isMovingToMarker = true - // ์ด์ „ ๋งˆ์ปค ์„ ํƒ ์ƒํƒœ ํ•ด์ œ if let previousMarker = currentMarker { updateMarkerStyle(marker: previousMarker, selected: false, isCluster: false) } - - // ์ƒˆ ๋งˆ์ปค ์„ ํƒ ์ƒํƒœ๋กœ ์„ค์ • updateMarkerStyle(marker: marker, selected: true, isCluster: false) currentMarker = marker - - // ์บ๋Ÿฌ์…€์— ํ‘œ์‹œํ•  ์Šคํ† ์–ด ํ™•์ธ if currentCarouselStores.isEmpty || !currentCarouselStores.contains(where: { $0.id == store.id }) { - // ํ˜„์žฌ ๋ทฐํฌํŠธ์˜ ๋ชจ๋“  ์Šคํ† ์–ด๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ let bounds = getVisibleBounds() let visibleStores = currentStores.filter { store in @@ -1471,21 +1371,17 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM } if !visibleStores.isEmpty { - // ๋ทฐํฌํŠธ์˜ ๋ชจ๋“  ์Šคํ† ์–ด๋ฅผ ์บ๋Ÿฌ์…€์— ํ‘œ์‹œ currentCarouselStores = visibleStores carouselView.updateCards(visibleStores) - // ์„ ํƒํ•œ ์Šคํ† ์–ด์˜ ์ธ๋ฑ์Šค๋ฅผ ์ฐพ์•„ ์Šคํฌ๋กค if let index = visibleStores.firstIndex(where: { $0.id == store.id }) { carouselView.scrollToCard(index: index) } } else { - // ๋ทฐํฌํŠธ์— ๋‹ค๋ฅธ ์Šคํ† ์–ด๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ, ์„ ํƒํ•œ ์Šคํ† ์–ด๋งŒ ํ‘œ์‹œ currentCarouselStores = [store] carouselView.updateCards([store]) } } else { - // ์บ๋Ÿฌ์…€์— ์ด๋ฏธ ํ•ด๋‹น ์Šคํ† ์–ด๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, ํ•ด๋‹น ์œ„์น˜๋กœ ์Šคํฌ๋กค if let index = currentCarouselStores.firstIndex(where: { $0.id == store.id }) { carouselView.scrollToCard(index: index) } @@ -1494,16 +1390,12 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM carouselView.isHidden = false mainView.setStoreCardHidden(false, animated: true) - // ํˆดํŒ ์ฒ˜๋ฆฌ if let storeArray = marker.userInfo["storeData"] as? [MapPopUpStore], storeArray.count > 1 { - // ๋งˆ์ดํฌ๋กœ ํด๋Ÿฌ์Šคํ„ฐ์ธ ๊ฒฝ์šฐ ํˆดํŒ ํ‘œ์‹œ configureTooltip(for: marker, stores: storeArray) - // ํ•ด๋‹น ์Šคํ† ์–ด์˜ ํˆดํŒ ์ธ๋ฑ์Šค ์„ ํƒ if let index = storeArray.firstIndex(where: { $0.id == store.id }) { (currentTooltipView as? MarkerTooltipView)?.selectStore(at: index) } } else { - // ๋‹จ์ผ ๋งˆ์ปค์ธ ๊ฒฝ์šฐ ํˆดํŒ ์ œ๊ฑฐ currentTooltipView?.removeFromSuperview() currentTooltipView = nil } @@ -1512,53 +1404,36 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM return true } - // ๋ฆฌ์ „ ํด๋Ÿฌ์Šคํ„ฐ ํƒญ ์ฒ˜๋ฆฌ func handleRegionalClusterTap(_ marker: NMFMarker, clusterData: ClusterMarkerData) -> Bool { - print("handleRegionalClusterTap ํ•จ์ˆ˜ ํ˜ธ์ถœ๋จ") let currentZoom = mainView.mapView.zoomLevel let currentLevel = MapZoomLevel.getLevel(from: Float(currentZoom)) - - // ๋””๋ฒ„๊น… - print("ํ˜„์žฌ ์คŒ ๋ ˆ๋ฒจ: \(currentZoom), ๋ชจ๋“œ: \(currentLevel)") - print("ํด๋Ÿฌ์Šคํ„ฐ ์ •๋ณด: \(clusterData.cluster.name), ์Šคํ† ์–ด ์ˆ˜: \(clusterData.storeCount)") - switch currentLevel { - case .city: // ์‹œ ๋‹จ์œ„ ํด๋Ÿฌ์Šคํ„ฐ - print("์‹œ ๋‹จ์œ„ ํด๋Ÿฌ์Šคํ„ฐ ์ฒ˜๋ฆฌ") + case .city: let districtZoomLevel: Double = 10.0 let cameraUpdate = NMFCameraUpdate(scrollTo: marker.position, zoomTo: districtZoomLevel) cameraUpdate.animation = .easeIn cameraUpdate.animationDuration = 0.3 mainView.mapView.moveCamera(cameraUpdate) - case .district: // ๊ตฌ ๋‹จ์œ„ ํด๋Ÿฌ์Šคํ„ฐ - print("๊ตฌ ๋‹จ์œ„ ํด๋Ÿฌ์Šคํ„ฐ ์ฒ˜๋ฆฌ") + case .district: let detailedZoomLevel: Double = 12.0 let cameraUpdate = NMFCameraUpdate(scrollTo: marker.position, zoomTo: detailedZoomLevel) cameraUpdate.animation = .easeIn cameraUpdate.animationDuration = 0.3 mainView.mapView.moveCamera(cameraUpdate) default: - print("๊ธฐํƒ€ ๋ ˆ๋ฒจ ํด๋Ÿฌ์Šคํ„ฐ ์ฒ˜๋ฆฌ") + print("๊ธฐํƒ€") } - - // ํด๋Ÿฌ์Šคํ„ฐ์— ํฌํ•จ๋œ ์Šคํ† ์–ด๋“ค๋งŒ ํ‘œ์‹œํ•˜๋„๋ก ๋งˆ์ปค ์—…๋ฐ์ดํŠธ updateMarkersForCluster(stores: clusterData.cluster.stores) - - // ์บ๋Ÿฌ์…€ ์—…๋ฐ์ดํŠธ carouselView.updateCards(clusterData.cluster.stores) carouselView.isHidden = false self.currentCarouselStores = clusterData.cluster.stores - return true } - // ๋งˆ์ดํฌ๋กœ ํด๋Ÿฌ์Šคํ„ฐ ํƒญ ์ฒ˜๋ฆฌ func handleMicroClusterTap(_ marker: NMFMarker, storeArray: [MapPopUpStore]) -> Bool { - // ์ด๋ฏธ ์„ ํƒ๋œ ๋งˆ์ปค๋ฅผ ๋‹ค์‹œ ํƒญํ•  ๋•Œ if currentMarker == marker { - // ํˆดํŒ๊ณผ ์บ๋Ÿฌ์…€๋งŒ ์ˆจ๊ธฐ๊ณ , ๋งˆ์ปค์˜ ์„ ํƒ ์ƒํƒœ๋Š” ์œ ์ง€ currentTooltipView?.removeFromSuperview() currentTooltipView = nil currentTooltipStores = [] @@ -1567,8 +1442,6 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM carouselView.isHidden = true carouselView.updateCards([]) currentCarouselStores = [] - - // ๋งˆ์ปค ์ƒํƒœ ์—…๋ฐ์ดํŠธ updateMarkerStyle(marker: marker, selected: false, isCluster: false, count: storeArray.count) currentMarker = nil @@ -1594,14 +1467,10 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM carouselView.scrollToCard(index: 0) mainView.setStoreCardHidden(false, animated: true) - - // ์ง€๋„ ์ด๋™ let cameraUpdate = NMFCameraUpdate(scrollTo: marker.position) cameraUpdate.animation = .easeIn cameraUpdate.animationDuration = 0.3 mainView.mapView.moveCamera(cameraUpdate) - - // ํˆดํŒ ์ƒ์„ฑ if storeArray.count > 1 { DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in guard let self = self else { return } @@ -1614,8 +1483,7 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM } private func showNoMarkersToast() { - // ๋””์ž์ธ ์˜ˆ์ •์ด๋ฏ€๋กœ ์ž„์‹œ ๊ตฌํ˜„ - Logger.log(message: "ํ˜„์žฌ ์ง€๋„ ์˜์—ญ์— ํ‘œ์‹œํ•  ๋งˆ์ปค๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค", category: .debug) + Logger.log("ํ˜„์žฌ ์ง€๋„ ์˜์—ญ์— ํ‘œ์‹œํ•  ๋งˆ์ปค๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค", category: .debug) } } @@ -1642,37 +1510,21 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM // MARK: - NMFMapViewTouchDelegate extension MapViewController { - // ๋งˆ์ปค ํƒญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ - // ๋งˆ์ปค ํƒญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ func mapView(_ mapView: NMFMapView, didTap marker: NMFMarker) -> Bool { - Logger.log(message: "didTapMarker ํ˜ธ์ถœ๋จ: \(marker.position), userInfo: \(marker.userInfo)", category: .debug) - - // ํด๋Ÿฌ์Šคํ„ฐ ๋งˆ์ปค ํ™•์ธ if let clusterData = marker.userInfo["clusterData"] as? ClusterMarkerData { - Logger.log(message: "ํด๋Ÿฌ์Šคํ„ฐ ๋ฐ์ดํ„ฐ ๊ฐ์ง€: \(clusterData.cluster.name), ์Šคํ† ์–ด ์ˆ˜: \(clusterData.storeCount)", category: .debug) return handleRegionalClusterTap(marker, clusterData: clusterData) - } - // ๋งˆ์ดํฌ๋กœ ํด๋Ÿฌ์Šคํ„ฐ ๋˜๋Š” ๋‹จ์ผ ์Šคํ† ์–ด ๋งˆ์ปค ํ™•์ธ - else if let storeArray = marker.userInfo["storeData"] as? [MapPopUpStore] { + } else if let storeArray = marker.userInfo["storeData"] as? [MapPopUpStore] { if storeArray.count > 1 { - Logger.log(message: "๋งˆ์ดํฌ๋กœ ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ์ง€: \(storeArray.count)๊ฐœ ์Šคํ† ์–ด", category: .debug) return handleMicroClusterTap(marker, storeArray: storeArray) } else if let singleStore = storeArray.first { - Logger.log(message: "๋‹จ์ผ ์Šคํ† ์–ด ๊ฐ์ง€: \(singleStore.name)", category: .debug) return handleSingleStoreTap(marker, store: singleStore) } - } - // ๋‹จ์ผ ์Šคํ† ์–ด ๋งˆ์ปค (๋ฐฐ์—ด์ด ์•„๋‹Œ ๊ฒฝ์šฐ) ํ™•์ธ - else if let singleStore = marker.userInfo["storeData"] as? MapPopUpStore { - Logger.log(message: "๋‹จ์ผ ์Šคํ† ์–ด ๊ฐ์ง€: \(singleStore.name)", category: .debug) + } else if let singleStore = marker.userInfo["storeData"] as? MapPopUpStore { return handleSingleStoreTap(marker, store: singleStore) } - - Logger.log(message: "์ธ์‹ํ•  ์ˆ˜ ์—†๋Š” ๋งˆ์ปค ํƒ€์ž…", category: .error) return false } - // ์ง€๋„ ํƒญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ func mapView(_ mapView: NMFMapView, didTapMap latlng: NMGLatLng, point: CGPoint) { guard !isMovingToMarker else { return } @@ -1681,54 +1533,40 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM updateMarkerStyle(marker: currentMarker, selected: false, isCluster: false) self.currentMarker = nil } - - // ํˆดํŒ ์ œ๊ฑฐ currentTooltipView?.removeFromSuperview() currentTooltipView = nil currentTooltipStores = [] currentTooltipCoordinate = nil - - // ์บ๋Ÿฌ์…€ ์ดˆ๊ธฐํ™” carouselView.isHidden = true carouselView.updateCards([]) self.currentCarouselStores = [] mainView.setStoreCardHidden(true, animated: true) - - // ํด๋Ÿฌ์Šคํ„ฐ๋ง ์—…๋ฐ์ดํŠธ updateMapWithClustering() } } // MARK: - NMFMapViewCameraDelegate extension MapViewController { - // ์นด๋ฉ”๋ผ ์ด๋™ ์‹œ์ž‘ ์‹œ ํ˜ธ์ถœ func mapView(_ mapView: NMFMapView, cameraWillChangeByReason reason: Int, animated: Bool) { if reason == NMFMapChangedByGesture && !isMovingToMarker { resetSelectedMarker() } } - - // ์นด๋ฉ”๋ผ ์ด๋™ ์ค‘ ํ˜ธ์ถœ func mapView(_ mapView: NMFMapView, cameraIsChangingByReason reason: Int) { if !isMovingToMarker { currentTooltipView?.removeFromSuperview() currentTooltipView = nil currentTooltipStores = [] updateMapWithClustering() - - // ์บ๋Ÿฌ์…€ ์ดˆ๊ธฐํ™” carouselView.isHidden = true carouselView.updateCards([]) currentCarouselStores = [] } } - - // ์นด๋ฉ”๋ผ ์ด๋™ ์™„๋ฃŒ ์‹œ ํ˜ธ์ถœ func mapView(_ mapView: NMFMapView, cameraDidChangeByReason reason: Int, animated: Bool) { if let marker = self.currentMarker, let storeArray = marker.userInfo["storeData"] as? [MapPopUpStore], storeArray.count > 1 { - // ํˆดํŒ์ด ์—†์œผ๋ฉด ์ƒ์„ฑ, ์žˆ์œผ๋ฉด ์œ„์น˜ ์—…๋ฐ์ดํŠธ if self.currentTooltipView == nil { self.configureTooltip(for: marker, stores: storeArray) } else { @@ -1736,37 +1574,17 @@ class MapViewController: BaseViewController, View, CLLocationManagerDelegate, NM } } self.isMovingToMarker = false - - // ๋ทฐํฌํŠธ ๋ณ€๊ฒฝ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ - idleSubject ํ†ตํ•ด ์•Œ๋ฆผ idleSubject.onNext(()) - - // ๋ทฐํฌํŠธ ๋ณ€๊ฒฝ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ - if let reactor = self.reactor { - let bounds = self.getVisibleBounds() - reactor.action.onNext(.viewportChanged( - northEastLat: bounds.northEast.lat, - northEastLon: bounds.northEast.lng, - southWestLat: bounds.southWest.lat, - southWestLon: bounds.southWest.lng - )) - } + cameraIdle.onNext(()) } } - // MARK: - UIGestureRecognizerDelegate extension MapViewController { - // ๋งต๋ทฐ์˜ ๋‹ค๋ฅธ ์ œ์Šค์ฒ˜์™€ ์ถฉ๋Œํ•˜์ง€ ์•Š๋„๋ก ํ•จ func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { - // ๋งต์˜ ๋‚ด์žฅ ์ œ์Šค์ฒ˜์™€ ๋™์‹œ ์ธ์‹ ํ—ˆ์šฉ return true } - - // ๋ฆฌ์ŠคํŠธ๋ทฐ๊ฐ€ ๋ณด์ผ ๋•Œ๋งŒ ์ปค์Šคํ…€ ํƒญ ์ œ์Šค์ฒ˜ ํ—ˆ์šฉ func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { - // ํ„ฐ์น˜๊ฐ€ ๋ฆฌ์ŠคํŠธ๋ทฐ ์˜์—ญ์— ์žˆ์œผ๋ฉด ์ปค์Šคํ…€ ์ œ์Šค์ฒ˜ ํŠธ๋ฆฌ๊ฑฐํ•˜์ง€ ์•Š์Œ let touchPoint = touch.location(in: view) - - // ๋ฆฌ์ŠคํŠธ๋ทฐ๊ฐ€ ๋ณด์ด๊ณ  ํ„ฐ์น˜๊ฐ€ ๋ฆฌ์ŠคํŠธ๋ทฐ ์œ„์— ์žˆ์œผ๋ฉด ํƒญ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Œ if modalState != .bottom { let listViewY = storeListViewController.view.frame.minY if touchPoint.y > listViewY { diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/StoreListView/StoreListReactor.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/StoreListView/StoreListReactor.swift index 054506ce..d335352d 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/StoreListView/StoreListReactor.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/StoreListView/StoreListReactor.swift @@ -80,7 +80,7 @@ final class StoreListReactor: Reactor { // Int64 โ†’ Int32 ๋ณ€ํ™˜ ํ•„์š” guard let idInt32 = Int32(exactly: store.id) else { - Logger.log(message: "ID ๊ฐ’์ด Int32 ๋ฒ”์œ„๋ฅผ ์ดˆ๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค: \(store.id)", category: .error) + Logger.log("ID ๊ฐ’์ด Int32 ๋ฒ”์œ„๋ฅผ ์ดˆ๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค: \(store.id)", category: .error) return .empty() } @@ -192,7 +192,7 @@ final class StoreListReactor: Reactor { newState.stores[index].isBookmarked = isBookmarked Logger.log( - message: """ + """ ๋ถ๋งˆํฌ ์ƒํƒœ ๋ณ€๊ฒฝ: - ์Šคํ† ์–ด๋ช…: \(store.title) - ID: \(store.id) diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Scene/MyPage/ProfileEdit/Main/ProfileEditController.swift b/Poppool/PresentationLayer/Presentation/Presentation/Scene/MyPage/ProfileEdit/Main/ProfileEditController.swift index 9dc41725..988ef8e7 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Scene/MyPage/ProfileEdit/Main/ProfileEditController.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Scene/MyPage/ProfileEdit/Main/ProfileEditController.swift @@ -220,7 +220,7 @@ extension ProfileEditController: PHPickerViewControllerDelegate, UIImagePickerCo func showCamera() { guard UIImagePickerController.isSourceTypeAvailable(.camera) else { - Logger.log(message: "์นด๋ฉ”๋ผ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.", category: .error) + Logger.log("์นด๋ฉ”๋ผ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.", category: .error) return } diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Utills/Common/ClusteringManager.swift b/Poppool/PresentationLayer/Presentation/Presentation/Utills/Common/ClusteringManager.swift index 23bebd96..a4bd93be 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Utills/Common/ClusteringManager.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Utills/Common/ClusteringManager.swift @@ -126,10 +126,8 @@ class ClusteringManager { let combined = Array(seoulClusters.values) + Array(gyeonggiClusters.values) + Array(otherClusters.values) let filtered = combined.filter { $0.storeCount > 0 } - - Logger.log(message: "๊ตฌ ๋‹จ์œ„ ํด๋Ÿฌ์Šคํ„ฐ ์ƒ์„ฑ ๊ฒฐ๊ณผ: \(filtered.count)๊ฐœ", category: .debug) for cluster in filtered { - Logger.log(message: "- \(cluster.base.name): \(cluster.storeCount)๊ฐœ ๋งค์žฅ", category: .debug) + Logger.log("- \(cluster.base.name): \(cluster.storeCount)๊ฐœ ๋งค์žฅ", category: .debug) } return filtered.map { $0.toMarkerData() } diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Utills/Controllers/BaseTabmanController.swift b/Poppool/PresentationLayer/Presentation/Presentation/Utills/Controllers/BaseTabmanController.swift index 42a777dd..2b3dc171 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Utills/Controllers/BaseTabmanController.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Utills/Controllers/BaseTabmanController.swift @@ -9,10 +9,8 @@ class BaseTabmanController: TabmanViewController { init() { super.init(nibName: nil, bundle: nil) Logger.log( - message: "\(self) init", - category: .info, - fileName: #file, - line: #line + "\(self) init", + category: .info ) } @@ -28,10 +26,8 @@ class BaseTabmanController: TabmanViewController { deinit { Logger.log( - message: "\(self) deinit", - category: .info, - fileName: #file, - line: #line + "\(self) deinit", + category: .info ) } } diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Utills/Controllers/BaseViewController.swift b/Poppool/PresentationLayer/Presentation/Presentation/Utills/Controllers/BaseViewController.swift index 03eeded3..7680932f 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Utills/Controllers/BaseViewController.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Utills/Controllers/BaseViewController.swift @@ -13,10 +13,8 @@ public class BaseViewController: UIViewController { public init() { super.init(nibName: nil, bundle: nil) Logger.log( - message: "\(self) init", - category: .info, - fileName: #file, - line: #line + "\(self) init", + category: .info ) } @@ -38,10 +36,8 @@ public class BaseViewController: UIViewController { deinit { Logger.log( - message: "\(self) deinit", - category: .info, - fileName: #file, - line: #line + "\(self) deinit", + category: .info ) } diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Utills/Interfaces/Sectionable/SectionSupplementaryItem.swift b/Poppool/PresentationLayer/Presentation/Presentation/Utills/Interfaces/Sectionable/SectionSupplementaryItem.swift index c37a5e4b..f7f7d23a 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Utills/Interfaces/Sectionable/SectionSupplementaryItem.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Utills/Interfaces/Sectionable/SectionSupplementaryItem.swift @@ -67,11 +67,8 @@ extension SectionSupplementaryItemable { for: indexPath ) as? ReusableView else { Logger.log( - message: "ReusableView Error", - category: .error, - fileName: #file, - line: #line - ) + "ReusableView Error", + category: .error) return UICollectionReusableView() } view.injection(with: viewInput) diff --git a/Poppool/PresentationLayer/Presentation/Presentation/Utills/Interfaces/Sectionable/Sectionable.swift b/Poppool/PresentationLayer/Presentation/Presentation/Utills/Interfaces/Sectionable/Sectionable.swift index 7153b6a7..a3cbb3d6 100644 --- a/Poppool/PresentationLayer/Presentation/Presentation/Utills/Interfaces/Sectionable/Sectionable.swift +++ b/Poppool/PresentationLayer/Presentation/Presentation/Utills/Interfaces/Sectionable/Sectionable.swift @@ -131,10 +131,8 @@ extension Sectionable { for: indexPath ) as? CellType else { Logger.log( - message: "dequeueReusableCell Fail", - category: .error, - fileName: #file, - line: #line + "dequeueReusableCell Fail", + category: .error ) return UICollectionViewCell() } @@ -158,10 +156,8 @@ extension Sectionable { guard let item = supplementaryItems?.filter({ $0.elementKind == kind }).first else { Logger.log( - message: "ReusableView Not Register", - category: .error, - fileName: #file, - line: #line + "ReusableView Not Register", + category: .error ) fatalError() }