Skip to content

Commit

Permalink
[Merger] develop into feature/#221
Browse files Browse the repository at this point in the history
  • Loading branch information
yungu0010 committed Jan 29, 2024
2 parents 008b016 + abe8491 commit 6ec198c
Show file tree
Hide file tree
Showing 23 changed files with 689 additions and 375 deletions.
68 changes: 60 additions & 8 deletions iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

112 changes: 2 additions & 110 deletions iOS-NOTTODO/iOS-NOTTODO/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Amplitude

import Firebase
import FirebaseMessaging
import FirebaseRemoteConfig

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
Expand All @@ -27,9 +28,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
Amplitude.instance().initializeApiKey(Bundle.main.amplitudeAPIKey)
KakaoSDK.initSDK(appKey: Bundle.main.kakaoAPIKey)
FirebaseApp.configure()

checkForUpdate()


// 메시지 대리자 설정
Messaging.messaging().delegate = self

Expand All @@ -42,20 +41,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
return true
}

func skipAuthView() {
// 홈 화면으로 바로 이동
DispatchQueue.main.async {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let window = windowScene.windows.first {
let tabBarController = TabBarController()
let navigationController = UINavigationController(rootViewController: tabBarController)
navigationController.isNavigationBarHidden = true
window.rootViewController = navigationController
window.makeKeyAndVisible()
}
}
}

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken

Expand Down Expand Up @@ -99,96 +84,3 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
completionHandler()
}
}

extension AppDelegate {
func checkForUpdate() {
// 앱스토어 버전
guard let appstoreVersion = getAppstoreVersion() else { return }

// 현재 설치된 앱의 버전
guard let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else { return }

if compareVersion(userVersion: appVersion, appstoreVersion: appstoreVersion) {
DispatchQueue.main.async {
self.showUpdateAlert()
}
} else {
if KeychainUtil.getAccessToken() != "" {
self.skipAuthView()
print("토큰 유효")
}
}
}

/// 버전 비교하는 메서드
func compareVersion(userVersion: String, appstoreVersion: String) -> Bool {
let userMajor = userVersion.split(separator: ".").map {Int($0)!}[0]
let appstoreMajor = appstoreVersion.split(separator: ".").map {Int($0)!}[0]

if userMajor < appstoreMajor {
return true
}

let userMinor = userVersion.split(separator: ".").map {Int($0)!}[1]
let appstoreMinor = appstoreVersion.split(separator: ".").map {Int($0)!}[1]

if userMinor < appstoreMinor {
return true
}

let userPatch = userVersion.split(separator: ".").map {Int($0)!}[2]
let appstorePatch = appstoreVersion.split(separator: ".").map {Int($0)!}[2]

if userPatch < appstorePatch {
return true
}

return false
}

/// 앱스토어에 배포된 버전 가져오는 메서드
func getAppstoreVersion() -> String? {
let appleID = Bundle.main.appleId
guard let url = URL(string: "https://itunes.apple.com/lookup?id=\(appleID)"),
let data = try? Data(contentsOf: url),
let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any],
let results = json["results"] as? [[String: Any]],
let appStoreVersion = results[0]["version"] as? String else {
return nil
}
return appStoreVersion
}

/// 선택 업데이트 경고창
func showUpdateAlert() {
let alertController = UIAlertController(
title: I18N.update,
message: I18N.updateAlert,
preferredStyle: .alert
)

let updateAction = UIAlertAction(title: I18N.update, style: .default) { _ in
// App Store로 이동
if let appStoreURL = URL(string: "https://itunes.apple.com/app/\(Bundle.main.appleId)") {
UIApplication.shared.open(appStoreURL, options: [:], completionHandler: {_ in
if KeychainUtil.getAccessToken() != "" {
self.skipAuthView()
print("토큰 유효")
}
})
}
}

let cancelAction = UIAlertAction(title: I18N.later, style: .default)

alertController.addAction(updateAction)
alertController.addAction(cancelAction)

if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
if let keyWindow = windowScene.windows.first,
let rootViewController = keyWindow.rootViewController {
rootViewController.present(alertController, animated: true, completion: nil)
}
}
}
}
3 changes: 1 addition & 2 deletions iOS-NOTTODO/iOS-NOTTODO/Application/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
let window = UIWindow(windowScene: windowScene)
window.overrideUserInterfaceStyle = UIUserInterfaceStyle.light

