Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions Poppool/Poppool.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@
08B191AE2CF5BFA60057BC04 /* AgeSelectedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08B191AD2CF5BFA60057BC04 /* AgeSelectedView.swift */; };
08B191B02CF5BFAE0057BC04 /* AgeSelectedReactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08B191AF2CF5BFAE0057BC04 /* AgeSelectedReactor.swift */; };
08B191B22CF5C0A60057BC04 /* PPPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08B191B12CF5C0A60057BC04 /* PPPicker.swift */; };
08B191B42CF609260057BC04 /* KakaoLoginService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08B191B32CF609260057BC04 /* KakaoLoginService.swift */; };
08B191B62CF6092B0057BC04 /* AppleLoginService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08B191B52CF6092B0057BC04 /* AppleLoginService.swift */; };
08B191B82CF6092F0057BC04 /* AuthServiceable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08B191B72CF6092F0057BC04 /* AuthServiceable.swift */; };
08B191BA2CF609AE0057BC04 /* RxKakaoSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 08B191B92CF609AE0057BC04 /* RxKakaoSDK */; };
08B191BC2CF609AE0057BC04 /* RxKakaoSDKAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 08B191BB2CF609AE0057BC04 /* RxKakaoSDKAuth */; };
08B191BE2CF609AE0057BC04 /* RxKakaoSDKUser in Frameworks */ = {isa = PBXBuildFile; productRef = 08B191BD2CF609AE0057BC04 /* RxKakaoSDKUser */; };
BDCA41C12CF35AC0005EECF6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDCA41C02CF35AC0005EECF6 /* AppDelegate.swift */; };
BDCA41C32CF35AC0005EECF6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDCA41C22CF35AC0005EECF6 /* SceneDelegate.swift */; };
BDCA41C52CF35AC0005EECF6 /* TestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDCA41C42CF35AC0005EECF6 /* TestViewController.swift */; };
Expand Down Expand Up @@ -210,6 +216,9 @@
08B191AD2CF5BFA60057BC04 /* AgeSelectedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AgeSelectedView.swift; sourceTree = "<group>"; };
08B191AF2CF5BFAE0057BC04 /* AgeSelectedReactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AgeSelectedReactor.swift; sourceTree = "<group>"; };
08B191B12CF5C0A60057BC04 /* PPPicker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PPPicker.swift; sourceTree = "<group>"; };
08B191B32CF609260057BC04 /* KakaoLoginService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KakaoLoginService.swift; sourceTree = "<group>"; };
08B191B52CF6092B0057BC04 /* AppleLoginService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppleLoginService.swift; sourceTree = "<group>"; };
08B191B72CF6092F0057BC04 /* AuthServiceable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthServiceable.swift; sourceTree = "<group>"; };
BDCA41BD2CF35AC0005EECF6 /* Poppool.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Poppool.app; sourceTree = BUILT_PRODUCTS_DIR; };
BDCA41C02CF35AC0005EECF6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
BDCA41C22CF35AC0005EECF6 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
Expand All @@ -234,11 +243,14 @@
BDCA41F52CF35D33005EECF6 /* Kingfisher in Frameworks */,
BDCA42072CF35FA6005EECF6 /* Tabman in Frameworks */,
BDCA42042CF35F76005EECF6 /* PanModal in Frameworks */,
08B191BA2CF609AE0057BC04 /* RxKakaoSDK in Frameworks */,
08B191BC2CF609AE0057BC04 /* RxKakaoSDKAuth in Frameworks */,
083A25D02CF364B70099B58E /* Alamofire in Frameworks */,
BDCA42102CF35FF5005EECF6 /* Lottie in Frameworks */,
BDCA41FE2CF35EE7005EECF6 /* ReactorKit in Frameworks */,
BDCA41F22CF35D0D005EECF6 /* SnapKit in Frameworks */,
BDCA420A2CF35FB1005EECF6 /* Pageboy in Frameworks */,
08B191BE2CF609AE0057BC04 /* RxKakaoSDKUser in Frameworks */,
BDCA42012CF35EFE005EECF6 /* RxKeyboard in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -367,6 +379,9 @@
083A25A02CF3623C0099B58E /* Infrastructure */ = {
isa = PBXGroup;
children = (
08B191B72CF6092F0057BC04 /* AuthServiceable.swift */,
08B191B52CF6092B0057BC04 /* AppleLoginService.swift */,
08B191B32CF609260057BC04 /* KakaoLoginService.swift */,
083A25BE2CF362770099B58E /* Logger */,
);
path = Infrastructure;
Expand Down Expand Up @@ -724,6 +739,9 @@
BDCA420C2CF35FD2005EECF6 /* RxGesture */,
BDCA420F2CF35FF5005EECF6 /* Lottie */,
083A25CF2CF364B70099B58E /* Alamofire */,
08B191B92CF609AE0057BC04 /* RxKakaoSDK */,
08B191BB2CF609AE0057BC04 /* RxKakaoSDKAuth */,
08B191BD2CF609AE0057BC04 /* RxKakaoSDKUser */,
);
productName = Poppool;
productReference = BDCA41BD2CF35AC0005EECF6 /* Poppool.app */;
Expand Down Expand Up @@ -868,6 +886,7 @@
08B1913D2CF367EB0057BC04 /* Constants.swift in Sources */,
083A25B72CF362670099B58E /* RequestEndpoint.swift in Sources */,
083A25B82CF362670099B58E /* IndicatorMaker.swift in Sources */,
08B191B62CF6092B0057BC04 /* AppleLoginService.swift in Sources */,
083A25B22CF362670099B58E /* NetworkError.swift in Sources */,
083A25832CF361EF0099B58E /* BaseViewController.swift in Sources */,
083A25922CF361F90099B58E /* ViewConvention.swift in Sources */,
Expand All @@ -883,6 +902,7 @@
08B1919C2CF4A77C0057BC04 /* TagSection.swift in Sources */,
083A25902CF361F90099B58E /* TestDynamicCell.swift in Sources */,
08B1917A2CF452B30057BC04 /* SignUpTermsView.swift in Sources */,
08B191B82CF6092F0057BC04 /* AuthServiceable.swift in Sources */,
BDCA41C52CF35AC0005EECF6 /* TestViewController.swift in Sources */,
083A258C2CF361F90099B58E /* ControllerConvention.swift in Sources */,
08B191982CF4A1010057BC04 /* SignUpStep4Reactor.swift in Sources */,
Expand All @@ -894,6 +914,7 @@
083A25B62CF362670099B58E /* MultipartEndPoint.swift in Sources */,
08B191942CF4A0F00057BC04 /* SignUpStep4View.swift in Sources */,
08B1918D2CF49FF70057BC04 /* SignUpStep3View.swift in Sources */,
08B191B42CF609260057BC04 /* KakaoLoginService.swift in Sources */,
BDCA41C12CF35AC0005EECF6 /* AppDelegate.swift in Sources */,
08B191A42CF5A7030057BC04 /* PPSegmentedControl.swift in Sources */,
08B191AE2CF5BFA60057BC04 /* AgeSelectedView.swift in Sources */,
Expand Down Expand Up @@ -1390,6 +1411,21 @@
package = 083A25CE2CF364B70099B58E /* XCRemoteSwiftPackageReference "Alamofire" */;
productName = Alamofire;
};
08B191B92CF609AE0057BC04 /* RxKakaoSDK */ = {
isa = XCSwiftPackageProductDependency;
package = BDCA41F92CF35EC0005EECF6 /* XCRemoteSwiftPackageReference "kakao-ios-sdk-rx" */;
productName = RxKakaoSDK;
};
08B191BB2CF609AE0057BC04 /* RxKakaoSDKAuth */ = {
isa = XCSwiftPackageProductDependency;
package = BDCA41F92CF35EC0005EECF6 /* XCRemoteSwiftPackageReference "kakao-ios-sdk-rx" */;
productName = RxKakaoSDKAuth;
};
08B191BD2CF609AE0057BC04 /* RxKakaoSDKUser */ = {
isa = XCSwiftPackageProductDependency;
package = BDCA41F92CF35EC0005EECF6 /* XCRemoteSwiftPackageReference "kakao-ios-sdk-rx" */;
productName = RxKakaoSDKUser;
};
BDCA41F12CF35D0D005EECF6 /* SnapKit */ = {
isa = XCSwiftPackageProductDependency;
package = BDCA41F02CF35D0D005EECF6 /* XCRemoteSwiftPackageReference "SnapKit" */;
Expand Down
6 changes: 5 additions & 1 deletion Poppool/Poppool/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@

import UIKit

import RxKakaoSDKAuth
import KakaoSDKAuth
import RxKakaoSDKCommon

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
RxKakaoSDK.initSDK(appKey: "", loggingEnable: false)
return true
}

