From 49251cae3b29b46217210eef61cb7d117cb0d5a0 Mon Sep 17 00:00:00 2001 From: opficdev Date: Wed, 15 Apr 2026 11:00:14 +0900 Subject: [PATCH 1/2] =?UTF-8?q?refactor:=20Nexa=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=EB=9F=AC=EB=A6=AC=EB=A5=BC=20=EB=8F=84=EC=9E=85?= =?UTF-8?q?=ED=95=B4=20=EB=B3=B4=EC=9D=BC=EB=9F=AC=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DevLog.xcodeproj/project.pbxproj | 17 +++++ .../xcshareddata/swiftpm/Package.resolved | 11 +++- .../GithubAuthenticationService.swift | 62 +++++++++---------- 3 files changed, 55 insertions(+), 35 deletions(-) diff --git a/DevLog.xcodeproj/project.pbxproj b/DevLog.xcodeproj/project.pbxproj index d2bdc23d..e94976e3 100644 --- a/DevLog.xcodeproj/project.pbxproj +++ b/DevLog.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ DFABA3B02E23526500FEFBDB /* FirebaseFirestore in Frameworks */ = {isa = PBXBuildFile; productRef = DFABA3AF2E23526500FEFBDB /* FirebaseFirestore */; }; DFABA3B22E23526500FEFBDB /* FirebaseFunctions in Frameworks */ = {isa = PBXBuildFile; productRef = DFABA3B12E23526500FEFBDB /* FirebaseFunctions */; }; DFABA3B42E23526500FEFBDB /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = DFABA3B32E23526500FEFBDB /* FirebaseMessaging */; }; + DFD3B68D2F8F1FB8001DA7CD /* Nexa in Frameworks */ = {isa = PBXBuildFile; productRef = DFD3B68C2F8F1FB8001DA7CD /* Nexa */; }; DFD645402EC827A10073E133 /* .gitignore in Resources */ = {isa = PBXBuildFile; fileRef = DFD6453F2EC827A10073E133 /* .gitignore */; }; DFD74E2F2E423EA700613803 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = DFD74E2E2E423EA700613803 /* README.md */; }; DFF2DACE2EDC02AD00778738 /* OrderedCollections in Frameworks */ = {isa = PBXBuildFile; productRef = DFF2DACD2EDC02AD00778738 /* OrderedCollections */; }; @@ -76,6 +77,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DFD3B68D2F8F1FB8001DA7CD /* Nexa in Frameworks */, DFABA3B42E23526500FEFBDB /* FirebaseMessaging in Frameworks */, DFABA3A92E2351EE00FEFBDB /* GoogleSignInSwift in Frameworks */, DFABA3B22E23526500FEFBDB /* FirebaseFunctions in Frameworks */, @@ -172,6 +174,7 @@ DFABA3B12E23526500FEFBDB /* FirebaseFunctions */, DFABA3B32E23526500FEFBDB /* FirebaseMessaging */, DFF2DACD2EDC02AD00778738 /* OrderedCollections */, + DFD3B68C2F8F1FB8001DA7CD /* Nexa */, ); productName = SwiftUI_DevLog; productReference = DFD48B002DC4D6E2005905C5 /* DevLog.app */; @@ -211,6 +214,7 @@ DFABA3AA2E23526500FEFBDB /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, DF66A07B2EA52E970098E643 /* XCRemoteSwiftPackageReference "SwiftLint" */, DFF2DACC2EDC02AD00778738 /* XCRemoteSwiftPackageReference "swift-collections" */, + DFD3B68B2F8F1FB8001DA7CD /* XCRemoteSwiftPackageReference "Nexa" */, ); preferredProjectObjectVersion = 77; productRefGroup = DFD48B012DC4D6E2005905C5 /* Products */; @@ -610,6 +614,14 @@ minimumVersion = 11.15.0; }; }; + DFD3B68B2F8F1FB8001DA7CD /* XCRemoteSwiftPackageReference "Nexa" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/opficdev/Nexa"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.1.0; + }; + }; DFF2DACC2EDC02AD00778738 /* XCRemoteSwiftPackageReference "swift-collections" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/apple/swift-collections.git"; @@ -666,6 +678,11 @@ package = DFABA3AA2E23526500FEFBDB /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; productName = FirebaseMessaging; }; + DFD3B68C2F8F1FB8001DA7CD /* Nexa */ = { + isa = XCSwiftPackageProductDependency; + package = DFD3B68B2F8F1FB8001DA7CD /* XCRemoteSwiftPackageReference "Nexa" */; + productName = Nexa; + }; DFF2DACD2EDC02AD00778738 /* OrderedCollections */ = { isa = XCSwiftPackageProductDependency; package = DFF2DACC2EDC02AD00778738 /* XCRemoteSwiftPackageReference "swift-collections" */; diff --git a/DevLog.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DevLog.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 75e09a49..fe577f2a 100644 --- a/DevLog.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DevLog.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "e440a72cfb4192fa35c539dad59247f988a89b2436e7dfc795518078100559a4", + "originHash" : "6e83e8a97f59e7d95bbfcd1dc82daad8306c7a0f7df1e8bb7966a26baf0e4a2b", "pins" : [ { "identity" : "abseil-cpp-binary", @@ -163,6 +163,15 @@ "version" : "6.0.1" } }, + { + "identity" : "nexa", + "kind" : "remoteSourceControl", + "location" : "https://github.com/opficdev/Nexa", + "state" : { + "revision" : "a2f3ca9862eb24ffc28bdeb6d67293b4e8ddf3a5", + "version" : "1.1.0" + } + }, { "identity" : "promises", "kind" : "remoteSourceControl", diff --git a/DevLog/Infra/Service/SocialLogin/GithubAuthenticationService.swift b/DevLog/Infra/Service/SocialLogin/GithubAuthenticationService.swift index 991e5974..35dfd3fe 100644 --- a/DevLog/Infra/Service/SocialLogin/GithubAuthenticationService.swift +++ b/DevLog/Infra/Service/SocialLogin/GithubAuthenticationService.swift @@ -11,6 +11,7 @@ import FirebaseAuth import FirebaseFirestore import FirebaseFunctions import FirebaseMessaging +import Nexa final class GithubAuthenticationService: NSObject, AuthenticationService { private enum FunctionName: String { @@ -18,6 +19,11 @@ final class GithubAuthenticationService: NSObject, AuthenticationService { case revokeGithubAccessToken } + private enum GitHubAPI { + static let baseURL = URL(string: "https://api.github.com")! + static let acceptHeader = "application/vnd.github.v3+json" + } + private let store = Firestore.firestore() private let functions = Functions.functions(region: "asia-northeast3") private let messaging = Messaging.messaging() @@ -243,24 +249,18 @@ final class GithubAuthenticationService: NSObject, AuthenticationService { // GitHub API로 사용자 프로필 정보 가져오기 private func requestUserProfile(accessToken: String) async throws -> GitHubUser { - guard let url = URL(string: "https://api.github.com/user") else { - throw URLError(.badURL) - } + let gitHubApiClient = NXAPIClient( + configuration: NXClientConfiguration( + baseURL: GitHubAPI.baseURL, + headers: ["Accept": GitHubAPI.acceptHeader] + ) + ) - var request = URLRequest(url: url) - request.httpMethod = "GET" - request.addValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization") - request.addValue("application/vnd.github.v3+json", forHTTPHeaderField: "Accept") - - let (data, response) = try await URLSession.shared.data(for: request) - - guard let httpResponse = response as? HTTPURLResponse, - httpResponse.statusCode == 200 else { - throw URLError(.badServerResponse) - } - - let decoder = JSONDecoder() - let gitHubUser = try decoder.decode(GitHubUser.self, from: data) + let gitHubUser = try await gitHubApiClient + .get("/user", as: GitHubUser.self) + .header("Authorization", "Bearer \(accessToken)") + .validate(.statusCodes([200])) + .send() if gitHubUser.email != nil { return gitHubUser @@ -276,24 +276,18 @@ final class GithubAuthenticationService: NSObject, AuthenticationService { } private func requestPrimaryVerifiedEmail(accessToken: String) async throws -> String? { - guard let url = URL(string: "https://api.github.com/user/emails") else { - throw URLError(.badURL) - } - - var request = URLRequest(url: url) - request.httpMethod = "GET" - request.addValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization") - request.addValue("application/vnd.github.v3+json", forHTTPHeaderField: "Accept") - - let (data, response) = try await URLSession.shared.data(for: request) - - guard let httpResponse = response as? HTTPURLResponse, - httpResponse.statusCode == 200 else { - throw URLError(.badServerResponse) - } + let gitHubApiClient = NXAPIClient( + configuration: NXClientConfiguration( + baseURL: GitHubAPI.baseURL, + headers: ["Accept": GitHubAPI.acceptHeader] + ) + ) - let decoder = JSONDecoder() - let gitHubEmails = try decoder.decode([GitHubEmail].self, from: data) + let gitHubEmails = try await gitHubApiClient + .get("/user/emails", as: [GitHubEmail].self) + .header("Authorization", "Bearer \(accessToken)") + .validate(.statusCodes([200])) + .send() if let primaryVerifiedEmail = gitHubEmails.first(where: { $0.primary && $0.verified }) { return primaryVerifiedEmail.email From b8f37e881a91e705d8cd0f316c0cb9bcfac0d627 Mon Sep 17 00:00:00 2001 From: opficdev Date: Wed, 15 Apr 2026 11:14:13 +0900 Subject: [PATCH 2/2] =?UTF-8?q?style:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=83=9D=EC=84=B1=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EB=A1=9C=EC=BB=AC=20=ED=81=B4=EB=9D=BC=EC=9D=B4=EC=96=B8?= =?UTF-8?q?=ED=8A=B8=20=EB=B3=80=EC=88=98=EB=A5=BC=20=ED=95=9C=EB=B2=88?= =?UTF-8?q?=EB=A7=8C=20=EC=83=9D=EC=84=B1=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GithubAuthenticationService.swift | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/DevLog/Infra/Service/SocialLogin/GithubAuthenticationService.swift b/DevLog/Infra/Service/SocialLogin/GithubAuthenticationService.swift index 35dfd3fe..5989ff4d 100644 --- a/DevLog/Infra/Service/SocialLogin/GithubAuthenticationService.swift +++ b/DevLog/Infra/Service/SocialLogin/GithubAuthenticationService.swift @@ -31,6 +31,12 @@ final class GithubAuthenticationService: NSObject, AuthenticationService { private let providerID = AuthProviderID.gitHub private let provider = TopViewControllerProvider() private let logger = Logger(category: "GithubAuthService") + private let gitHubApiClient = NXAPIClient( + configuration: NXClientConfiguration( + baseURL: GitHubAPI.baseURL, + headers: ["Accept": GitHubAPI.acceptHeader] + ) + ) func signIn() async throws -> AuthDataResponse { logger.info("Starting GitHub sign in") @@ -249,13 +255,6 @@ final class GithubAuthenticationService: NSObject, AuthenticationService { // GitHub API로 사용자 프로필 정보 가져오기 private func requestUserProfile(accessToken: String) async throws -> GitHubUser { - let gitHubApiClient = NXAPIClient( - configuration: NXClientConfiguration( - baseURL: GitHubAPI.baseURL, - headers: ["Accept": GitHubAPI.acceptHeader] - ) - ) - let gitHubUser = try await gitHubApiClient .get("/user", as: GitHubUser.self) .header("Authorization", "Bearer \(accessToken)") @@ -276,13 +275,6 @@ final class GithubAuthenticationService: NSObject, AuthenticationService { } private func requestPrimaryVerifiedEmail(accessToken: String) async throws -> String? { - let gitHubApiClient = NXAPIClient( - configuration: NXClientConfiguration( - baseURL: GitHubAPI.baseURL, - headers: ["Accept": GitHubAPI.acceptHeader] - ) - ) - let gitHubEmails = try await gitHubApiClient .get("/user/emails", as: [GitHubEmail].self) .header("Authorization", "Bearer \(accessToken)")