diff --git a/HealthFoodMe/HealthFoodMe.xcodeproj/project.pbxproj b/HealthFoodMe/HealthFoodMe.xcodeproj/project.pbxproj index eff8422e..253007e5 100644 --- a/HealthFoodMe/HealthFoodMe.xcodeproj/project.pbxproj +++ b/HealthFoodMe/HealthFoodMe.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 3BCC441E28745FD800661A12 /* SocialLoginVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BCC441D28745FD800661A12 /* SocialLoginVC.swift */; }; + 3BCC442028745FE500661A12 /* SocialLogin.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3BCC441F28745FE500661A12 /* SocialLogin.storyboard */; }; 6005A822AEB1A47010D6C01E /* Pods_HealthFoodMe.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DEDECAEA3BF2AEAD960B4B3C /* Pods_HealthFoodMe.framework */; }; EB6A44C7287366DF00749582 /* .swiftlint.yml in Resources */ = {isa = PBXBuildFile; fileRef = EB6A44C6287366DF00749582 /* .swiftlint.yml */; }; EBF66ABC287227F500DE0ED1 /* UserDefaults+.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF66A51287227F500DE0ED1 /* UserDefaults+.swift */; }; @@ -87,6 +89,9 @@ /* Begin PBXFileReference section */ 26C3E6667A430DB48E0CC0FE /* Pods-HealthFoodMe.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HealthFoodMe.release.xcconfig"; path = "Target Support Files/Pods-HealthFoodMe/Pods-HealthFoodMe.release.xcconfig"; sourceTree = ""; }; + 3B0B254D28757C7100950539 /* HealthFoodMe.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = HealthFoodMe.entitlements; sourceTree = ""; }; + 3BCC441D28745FD800661A12 /* SocialLoginVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocialLoginVC.swift; sourceTree = ""; }; + 3BCC441F28745FE500661A12 /* SocialLogin.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = SocialLogin.storyboard; sourceTree = ""; }; 75E42041F59816FF5154CDD3 /* Pods-HealthFoodMe.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HealthFoodMe.debug.xcconfig"; path = "Target Support Files/Pods-HealthFoodMe/Pods-HealthFoodMe.debug.xcconfig"; sourceTree = ""; }; DEDECAEA3BF2AEAD960B4B3C /* Pods_HealthFoodMe.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_HealthFoodMe.framework; sourceTree = BUILT_PRODUCTS_DIR; }; EB085ED628716E1900361837 /* HealthFoodMe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HealthFoodMe.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -188,6 +193,31 @@ name = Frameworks; sourceTree = ""; }; + 3BCC441A28745FA900661A12 /* Auth */ = { + isa = PBXGroup; + children = ( + 3BCC441B28745FB000661A12 /* SocialLoginScene */, + ); + path = Auth; + sourceTree = ""; + }; + 3BCC441B28745FB000661A12 /* SocialLoginScene */ = { + isa = PBXGroup; + children = ( + 3BCC441C28745FC500661A12 /* VC */, + ); + path = SocialLoginScene; + sourceTree = ""; + }; + 3BCC441C28745FC500661A12 /* VC */ = { + isa = PBXGroup; + children = ( + 3BCC441D28745FD800661A12 /* SocialLoginVC.swift */, + 3BCC441F28745FE500661A12 /* SocialLogin.storyboard */, + ); + path = VC; + sourceTree = ""; + }; E3F60CBC9B890A7FB4D4AAAF /* Pods */ = { isa = PBXGroup; children = ( @@ -218,6 +248,7 @@ EB085ED828716E1900361837 /* HealthFoodMe */ = { isa = PBXGroup; children = ( + 3B0B254D28757C7100950539 /* HealthFoodMe.entitlements */, EBF66A74287227F500DE0ED1 /* Application */, EBF66A80287227F500DE0ED1 /* Data */, EBF66AB3287227F500DE0ED1 /* Domain */, @@ -435,6 +466,7 @@ EBF66A90287227F500DE0ED1 /* Presentation */ = { isa = PBXGroup; children = ( + 3BCC441A28745FA900661A12 /* Auth */, EBF66A9F287227F500DE0ED1 /* Common */, EBF66A91287227F500DE0ED1 /* Home */, ); @@ -648,6 +680,7 @@ buildActionMask = 2147483647; files = ( EB6A44C7287366DF00749582 /* .swiftlint.yml in Resources */, + 3BCC442028745FE500661A12 /* SocialLogin.storyboard in Resources */, EBF66AD0287227F500DE0ED1 /* Assets.xcassets in Resources */, EBF66AD2287227F500DE0ED1 /* LaunchScreen.storyboard in Resources */, EBF66AD1287227F500DE0ED1 /* NotoSansSC-Bold.otf in Resources */, @@ -762,6 +795,7 @@ EBF66ABE287227F500DE0ED1 /* UITextView+.swift in Sources */, EBF66AD5287227F500DE0ED1 /* ViewModelType.swift in Sources */, EBF66ADA287227F500DE0ED1 /* controllerFromStoryBoard.swift in Sources */, + 3BCC441E28745FD800661A12 /* SocialLoginVC.swift in Sources */, EBF66AEC287227F500DE0ED1 /* PostDetailCVLayout.swift in Sources */, EBF66ABD287227F500DE0ED1 /* UIDevice+.swift in Sources */, EBF66AE1287227F500DE0ED1 /* BaseService.swift in Sources */, @@ -928,6 +962,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = HealthFoodMe/HealthFoodMe.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; @@ -959,6 +994,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = HealthFoodMe/HealthFoodMe.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; diff --git a/HealthFoodMe/HealthFoodMe/Application/AppDelegate.swift b/HealthFoodMe/HealthFoodMe/Application/AppDelegate.swift index 4a80abd5..a441dd51 100644 --- a/HealthFoodMe/HealthFoodMe/Application/AppDelegate.swift +++ b/HealthFoodMe/HealthFoodMe/Application/AppDelegate.swift @@ -7,6 +7,9 @@ import UIKit +import AuthenticationServices +import KakaoSDKCommon + @main class AppDelegate: UIResponder, UIApplicationDelegate { @@ -18,8 +21,29 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + KakaoSDK.initSDK(appKey : "8483f545857597ac5a551516e471a131") + + let appleIDProvider = ASAuthorizationAppleIDProvider() + appleIDProvider.getCredentialState(forUserID: "00000.abcabcabcabc.0000(로그인에 사용한 UserIdentifier)") { (credentialState, error) in + switch credentialState { + case .authorized: // 이미 증명이 된 경우 (정상) + print("authorized") + // The Apple ID credential is valid. + case .revoked: // 증명을 취소했을 때, + print("revoked") + // 로그인뷰로 이동하기 + case .notFound: // 증명이 존재하지 않을 경우 + print("notFound") + // 로그인뷰로 이동하기 + + default: + break + } + } + return true } + // MARK: UISceneSession Lifecycle diff --git a/HealthFoodMe/HealthFoodMe/Application/SceneDelegate.swift b/HealthFoodMe/HealthFoodMe/Application/SceneDelegate.swift index 1aad2dfd..721cb02f 100644 --- a/HealthFoodMe/HealthFoodMe/Application/SceneDelegate.swift +++ b/HealthFoodMe/HealthFoodMe/Application/SceneDelegate.swift @@ -7,30 +7,39 @@ import UIKit +import KakaoSDKAuth + class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? + func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { + if let url = URLContexts.first?.url { + if (AuthApi.isKakaoTalkLoginUrl(url)) { + _ = AuthController.handleOpenUrl(url: url) + } + } + } func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { - if #available(iOS 15.0, *) { - let navigationBarAppearance = UINavigationBarAppearance() - navigationBarAppearance.configureWithOpaqueBackground() - navigationBarAppearance.backgroundColor = .white - navigationBarAppearance.shadowColor = .white - - UINavigationBar.appearance().standardAppearance = navigationBarAppearance - UINavigationBar.appearance().scrollEdgeAppearance = navigationBarAppearance - } - - guard let windowScene = (scene as? UIWindowScene) else { return } - let rootViewController = PostDetailVC() - let window = UIWindow(windowScene: windowScene) - window.rootViewController = rootViewController - self.window = window - window.backgroundColor = .white - window.makeKeyAndVisible() +// if #available(iOS 15.0, *) { +// let navigationBarAppearance = UINavigationBarAppearance() +// navigationBarAppearance.configureWithOpaqueBackground() +// navigationBarAppearance.backgroundColor = .white +// navigationBarAppearance.shadowColor = .white +// +// UINavigationBar.appearance().standardAppearance = navigationBarAppearance +// UINavigationBar.appearance().scrollEdgeAppearance = navigationBarAppearance +// } +// +// guard let windowScene = (scene as? UIWindowScene) else { return } +// let rootViewController = PostDetailVC() +// let window = UIWindow(windowScene: windowScene) +// window.rootViewController = rootViewController +// self.window = window +// window.backgroundColor = .white +// window.makeKeyAndVisible() } func sceneDidDisconnect(_ scene: UIScene) { diff --git a/HealthFoodMe/HealthFoodMe/Global/Literals/StringLiterals.swift b/HealthFoodMe/HealthFoodMe/Global/Literals/StringLiterals.swift index 3a090092..093007d9 100644 --- a/HealthFoodMe/HealthFoodMe/Global/Literals/StringLiterals.swift +++ b/HealthFoodMe/HealthFoodMe/Global/Literals/StringLiterals.swift @@ -16,6 +16,11 @@ struct I18N { static let myPlan = "마이 플랜" } + struct Auth { + static let kakaoLoginError = "카카오 로그인에 실패하였습니다." + static let appleLoginError = "애플 로그인에 실패하였습니다." + } + struct Alert { static let alarm = "알림" static let error = "오류" diff --git a/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/Contents.json b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authSubTitle.imageset/Contents.json b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authSubTitle.imageset/Contents.json new file mode 100644 index 00000000..ae48635f --- /dev/null +++ b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authSubTitle.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "authSubTitle.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "authSubTitle@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "authSubTitle@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authSubTitle.imageset/authSubTitle.png b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authSubTitle.imageset/authSubTitle.png new file mode 100644 index 00000000..0ee4c795 Binary files /dev/null and b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authSubTitle.imageset/authSubTitle.png differ diff --git a/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authSubTitle.imageset/authSubTitle@2x.png b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authSubTitle.imageset/authSubTitle@2x.png new file mode 100644 index 00000000..79f6a36a Binary files /dev/null and b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authSubTitle.imageset/authSubTitle@2x.png differ diff --git a/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authSubTitle.imageset/authSubTitle@3x.png b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authSubTitle.imageset/authSubTitle@3x.png new file mode 100644 index 00000000..64458ed1 Binary files /dev/null and b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authSubTitle.imageset/authSubTitle@3x.png differ diff --git a/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authTitle.imageset/Contents.json b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authTitle.imageset/Contents.json new file mode 100644 index 00000000..787d25e9 --- /dev/null +++ b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authTitle.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "authTitle.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "authTitle@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "authTitle@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authTitle.imageset/authTitle.png b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authTitle.imageset/authTitle.png new file mode 100644 index 00000000..15aa7d0d Binary files /dev/null and b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authTitle.imageset/authTitle.png differ diff --git a/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authTitle.imageset/authTitle@2x.png b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authTitle.imageset/authTitle@2x.png new file mode 100644 index 00000000..193e607e Binary files /dev/null and b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authTitle.imageset/authTitle@2x.png differ diff --git a/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authTitle.imageset/authTitle@3x.png b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authTitle.imageset/authTitle@3x.png new file mode 100644 index 00000000..8044effe Binary files /dev/null and b/HealthFoodMe/HealthFoodMe/Global/Resources/Assets.xcassets/Auth/authTitle.imageset/authTitle@3x.png differ diff --git a/HealthFoodMe/HealthFoodMe/HealthFoodMe.entitlements b/HealthFoodMe/HealthFoodMe/HealthFoodMe.entitlements new file mode 100644 index 00000000..a812db50 --- /dev/null +++ b/HealthFoodMe/HealthFoodMe/HealthFoodMe.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.developer.applesignin + + Default + + + diff --git a/HealthFoodMe/HealthFoodMe/Info.plist b/HealthFoodMe/HealthFoodMe/Info.plist index bc240fdb..be872845 100644 --- a/HealthFoodMe/HealthFoodMe/Info.plist +++ b/HealthFoodMe/HealthFoodMe/Info.plist @@ -2,6 +2,22 @@ + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + kakao8483f545857597ac5a551516e471a131 + + + + LSApplicationQueriesSchemes + + kakaokompassauth + kakaolink + NSAppTransportSecurity NSAllowsArbitraryLoads @@ -20,6 +36,8 @@ Default Configuration UISceneDelegateClassName $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + SocialLogin diff --git a/HealthFoodMe/HealthFoodMe/Presentation/Auth/SocialLoginScene/VC/SocialLogin.storyboard b/HealthFoodMe/HealthFoodMe/Presentation/Auth/SocialLoginScene/VC/SocialLogin.storyboard new file mode 100644 index 00000000..0600375b --- /dev/null +++ b/HealthFoodMe/HealthFoodMe/Presentation/Auth/SocialLoginScene/VC/SocialLogin.storyboard @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/HealthFoodMe/HealthFoodMe/Presentation/Auth/SocialLoginScene/VC/SocialLoginVC.swift b/HealthFoodMe/HealthFoodMe/Presentation/Auth/SocialLoginScene/VC/SocialLoginVC.swift new file mode 100644 index 00000000..d235e988 --- /dev/null +++ b/HealthFoodMe/HealthFoodMe/Presentation/Auth/SocialLoginScene/VC/SocialLoginVC.swift @@ -0,0 +1,164 @@ +// +// SocialLoginVC.swift +// HealthFoodMe +// +// Created by 강윤서 on 2022/07/05. +// + +import UIKit + +import AuthenticationServices +import KakaoSDKAuth +import KakaoSDKCommon +import KakaoSDKUser +import SnapKit + +class SocialLoginVC: UIViewController { + + // MARK: - Properties + private lazy var titleImageView = UIImageView() + private lazy var subtitleImageView = UIImageView() + private lazy var kakaoLoginButton = UIButton() + private lazy var appleLoginButton = UIButton() + + // MARK: - View Life Cycle + override func viewDidLoad() { + super.viewDidLoad() + + setUI() + setLayout() + setAddTarget() + } + +} + +// MARK: - extension +extension SocialLoginVC { + private func kakaoLogin() { + if UserApi.isKakaoTalkLoginAvailable() { + // 카카오톡 로그인. api 호출 결과를 클로저로 전달. + UserApi.shared.loginWithKakaoTalk { (oauthToken, error) in + if let _ = error { self.showKakaoLoginFailMessage() } else { + if let accessToken = oauthToken?.accessToken { + // 엑세스 토큰 받아와서 서버에게 넘겨주는 로직 작성 + + print("TOKEN", accessToken) + self.postSocialLoginData(socialToken: accessToken, socialType: "KAKAO") + } + } + } + } else { // 웹으로 로그인해도 똑같이 처리되도록 + UserApi.shared.loginWithKakaoAccount { (oauthToken, error) in + if let _ = error { self.showKakaoLoginFailMessage() } else { + if let accessToken = oauthToken?.accessToken { + print("TOKEN", accessToken) + self.postSocialLoginData(socialToken: accessToken, socialType: "KAKAO") + } + // 성공해서 성공 VC로 이동 + } + } + } + } + + private func showKakaoLoginFailMessage() { + self.makeAlert(title: I18N.Alert.error, message: I18N.Auth.kakaoLoginError, okAction: nil, completion: nil) + } + + private func postSocialLoginData(socialToken: String, socialType: String) { + + } + + private func appleLogin() { + let appleIDProvider = ASAuthorizationAppleIDProvider() + let request = appleIDProvider.createRequest() + request.requestedScopes = [.fullName, .email] + + let authorizationController = ASAuthorizationController(authorizationRequests: [request]) + authorizationController.delegate = self + authorizationController.presentationContextProvider = self + authorizationController.performRequests() + } + + private func setUI() { + titleImageView.image = UIImage(named: "authTitle") + subtitleImageView.image = UIImage(named: "authSubtitle") + + kakaoLoginButton.setTitle("카카오톡 아이디로 로그인", for: .normal) + kakaoLoginButton.setTitleColor(.black, for: .normal) + + appleLoginButton.setTitle("애플 아이디로 로그인", for: .normal) + appleLoginButton.backgroundColor = UIColor.carrotBlack + } + + private func setLayout() { + view.addSubviews(titleImageView, subtitleImageView, kakaoLoginButton, appleLoginButton) + titleImageView.snp.makeConstraints { make in + make.top.equalToSuperview().inset(270) + make.centerX.equalToSuperview() + } + + subtitleImageView.snp.makeConstraints { make in + make.top.equalTo(titleImageView.snp.bottom).offset(15) + make.centerX.equalToSuperview() + } + + kakaoLoginButton.snp.makeConstraints { make in + make.top.equalTo(subtitleImageView.snp.bottom).offset(100) + make.leading.trailing.equalToSuperview().inset(50) + make.centerX.equalToSuperview() + } + + appleLoginButton.snp.makeConstraints {make in + make.top.equalTo(kakaoLoginButton.snp.bottom).offset(9) + make.leading.trailing.equalToSuperview().inset(50) + make.centerX.equalToSuperview() + } + } + + private func setAddTarget() { + kakaoLoginButton.addTarget(self, action: #selector(doKakaoLogin), for: .touchUpInside) + appleLoginButton.addTarget(self, action: #selector(doAppleLogin), for: .touchUpInside) + } + + // MARK: - @objc Methods + @objc func doKakaoLogin() { + kakaoLogin() + } + + @objc func doAppleLogin() { + appleLogin() + } +} + +extension SocialLoginVC: ASAuthorizationControllerPresentationContextProviding { + private func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor { + return self.view.window! + } +} + +extension SocialLoginVC: ASAuthorizationControllerDelegate { + // Apple ID 연동 성공시 + private func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { + switch authorization.credential { + // Apple ID + case let appleIDCredential as ASAuthorizationAppleIDCredential : + let userIdentifier = appleIDCredential.user + let fullName = appleIDCredential.fullName + let email = appleIDCredential.email + + print("User ID : \(userIdentifier)") + print("User Email : \(email ?? "")") + print("User Name : \((fullName?.givenName ?? "") + (fullName?.familyName ?? ""))") + + let identityToken = appleIDCredential.identityToken + let tokenString = String(data: identityToken!, encoding: .utf8) + + if let token = tokenString { + postSocialLoginData(socialToken: token, socialType: "APPLE") + } + default: + // 실패 시 실패VC로 이동 + print("애플아이디 로그인 실패") + } + } +} diff --git a/HealthFoodMe/HealthFoodMe/Presentation/Home/PostDetailScene/Layout/PostDetailCVLayout.swift b/HealthFoodMe/HealthFoodMe/Presentation/Home/PostDetailScene/Layout/PostDetailCVLayout.swift index 9bd7e22d..0389f128 100644 --- a/HealthFoodMe/HealthFoodMe/Presentation/Home/PostDetailScene/Layout/PostDetailCVLayout.swift +++ b/HealthFoodMe/HealthFoodMe/Presentation/Home/PostDetailScene/Layout/PostDetailCVLayout.swift @@ -5,36 +5,36 @@ // Created by Junho Lee on 2022/05/18. // -import UIKit - -extension PostDetailVC { - internal func createLayout() -> UICollectionViewCompositionalLayout { - return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in - if sectionNumber == 0 { - let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) - let item = NSCollectionLayoutItem(layoutSize: itemSize) - let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(UIScreen.main.bounds.width), heightDimension: .absolute(UIScreen.main.bounds.width)) - let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) - let section = NSCollectionLayoutSection(group: group) - section.orthogonalScrollingBehavior = .groupPagingCentered - section.visibleItemsInvalidationHandler = { items, contentOffset, environment in - let currentPage = Int(max(0, round(contentOffset.x / environment.container.contentSize.width))) - self.pageControl.currentPage = currentPage - } - return section - } else { - let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(315)) - let item = NSCollectionLayoutItem(layoutSize: itemSize) - let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(315)) - let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: 1) - let section = NSCollectionLayoutSection(group: group) - let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(85)) - let header = - NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: PostDetailUserHeader.className, alignment: .topLeading) - section.boundarySupplementaryItems = [header] - section.orthogonalScrollingBehavior = .none - return section - } - } - } -} +//import UIKit +// +//extension PostDetailVC { +// internal func createLayout() -> UICollectionViewCompositionalLayout { +// return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in +// if sectionNumber == 0 { +// let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) +// let item = NSCollectionLayoutItem(layoutSize: itemSize) +// let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(UIScreen.main.bounds.width), heightDimension: .absolute(UIScreen.main.bounds.width)) +// let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) +// let section = NSCollectionLayoutSection(group: group) +// section.orthogonalScrollingBehavior = .groupPagingCentered +// section.visibleItemsInvalidationHandler = { items, contentOffset, environment in +// let currentPage = Int(max(0, round(contentOffset.x / environment.container.contentSize.width))) +// self.pageControl.currentPage = currentPage +// } +// return section +// } else { +// let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(315)) +// let item = NSCollectionLayoutItem(layoutSize: itemSize) +// let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(315)) +// let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: 1) +// let section = NSCollectionLayoutSection(group: group) +// let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(85)) +// let header = +// NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: PostDetailUserHeader.className, alignment: .topLeading) +// section.boundarySupplementaryItems = [header] +// section.orthogonalScrollingBehavior = .none +// return section +// } +// } +// } +//} diff --git a/HealthFoodMe/HealthFoodMe/Presentation/Home/PostDetailScene/VC/PostDetailVC.swift b/HealthFoodMe/HealthFoodMe/Presentation/Home/PostDetailScene/VC/PostDetailVC.swift index dbec0982..745c66a2 100644 --- a/HealthFoodMe/HealthFoodMe/Presentation/Home/PostDetailScene/VC/PostDetailVC.swift +++ b/HealthFoodMe/HealthFoodMe/Presentation/Home/PostDetailScene/VC/PostDetailVC.swift @@ -1,302 +1,302 @@ +//// +//// PostDetailVC.swift +//// HealthFoodMe +//// +//// Created by Junho Lee on 2022/05/16. +//// // -// PostDetailVC.swift -// HealthFoodMe +//import UIKit // -// Created by Junho Lee on 2022/05/16. +//import RxSwift +//import RxCocoa +//import SnapKit // - -import UIKit - -import RxSwift -import RxCocoa -import SnapKit - -final class PostDetailVC: BaseVC { - - // MARK: - Properties - - static var storyboard: Storyboards = .postDetail - - enum SectionType: Int { - case imageSection = 0 - case postSection = 1 - } - - var postDetailModel: PostDetail? { - didSet { - detailCV.reloadData() - if let data = postDetailModel { - self.pageControl.numberOfPages = min(5, data.image.count) - self.pageControl.currentPage = 0 - bottomView.setData(data: data) - } - } - } - - var postId: String? - var fromPostWrite: Bool = false - - private lazy var postContentCell = PostContentCVC() - - private lazy var detailCV: UICollectionView = { - let layout = createLayout() - layout.configuration.interSectionSpacing = 0 - let cv = UICollectionView(frame: .zero, collectionViewLayout: layout) - cv.showsHorizontalScrollIndicator = false - cv.backgroundColor = .carrotWhite - return cv - }() - - internal let pageControl: UIPageControl = { - let pc = UIPageControl() - pc.numberOfPages = 5 - pc.pageIndicatorTintColor = .carrotDarkLightGray - pc.currentPageIndicatorTintColor = .carrotWhite - return pc - }() - - private lazy var naviHomeButton: UIButton = { - let bt = UIButton() - bt.setImage(ImageLiterals.PostDetail.homeIcon, for: .normal) - bt.addAction(UIAction(handler: { _ in - self.navigationController?.popViewController(animated: true) - }), for: .touchUpInside) - bt.frame = CGRect(x: 0, y: 0, width: 24, height: 24) - return bt - }() - - private lazy var naviMoreButton: UIButton = { - let bt = UIButton() - bt.setImage(ImageLiterals.PostDetail.moreIcon, for: .normal) - bt.addAction(UIAction(handler: { _ in - - }), for: .touchUpInside) - bt.frame = CGRect(x: 0, y: 0, width: 24, height: 24) - return bt - }() - - private lazy var bottomView = PostDetailBottomView() - - // MARK: - Life Cycles - - override func viewDidLoad() { - super.viewDidLoad() - - bind() - setDelegate() - setCollectionView() - - getPostDetail() - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - - self.tabBarController?.tabBar.isHidden = true - } - - // MARK: - Bind - - override func bind() { - bottomView.likeButtonTapped.throttleOnMain(.seconds(1)) - .asDriver(onErrorJustReturn: true) - .drive(onNext: { [weak self] selected in - self?.bottomView.likeButton.isSelected.toggle() - self?.changeLikesStatus() - }) - .disposed(by: disposeBag) - } - - // MARK: - Custom Methods - - private func setDelegate() { - detailCV.delegate = self - detailCV.dataSource = self - } - - private func setCollectionView() { - detailCV.register(PostDetailUserHeader.self, forSupplementaryViewOfKind: PostDetailUserHeader.className, withReuseIdentifier: PostDetailUserHeader.className) - - PostImageCVC.register(target: detailCV) - PostContentCVC.register(target: detailCV) - } - - private func fetchPostDetailData(data: PostDetail) { - postContentCell.changeSellStatus(status: "\(data.onSale)") - } - - private func getPostDetail() { - if let postId = postId, - !fromPostWrite { - getPostDetail(postId: postId) - } - } - - // MARK: - UI & Layout - - override func setUI() { - view.backgroundColor = .carrotWhite - - let homeBtn = UIBarButtonItem(customView: naviHomeButton) - let moreBtn = UIBarButtonItem(customView: naviMoreButton) - self.navigationItem.setLeftBarButton(homeBtn, animated: false) - self.navigationItem.setRightBarButton(moreBtn, animated: false) - - self.navigationController?.isNavigationBarHidden = false - } - - override func setLayout() { - view.addSubviews(detailCV, pageControl, bottomView) - - detailCV.snp.makeConstraints { make in - make.top.leading.trailing.equalToSuperview() - make.bottom.equalTo(bottomView.snp.top) - } - - pageControl.snp.makeConstraints { make in - make.centerX.equalToSuperview() - make.top.equalToSuperview().inset(UIScreen.main.bounds.width-23) - } - - bottomView.snp.makeConstraints { make in - make.leading.trailing.bottom.equalToSuperview() - make.height.equalTo(103) - } - } -} - -// MARK: Collection DataSource - -extension PostDetailVC: UICollectionViewDataSource { - - func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - guard let sectionType = SectionType(rawValue: section) else { return 1 } - - switch sectionType { - case .imageSection: - if let data = postDetailModel { - return data.image.count - } else { return 5 } - - case .postSection: return 1 - } - } - - func numberOfSections(in collectionView: UICollectionView) -> Int { - return 2 - } - - func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { - if kind == PostDetailUserHeader.className { - let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: PostDetailUserHeader.className, for: indexPath) - if let view = view as? PostDetailUserHeader, - let data = postDetailModel { - view.setData(data: data) - } - return view - } else { return UICollectionReusableView() } - } - - func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - - guard let sectionType = SectionType(rawValue: indexPath.section) else { return UICollectionViewCell() } - - switch sectionType { - case .imageSection: - guard let postImageCell = collectionView.dequeueReusableCell(withReuseIdentifier: PostImageCVC.className, for: indexPath) as? PostImageCVC else { return UICollectionViewCell() } - if let data = postDetailModel { - postImageCell.setData(postImageURL: data.image[indexPath.row]) - } else { - postImageCell.setData(postImage: ImageLiterals.PostDetail.sample[indexPath.row]) - } - - return postImageCell - case .postSection: - guard let postContentCell = collectionView.dequeueReusableCell(withReuseIdentifier: PostContentCVC.className, for: indexPath) as? PostContentCVC else { return UICollectionViewCell() } - postContentCell.delegate = self - if let data = postDetailModel { - postContentCell.setData(data: data) - } - self.postContentCell = postContentCell - - return postContentCell - } - } -} - -// MARK: CollectionView Delegate -extension PostDetailVC: UICollectionViewDelegate { - func scrollViewDidScroll(_ scrollView: UIScrollView) { - self.pageControl.snp.remakeConstraints { make in - make.centerX.equalToSuperview() - make.top.equalToSuperview().inset(-scrollView.contentOffset.y+UIScreen.main.bounds.width-40) - } - } -} - -// MARK: Cell Delegate -extension PostDetailVC: PostContentDelegate { - func presentSellStatusActionSheet() { - let actionSheet = UIAlertController(title: "상태 변경", message: nil, preferredStyle: .actionSheet) - - let sellingAction = UIAlertAction(title: "판매중", style: .default) { _ in - self.postContentCell.changeSellStatus(status: "0") - self.changeSellStatus(onSale: "0") - } - let reservedAction = UIAlertAction(title: "예약중", style: .default) { _ in - self.postContentCell.changeSellStatus(status: "1") - self.changeSellStatus(onSale: "1") - } - let completedAction = UIAlertAction(title: "거래완료", style: .default) { _ in - self.postContentCell.changeSellStatus(status: "2") - self.changeSellStatus(onSale: "2") - } - let cancelAction = UIAlertAction(title: "닫기", style: .cancel, handler: nil) - - actionSheet.addAction(sellingAction) - actionSheet.addAction(reservedAction) - actionSheet.addAction(completedAction) - actionSheet.addAction(cancelAction) - - self.present(actionSheet, animated: true) - } -} - -// MARK: Network -extension PostDetailVC { - func getPostDetail(postId: String) { - HomeService.shared.getPostDetail(postId: postId) { networkResult in - switch networkResult { - case .success(let data): - if let data = data as? PostDetail { - self.postDetailModel = data - self.bottomView.setData(data: data) - } - default: - break - } - } - } - - func changeSellStatus(onSale: String) { - HomeService.shared.changeSellStatus(postId: postId ?? "", onSale: onSale) { networkResult in - switch networkResult { - case .success(let message): - print(message) - default: - break - } - } - } - - func changeLikesStatus() { - HomeService.shared.changeLikeStatus(postId: postId ?? "") { networkResult in - switch networkResult { - case .success(let message): - print(message) - default: - break - } - } - } -} +//final class PostDetailVC: BaseVC { +// +// // MARK: - Properties +// +// static var storyboard: Storyboards = .postDetail +// +// enum SectionType: Int { +// case imageSection = 0 +// case postSection = 1 +// } +// +// var postDetailModel: PostDetail? { +// didSet { +// detailCV.reloadData() +// if let data = postDetailModel { +// self.pageControl.numberOfPages = min(5, data.image.count) +// self.pageControl.currentPage = 0 +// bottomView.setData(data: data) +// } +// } +// } +// +// var postId: String? +// var fromPostWrite: Bool = false +// +// private lazy var postContentCell = PostContentCVC() +// +// private lazy var detailCV: UICollectionView = { +// let layout = createLayout() +// layout.configuration.interSectionSpacing = 0 +// let cv = UICollectionView(frame: .zero, collectionViewLayout: layout) +// cv.showsHorizontalScrollIndicator = false +// cv.backgroundColor = .carrotWhite +// return cv +// }() +// +// internal let pageControl: UIPageControl = { +// let pc = UIPageControl() +// pc.numberOfPages = 5 +// pc.pageIndicatorTintColor = .carrotDarkLightGray +// pc.currentPageIndicatorTintColor = .carrotWhite +// return pc +// }() +// +// private lazy var naviHomeButton: UIButton = { +// let bt = UIButton() +// bt.setImage(ImageLiterals.PostDetail.homeIcon, for: .normal) +// bt.addAction(UIAction(handler: { _ in +// self.navigationController?.popViewController(animated: true) +// }), for: .touchUpInside) +// bt.frame = CGRect(x: 0, y: 0, width: 24, height: 24) +// return bt +// }() +// +// private lazy var naviMoreButton: UIButton = { +// let bt = UIButton() +// bt.setImage(ImageLiterals.PostDetail.moreIcon, for: .normal) +// bt.addAction(UIAction(handler: { _ in +// +// }), for: .touchUpInside) +// bt.frame = CGRect(x: 0, y: 0, width: 24, height: 24) +// return bt +// }() +// +// private lazy var bottomView = PostDetailBottomView() +// +// // MARK: - Life Cycles +// +// override func viewDidLoad() { +// super.viewDidLoad() +// +// bind() +// setDelegate() +// setCollectionView() +// +// getPostDetail() +// } +// +// override func viewWillAppear(_ animated: Bool) { +// super.viewWillAppear(animated) +// +// self.tabBarController?.tabBar.isHidden = true +// } +// +// // MARK: - Bind +// +// override func bind() { +// bottomView.likeButtonTapped.throttleOnMain(.seconds(1)) +// .asDriver(onErrorJustReturn: true) +// .drive(onNext: { [weak self] selected in +// self?.bottomView.likeButton.isSelected.toggle() +// self?.changeLikesStatus() +// }) +// .disposed(by: disposeBag) +// } +// +// // MARK: - Custom Methods +// +// private func setDelegate() { +// detailCV.delegate = self +// detailCV.dataSource = self +// } +// +// private func setCollectionView() { +// detailCV.register(PostDetailUserHeader.self, forSupplementaryViewOfKind: PostDetailUserHeader.className, withReuseIdentifier: PostDetailUserHeader.className) +// +// PostImageCVC.register(target: detailCV) +// PostContentCVC.register(target: detailCV) +// } +// +// private func fetchPostDetailData(data: PostDetail) { +// postContentCell.changeSellStatus(status: "\(data.onSale)") +// } +// +// private func getPostDetail() { +// if let postId = postId, +// !fromPostWrite { +// getPostDetail(postId: postId) +// } +// } +// +// // MARK: - UI & Layout +// +// override func setUI() { +// view.backgroundColor = .carrotWhite +// +// let homeBtn = UIBarButtonItem(customView: naviHomeButton) +// let moreBtn = UIBarButtonItem(customView: naviMoreButton) +// self.navigationItem.setLeftBarButton(homeBtn, animated: false) +// self.navigationItem.setRightBarButton(moreBtn, animated: false) +// +// self.navigationController?.isNavigationBarHidden = false +// } +// +// override func setLayout() { +// view.addSubviews(detailCV, pageControl, bottomView) +// +// detailCV.snp.makeConstraints { make in +// make.top.leading.trailing.equalToSuperview() +// make.bottom.equalTo(bottomView.snp.top) +// } +// +// pageControl.snp.makeConstraints { make in +// make.centerX.equalToSuperview() +// make.top.equalToSuperview().inset(UIScreen.main.bounds.width-23) +// } +// +// bottomView.snp.makeConstraints { make in +// make.leading.trailing.bottom.equalToSuperview() +// make.height.equalTo(103) +// } +// } +//} +// +//// MARK: Collection DataSource +// +//extension PostDetailVC: UICollectionViewDataSource { +// +// func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { +// guard let sectionType = SectionType(rawValue: section) else { return 1 } +// +// switch sectionType { +// case .imageSection: +// if let data = postDetailModel { +// return data.image.count +// } else { return 5 } +// +// case .postSection: return 1 +// } +// } +// +// func numberOfSections(in collectionView: UICollectionView) -> Int { +// return 2 +// } +// +// func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { +// if kind == PostDetailUserHeader.className { +// let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: PostDetailUserHeader.className, for: indexPath) +// if let view = view as? PostDetailUserHeader, +// let data = postDetailModel { +// view.setData(data: data) +// } +// return view +// } else { return UICollectionReusableView() } +// } +// +// func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { +// +// guard let sectionType = SectionType(rawValue: indexPath.section) else { return UICollectionViewCell() } +// +// switch sectionType { +// case .imageSection: +// guard let postImageCell = collectionView.dequeueReusableCell(withReuseIdentifier: PostImageCVC.className, for: indexPath) as? PostImageCVC else { return UICollectionViewCell() } +// if let data = postDetailModel { +// postImageCell.setData(postImageURL: data.image[indexPath.row]) +// } else { +// postImageCell.setData(postImage: ImageLiterals.PostDetail.sample[indexPath.row]) +// } +// +// return postImageCell +// case .postSection: +// guard let postContentCell = collectionView.dequeueReusableCell(withReuseIdentifier: PostContentCVC.className, for: indexPath) as? PostContentCVC else { return UICollectionViewCell() } +// postContentCell.delegate = self +// if let data = postDetailModel { +// postContentCell.setData(data: data) +// } +// self.postContentCell = postContentCell +// +// return postContentCell +// } +// } +//} +// +//// MARK: CollectionView Delegate +//extension PostDetailVC: UICollectionViewDelegate { +// func scrollViewDidScroll(_ scrollView: UIScrollView) { +// self.pageControl.snp.remakeConstraints { make in +// make.centerX.equalToSuperview() +// make.top.equalToSuperview().inset(-scrollView.contentOffset.y+UIScreen.main.bounds.width-40) +// } +// } +//} +// +//// MARK: Cell Delegate +//extension PostDetailVC: PostContentDelegate { +// func presentSellStatusActionSheet() { +// let actionSheet = UIAlertController(title: "상태 변경", message: nil, preferredStyle: .actionSheet) +// +// let sellingAction = UIAlertAction(title: "판매중", style: .default) { _ in +// self.postContentCell.changeSellStatus(status: "0") +// self.changeSellStatus(onSale: "0") +// } +// let reservedAction = UIAlertAction(title: "예약중", style: .default) { _ in +// self.postContentCell.changeSellStatus(status: "1") +// self.changeSellStatus(onSale: "1") +// } +// let completedAction = UIAlertAction(title: "거래완료", style: .default) { _ in +// self.postContentCell.changeSellStatus(status: "2") +// self.changeSellStatus(onSale: "2") +// } +// let cancelAction = UIAlertAction(title: "닫기", style: .cancel, handler: nil) +// +// actionSheet.addAction(sellingAction) +// actionSheet.addAction(reservedAction) +// actionSheet.addAction(completedAction) +// actionSheet.addAction(cancelAction) +// +// self.present(actionSheet, animated: true) +// } +//} +// +//// MARK: Network +//extension PostDetailVC { +// func getPostDetail(postId: String) { +// HomeService.shared.getPostDetail(postId: postId) { networkResult in +// switch networkResult { +// case .success(let data): +// if let data = data as? PostDetail { +// self.postDetailModel = data +// self.bottomView.setData(data: data) +// } +// default: +// break +// } +// } +// } +// +// func changeSellStatus(onSale: String) { +// HomeService.shared.changeSellStatus(postId: postId ?? "", onSale: onSale) { networkResult in +// switch networkResult { +// case .success(let message): +// print(message) +// default: +// break +// } +// } +// } +// +// func changeLikesStatus() { +// HomeService.shared.changeLikeStatus(postId: postId ?? "") { networkResult in +// switch networkResult { +// case .success(let message): +// print(message) +// default: +// break +// } +// } +// } +//} diff --git a/HealthFoodMe/Podfile.lock b/HealthFoodMe/Podfile.lock index 7fbbbbf8..29ef6bee 100644 --- a/HealthFoodMe/Podfile.lock +++ b/HealthFoodMe/Podfile.lock @@ -1,20 +1,20 @@ PODS: - Alamofire (5.6.1) - - Firebase/Core (9.1.0): + - Firebase/Core (9.2.0): - Firebase/CoreOnly - - FirebaseAnalytics (~> 9.1.0) - - Firebase/CoreOnly (9.1.0): - - FirebaseCore (= 9.1.0) - - Firebase/Crashlytics (9.1.0): + - FirebaseAnalytics (~> 9.2.0) + - Firebase/CoreOnly (9.2.0): + - FirebaseCore (= 9.2.0) + - Firebase/Crashlytics (9.2.0): - Firebase/CoreOnly - - FirebaseCrashlytics (~> 9.1.0) - - Firebase/RemoteConfig (9.1.0): + - FirebaseCrashlytics (~> 9.2.0) + - Firebase/RemoteConfig (9.2.0): - Firebase/CoreOnly - - FirebaseRemoteConfig (~> 9.1.0) + - FirebaseRemoteConfig (~> 9.2.0) - FirebaseABTesting (9.2.0): - FirebaseCore (~> 9.0) - - FirebaseAnalytics (9.1.0): - - FirebaseAnalytics/AdIdSupport (= 9.1.0) + - FirebaseAnalytics (9.2.0): + - FirebaseAnalytics/AdIdSupport (= 9.2.0) - FirebaseCore (~> 9.0) - FirebaseInstallations (~> 9.0) - GoogleUtilities/AppDelegateSwizzler (~> 7.7) @@ -22,60 +22,60 @@ PODS: - GoogleUtilities/Network (~> 7.7) - "GoogleUtilities/NSData+zlib (~> 7.7)" - nanopb (< 2.30910.0, >= 2.30908.0) - - FirebaseAnalytics/AdIdSupport (9.1.0): + - FirebaseAnalytics/AdIdSupport (9.2.0): - FirebaseCore (~> 9.0) - FirebaseInstallations (~> 9.0) - - GoogleAppMeasurement (= 9.1.0) + - GoogleAppMeasurement (= 9.2.0) - GoogleUtilities/AppDelegateSwizzler (~> 7.7) - GoogleUtilities/MethodSwizzler (~> 7.7) - GoogleUtilities/Network (~> 7.7) - "GoogleUtilities/NSData+zlib (~> 7.7)" - nanopb (< 2.30910.0, >= 2.30908.0) - - FirebaseCore (9.1.0): + - FirebaseCore (9.2.0): - FirebaseCoreDiagnostics (~> 9.0) - FirebaseCoreInternal (~> 9.0) - GoogleUtilities/Environment (~> 7.7) - GoogleUtilities/Logger (~> 7.7) - - FirebaseCoreDiagnostics (9.1.0): + - FirebaseCoreDiagnostics (9.2.0): - GoogleDataTransport (< 10.0.0, >= 9.1.4) - GoogleUtilities/Environment (~> 7.7) - GoogleUtilities/Logger (~> 7.7) - nanopb (< 2.30910.0, >= 2.30908.0) - - FirebaseCoreInternal (9.1.0): + - FirebaseCoreInternal (9.2.0): - "GoogleUtilities/NSData+zlib (~> 7.7)" - - FirebaseCrashlytics (9.1.0): + - FirebaseCrashlytics (9.2.0): - FirebaseCore (~> 9.0) - FirebaseInstallations (~> 9.0) - GoogleDataTransport (< 10.0.0, >= 9.1.4) - GoogleUtilities/Environment (~> 7.7) - nanopb (< 2.30910.0, >= 2.30908.0) - PromisesObjC (~> 2.1) - - FirebaseInstallations (9.1.0): + - FirebaseInstallations (9.2.0): - FirebaseCore (~> 9.0) - GoogleUtilities/Environment (~> 7.7) - GoogleUtilities/UserDefaults (~> 7.7) - PromisesObjC (~> 2.1) - - FirebaseRemoteConfig (9.1.0): + - FirebaseRemoteConfig (9.2.0): - FirebaseABTesting (~> 9.0) - FirebaseCore (~> 9.0) - FirebaseInstallations (~> 9.0) - GoogleUtilities/Environment (~> 7.7) - "GoogleUtilities/NSData+zlib (~> 7.7)" - - GoogleAppMeasurement (9.1.0): - - GoogleAppMeasurement/AdIdSupport (= 9.1.0) + - GoogleAppMeasurement (9.2.0): + - GoogleAppMeasurement/AdIdSupport (= 9.2.0) - GoogleUtilities/AppDelegateSwizzler (~> 7.7) - GoogleUtilities/MethodSwizzler (~> 7.7) - GoogleUtilities/Network (~> 7.7) - "GoogleUtilities/NSData+zlib (~> 7.7)" - nanopb (< 2.30910.0, >= 2.30908.0) - - GoogleAppMeasurement/AdIdSupport (9.1.0): - - GoogleAppMeasurement/WithoutAdIdSupport (= 9.1.0) + - GoogleAppMeasurement/AdIdSupport (9.2.0): + - GoogleAppMeasurement/WithoutAdIdSupport (= 9.2.0) - GoogleUtilities/AppDelegateSwizzler (~> 7.7) - GoogleUtilities/MethodSwizzler (~> 7.7) - GoogleUtilities/Network (~> 7.7) - "GoogleUtilities/NSData+zlib (~> 7.7)" - nanopb (< 2.30910.0, >= 2.30908.0) - - GoogleAppMeasurement/WithoutAdIdSupport (9.1.0): + - GoogleAppMeasurement/WithoutAdIdSupport (9.2.0): - GoogleUtilities/AppDelegateSwizzler (~> 7.7) - GoogleUtilities/MethodSwizzler (~> 7.7) - GoogleUtilities/Network (~> 7.7) @@ -104,17 +104,17 @@ PODS: - GoogleUtilities/Logger - GoogleUtilities/UserDefaults (7.7.0): - GoogleUtilities/Logger - - KakaoSDKAuth (2.10.1): - - KakaoSDKCommon (= 2.10.1) - - KakaoSDKCommon (2.10.1): - - KakaoSDKCommon/Common (= 2.10.1) - - KakaoSDKCommon/Network (= 2.10.1) - - KakaoSDKCommon/Common (2.10.1) - - KakaoSDKCommon/Network (2.10.1): + - KakaoSDKAuth (2.11.0): + - KakaoSDKCommon (= 2.11.0) + - KakaoSDKCommon (2.11.0): + - KakaoSDKCommon/Common (= 2.11.0) + - KakaoSDKCommon/Network (= 2.11.0) + - KakaoSDKCommon/Common (2.11.0) + - KakaoSDKCommon/Network (2.11.0): - Alamofire (~> 5.1) - - KakaoSDKCommon/Common (= 2.10.1) - - KakaoSDKUser (2.10.1): - - KakaoSDKAuth (= 2.10.1) + - KakaoSDKCommon/Common (= 2.11.0) + - KakaoSDKUser (2.11.0): + - KakaoSDKAuth (= 2.11.0) - Kingfisher (7.2.4) - nanopb (2.30909.0): - nanopb/decode (= 2.30909.0) @@ -122,7 +122,7 @@ PODS: - nanopb/decode (2.30909.0) - nanopb/encode (2.30909.0) - NMapsMap (3.15.0) - - PromisesObjC (2.1.0) + - PromisesObjC (2.1.1) - Realm (10.28.2): - Realm/Headers (= 10.28.2) - Realm/Headers (10.28.2) @@ -184,25 +184,25 @@ SPEC REPOS: SPEC CHECKSUMS: Alamofire: 87bd8c952f9a4454320fce00d9cc3de57bcadaf5 - Firebase: 91c243d75573ac6e7c9735ec859b72bffb61347d + Firebase: 4ba896cb8e5105d4b9e247e1c1b6222b548df55a FirebaseABTesting: cd1ec762a0078b46a7ce91dfe5b7b8991c2dff8f - FirebaseAnalytics: bf11064790ac96804df1df9ddc0ae45af950d9fc - FirebaseCore: b7bfc258e996eada23b3666bd6b9a22ca092acb8 - FirebaseCoreDiagnostics: 2dabba3412b23b524823325739f45e520f67d1e7 - FirebaseCoreInternal: f3c838ae0b41cd840bbf34f90debfede78d352e5 - FirebaseCrashlytics: 8e21736dcf15d814b79229eb7e79ba3a5eec5f30 - FirebaseInstallations: a91c74276b544524ce144c8315d8cdbce2dbe30b - FirebaseRemoteConfig: ebd0eb74b9a0593ab2a3f0788a5be5595b46a05c - GoogleAppMeasurement: 8ecc717f2abe3f9ee95a5d38db08827852894acc + FirebaseAnalytics: af5a03a8dff7648c7b8486f6a78b1368e0268dd3 + FirebaseCore: 0e27f2a15d8f7b7ef11e7d93e23b1cbab55d748c + FirebaseCoreDiagnostics: ad3f6c68b7c5b63b7cf15b0785d7137f05f32268 + FirebaseCoreInternal: cb966328b6985dbd6f535e1461291063e1c4a00f + FirebaseCrashlytics: 9fff819edb2bfc9d3eff612225b207d41945a935 + FirebaseInstallations: 21186f0ca7849f90f4a3219fa31a5eca2e30f113 + FirebaseRemoteConfig: 16e29297f0dd0c7d2415c4506d614fe0b54875d1 + GoogleAppMeasurement: 7a33224321f975d58c166657260526775d9c6b1a GoogleDataTransport: 5fffe35792f8b96ec8d6775f5eccd83c998d5a3b GoogleUtilities: e0913149f6b0625b553d70dae12b49fc62914fd1 - KakaoSDKAuth: b4fec62192c2ac8a9375847f666c0932e38afeb5 - KakaoSDKCommon: 4989e3bae5f4884903bc1df7134e13d0e903d587 - KakaoSDKUser: 5c5fd4b5864e8b5ac9587fdbb473daf2fa675abf + KakaoSDKAuth: b9470887e42b869725b391f4af34c4aaec42ea46 + KakaoSDKCommon: 0f59f2c1aead6012d92758e8ca46b63ea11c408b + KakaoSDKUser: 5dbefe494c50dfdc87e4072710e503d39b41a609 Kingfisher: 2457be2121734e69e54a2312ecc0150eb9ae70b3 nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431 NMapsMap: f151761c088d6516064c59da03ab6503769486e6 - PromisesObjC: 99b6f43f9e1044bd87a95a60beff28c2c44ddb72 + PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb Realm: e617c54ad0f566b3d0f6a2abae7010de05f252ac RealmSwift: 8a516a8759d80d52ebcec1ff1076f5f5159f98b2 RxCocoa: 94f817b71c07517321eb4f9ad299112ca8af743b