Expand Down
16 changes: 14 additions & 2 deletions Poppool/Poppool/Application/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

import UIKit

import RxKakaoSDKAuth
import KakaoSDKAuth
import RxSwift

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?
Expand All @@ -17,8 +21,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
window = UIWindow(windowScene: windowScene)


let rootViewController = SignUpMainController()
rootViewController.reactor = SignUpMainReactor()
let rootViewController = LoginController()
rootViewController.reactor = LoginReactor()

let navigationController = UINavigationController(rootViewController: rootViewController)
window?.rootViewController = navigationController
Expand All @@ -39,5 +43,13 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {

func sceneDidEnterBackground(_ scene: UIScene) {
}

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
if let url = URLContexts.first?.url {
if AuthApi.isKakaoTalkLoginUrl(url) {
_ = AuthController.rx.handleOpenUrl(url: url)
}
}
}
}

124 changes: 124 additions & 0 deletions Poppool/Poppool/Infrastructure/AppleLoginService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
//
// AppleLoginService.swift
// MomsVillage
//
// Created by SeoJunYoung on 8/20/24.
//

import RxSwift
import AuthenticationServices

final class AppleLoginService: NSObject, AuthServiceable {

// 사용자 자격 증명 정보를 방출할 subject
private var authServiceResponse: PublishSubject<AuthServiceResponse> = .init()

override init() {
super.init()
Logger.log(
message: "\(self) init",
category: .info,
fileName: #file,
line: #line
)
}

deinit {
Logger.log(
message: "\(self) deinit",
category: .info,
fileName: #file,
line: #line
)
}

func fetchUserCredential() -> Observable<AuthServiceResponse> {
performRequest()
return authServiceResponse
}

// Apple 인증 요청을 수행하는 함수
private func performRequest() {
let appleIDProvider = ASAuthorizationAppleIDProvider()
let request = appleIDProvider.createRequest()
request.requestedScopes = [.fullName, .email]

let authorizationController = ASAuthorizationController(authorizationRequests: [request])
authorizationController.delegate = self
authorizationController.presentationContextProvider = self
authorizationController.performRequests()
}
}