let rootViewController = ValueOnboardingViewController()
let rootViewController = UpdateCheckViewController()
let navigationController = UINavigationController(rootViewController: rootViewController)
navigationController.isNavigationBarHidden = true
window.rootViewController = navigationController
Expand Down Expand Up @@ -52,7 +52,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
}

extension SceneDelegate {

func changeRootViewControllerTo(_ viewController: UIViewController) {
guard let window = window else { return }

Expand Down
7 changes: 6 additions & 1 deletion iOS-NOTTODO/iOS-NOTTODO/Global/Enum/AnalyticsEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,25 @@ enum AnalyticsEvent {
case viewSignIn
case clickSignIn(provider: String)
case completeSignIn(provider: String)
case clickAdModalCta
case clickAdModalClose(again: String)

var name: String {
switch self {
case .viewSignIn: return "view_signin"
case .clickSignIn: return "click_signin"
case .completeSignIn: return "complete_signin"
case .clickAdModalCta: return "click_ad_modal_cta"
case .clickAdModalClose: return "click_ad_modal_close"
}
}

var parameters: [String: Any]? {
switch self {
case .viewSignIn: return nil
case .viewSignIn, .clickAdModalCta: return nil
case .clickSignIn(provider: let provider ): return ["provider": provider]
case .completeSignIn(provider: let provider): return ["provider": provider]
case .clickAdModalClose(again: let again): return ["again": again]
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion iOS-NOTTODO/iOS-NOTTODO/Global/Enum/DefaultKeys.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ struct DefaultKeys {
static let socialToken = "socialToken"
static let accessToken = "accessToken"
static let fcmToken = "fcmToken"
static let isSelected = "isSelected"
static let isDeprecatedBtnClicked = "isDeprecatedBtnClicked"
}
6 changes: 3 additions & 3 deletions iOS-NOTTODO/iOS-NOTTODO/Global/Enum/KeychainUtil.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ public final class KeychainUtil {
UserDefaults.standard.string(forKey: DefaultKeys.appleEmail) ?? "연동된 이메일 정보가 없습니다"
}

static func isSelected() -> Bool {
UserDefaults.standard.bool(forKey: DefaultKeys.isSelected)
static func isDeprecatedBtnClicked() -> Bool {
UserDefaults.standard.bool(forKey: DefaultKeys.isDeprecatedBtnClicked)
}

static func removeUserInfo() {
if UserDefaults.standard.bool(forKey: DefaultKeys.isAppleLogin) {
UserDefaults.standard.removeObject(forKey: DefaultKeys.appleName)
Expand Down
10 changes: 4 additions & 6 deletions iOS-NOTTODO/iOS-NOTTODO/Global/Enum/MyInfoURL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,23 @@ import Foundation
import SafariServices

enum MyInfoURL {
case guid, quesition, notice, contact, service, personalInfo, googleForm, opensource
case guid, faq, notice, question, service, personalInfo, googleForm
var url: String {
switch self {
case .guid:
return "https://teamnottodo.notion.site/f35a7f2d6d5c4b33b4d0949f6077e6cd"
case .quesition:
case .faq:
return "https://teamnottodo.notion.site/a6ef7036bde24e289e576ace099f39dc"
case .notice:
return "https://teamnottodo.notion.site/a5dbb310ec1d43baae02b7e9bf0b3411"
case .contact:
case .question:
return "http://pf.kakao.com/_fUIQxj/chat"
case .service:
return "https://teamnottodo.notion.site/81594da775614d23900cdb2475eadb73?pvs=4"
case .personalInfo:
return "https://teamnottodo.notion.site/5af34df7da3649fc941312c5f533c1eb"
case .googleForm:
return "https://forms.gle/rWFJrpVv1RqHwTg28"
case .opensource:
return "https://teamnottodo.notion.site/a391274a627643f6a4d1f2412d4cf170?pvs=4"
return "https://forms.gle/gwBJ4hL4bCTjXRTP6"
}
}

Expand Down
3 changes: 3 additions & 0 deletions iOS-NOTTODO/iOS-NOTTODO/Global/Literals/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ struct I18N {
최신 업데이트가 있습니다.
업데이트하시겠습니까?
"""
static func forceUpdateAlert(newVersion: String) -> String {
return "낫투두의 새로운 버전이 있습니다. \(newVersion)버전 으로 업데이트 해주세요."
}
static let later = "나중에"
static let notiDialogTitle = """
알림을 허용하면
Expand Down
47 changes: 47 additions & 0 deletions iOS-NOTTODO/iOS-NOTTODO/Network/External/FirebaseUtil.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// FirebaseUtil.swift
// iOS-NOTTODO
//
// Created by 김혜수 on 1/23/24.
//

import Foundation

import FirebaseRemoteConfig

final class FirebaseUtil {

static let shared = FirebaseUtil()

private let config = RemoteConfig.remoteConfig()

enum RemoteConfigType {
case minimumVersion
}

init() {
self.setRemoteConfigSetting()
}

func fetchRemoteConfig(type: RemoteConfigType) async -> String? {
return await withCheckedContinuation { continuation in
config.fetch { [weak self] status, _ in
if status == .success {
self?.config.activate()
guard let version = self?.config["minimum_version"].stringValue, !version.isEmpty else {
continuation.resume(returning: nil)
return
}
continuation.resume(returning: version)
}
}
}
}

private func setRemoteConfigSetting() {
let setting = RemoteConfigSettings()
setting.minimumFetchInterval = 0
setting.fetchTimeout = 10
config.configSettings = setting
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@

import UIKit

class DetailAchievementCollectionViewCell: UICollectionViewCell {
import SnapKit
import Then

final class DetailAchievementCollectionViewCell: UICollectionViewCell {

// MARK: - Properties

Expand All @@ -16,15 +19,14 @@ class DetailAchievementCollectionViewCell: UICollectionViewCell {
// MARK: - UI Components

let tagLabel = PaddingLabel(padding: UIEdgeInsets(top: 4, left: 12, bottom: 4, right: 12))
private let horizontalStackView = UIStackView()
private let emptyView = UIView()
let titleLabel = UILabel()
private let checkImage = UIImageView()

// MARK: - Life Cycle

override init(frame: CGRect) {
super.init(frame: frame)

setUI()
setLayout()
}
Expand All @@ -37,55 +39,57 @@ class DetailAchievementCollectionViewCell: UICollectionViewCell {
// MARK: - Methods

extension DetailAchievementCollectionViewCell {

private func setUI() {

contentView.backgroundColor = .clear

tagLabel.do {
$0.layer.backgroundColor = UIColor.bg?.cgColor
$0.font = .Pretendard(.medium, size: 14)
$0.textColor = .gray1
$0.layer.cornerRadius = 10
$0.layer.cornerRadius = 25/2
}

horizontalStackView.do {
$0.addArrangedSubviews(titleLabel, emptyView, checkImage)
$0.axis = .horizontal
}


titleLabel.do {
$0.font = .Pretendard(.semiBold, size: 16)
$0.textColor = .gray2
$0.numberOfLines = 0
$0.numberOfLines = 1
$0.textAlignment = .left
}

checkImage.do {
$0.image = .icChecked
}
}

private func setLayout() {
addSubviews(tagLabel, horizontalStackView)
contentView.addSubviews(tagLabel, titleLabel, checkImage)

tagLabel.snp.makeConstraints {
$0.top.equalToSuperview().offset(22)
$0.leading.equalToSuperview().offset(29)
$0.leading.equalToSuperview().inset(28)
}
horizontalStackView.snp.makeConstraints {

titleLabel.snp.makeConstraints {
$0.top.equalTo(tagLabel.snp.bottom).offset(7)
$0.leading.equalToSuperview().inset(28)
$0.trailing.equalToSuperview()
$0.bottom.equalToSuperview().inset(24)
$0.trailing.equalToSuperview().inset(50)
}

checkImage.snp.makeConstraints {
$0.trailing.equalToSuperview()
$0.centerY.equalTo(titleLabel.snp.centerY)
$0.size.equalTo(21)
$0.trailing.equalToSuperview().inset(28)
$0.bottom.equalToSuperview().inset(24)
}
}

func configure(model: DailyMissionResponseDTO) {
tagLabel.text = model.title
titleLabel.text = model.situationName
tagLabel.text = model.situationName
titleLabel.text = model.title
titleLabel.lineBreakMode = .byTruncatingTail

switch model.completionStatus {
case .CHECKED: checkImage.isHidden = false
case .UNCHECKED: checkImage.isHidden = true
Expand Down
Loading

0 comments on commit 6ec198c

Please sign in to comment.