extension AppleLoginService: ASAuthorizationControllerPresentationContextProviding,
ASAuthorizationControllerDelegate {
// 인증 컨트롤러의 프레젠테이션 앵커를 반환하는 함수
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
let scenes = UIApplication.shared.connectedScenes
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
)
return UIWindow()
}
return window
}

// 인증 성공 시 호출되는 함수
func authorizationController(
controller: ASAuthorizationController,
didCompleteWithAuthorization authorization: ASAuthorization
) {
switch authorization.credential {
case let appleIDCredential as ASAuthorizationAppleIDCredential:
guard let idToken = appleIDCredential.identityToken else {
// 토큰이 없는 경우 오류 방출
Logger.log(
message: "AppleLogin Token is Not Found",
category: .error,
fileName: #file,
line: #line
)
authServiceResponse.onError(AuthError.unknownError)
return
}
guard let idToken = String(data: idToken, encoding: .utf8) else {
Logger.log(
message: "AppleLogin Token Convert Fail",
category: .error,
fileName: #file,
line: #line
)
authServiceResponse.onError(AuthError.unknownError)
return
}
guard let authorizationCode = appleIDCredential.authorizationCode else {
return
}

guard let convertAuthorizationCode = String(data: authorizationCode, encoding: .utf8) else {
return
}
authServiceResponse.onNext(.init(idToken: idToken, authorizationCode: convertAuthorizationCode))
default:
break
}
}
// 인증 실패 시 호출되는 함수
func authorizationController(
controller: ASAuthorizationController,
didCompleteWithError error: Error
) {
Logger.log(
message: "AppleLogin Fail",
category: .error,
fileName: #file,
line: #line
)
authServiceResponse.onError(error)
}
}
28 changes: 28 additions & 0 deletions Poppool/Poppool/Infrastructure/AuthServiceable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// AuthService.swift
// MomsVillage
//
// Created by SeoJunYoung on 8/22/24.
//

import UIKit

import RxSwift

protocol AuthServiceable: AnyObject {
/// 사용자 자격 증명을 가져오는 함수
/// - Returns: Response 형태의 사용자 자격 증명
func fetchUserCredential() -> Observable<AuthServiceResponse>
}

struct AuthServiceResponse {
var idToken: String?
var authorizationCode: String?
var kakaoUserId: Int64?
var kakaoAccessToken: String?
}

enum AuthError: Error {
case notInstalled
case unknownError
}
Loading