Skip to content

Commit

Permalink
[Merge] #195 - conflict 해결 및 머지
Browse files Browse the repository at this point in the history
  • Loading branch information
jeongdung-eo committed Jan 24, 2024
2 parents 6d4feaa + e9bb3f9 commit 6296ed4
Show file tree
Hide file tree
Showing 72 changed files with 2,050 additions and 739 deletions.
48 changes: 42 additions & 6 deletions iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

132 changes: 101 additions & 31 deletions iOS-NOTTODO/iOS-NOTTODO/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,43 +28,20 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
KakaoSDK.initSDK(appKey: Bundle.main.kakaoAPIKey)
FirebaseApp.configure()

if KeychainUtil.getAccessToken() != "" {
self.skipAuthView()
print("토큰 유효")
} else {
// self.showAuthView()
// 토큰이 유효하지 않을 경우 일단은 온보딩->로그인->홈 이렇게만 가도록
}
checkForUpdate()

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

// FCM 다시 사용 설정
Messaging.messaging().isAutoInitEnabled = true

// 푸시 알림 권한 설정 및 푸시 알림에 앱 등록
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(options: authOptions, completionHandler: { _, _ in })


// device token 요청.
application.registerForRemoteNotifications()

return true
}

func showAuthView() {
DispatchQueue.main.async {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let window = windowScene.windows.first {
let authViewController = AuthViewController()
let navigationController = UINavigationController(rootViewController: authViewController)
window.rootViewController = navigationController
window.makeKeyAndVisible()
}
}
}

func skipAuthView() {
// 홈 화면으로 바로 이동
DispatchQueue.main.async {
Expand Down Expand Up @@ -103,22 +80,115 @@ func application(_ application: UIApplication, didDiscardSceneSessions sceneSess

extension AppDelegate: MessagingDelegate {
/// 현재 등록 토큰 가져오기.
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
if let fcmToken = fcmToken {
KeychainUtil.setFcmToken(fcmToken)
}
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
if let fcmToken = fcmToken {
KeychainUtil.setFcmToken(fcmToken)
}
}
}

extension AppDelegate: UNUserNotificationCenterDelegate {

/// foreground에서 러닝 중에 앱에 도착하는 알림을 다루는 메서드
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.list, .sound, .badge, .banner])
}

/// 도착한 notification에 대한 유저의 반응을 다루는 메서드
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
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)
}
}
}
}
27 changes: 20 additions & 7 deletions iOS-NOTTODO/iOS-NOTTODO/Application/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import UIKit
import KakaoSDKAuth

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?
static var shared: SceneDelegate? { UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate }

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.overrideUserInterfaceStyle = UIUserInterfaceStyle.light

let rootViewController = ValueOnboardingViewController()
let navigationController = UINavigationController(rootViewController: rootViewController)
navigationController.isNavigationBarHidden = true
Expand All @@ -33,19 +34,31 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
}
}
}

func sceneDidDisconnect(_ scene: UIScene) {
}

func sceneDidBecomeActive(_ scene: UIScene) {
}

func sceneWillResignActive(_ scene: UIScene) {
}

func sceneWillEnterForeground(_ scene: UIScene) {
}

func sceneDidEnterBackground(_ scene: UIScene) {
}
}

extension SceneDelegate {

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

let rootViewController = viewController
let navigationController = UINavigationController(rootViewController: rootViewController)
navigationController.isNavigationBarHidden = true
window.rootViewController = navigationController
}
}
1 change: 1 addition & 0 deletions iOS-NOTTODO/iOS-NOTTODO/Global/Enum/DefaultKeys.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ struct DefaultKeys {
static let socialToken = "socialToken"
static let accessToken = "accessToken"
static let fcmToken = "fcmToken"
static let isSelected = "isSelected"
}
4 changes: 4 additions & 0 deletions iOS-NOTTODO/iOS-NOTTODO/Global/Enum/KeychainUtil.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ public final class KeychainUtil {
UserDefaults.standard.string(forKey: DefaultKeys.appleEmail) ?? "연동된 이메일 정보가 없습니다"
}

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

static func removeUserInfo() {
if UserDefaults.standard.bool(forKey: DefaultKeys.isAppleLogin) {
UserDefaults.standard.removeObject(forKey: DefaultKeys.appleName)
Expand Down
12 changes: 12 additions & 0 deletions iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Bundle+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,16 @@ extension Bundle {
}
return value
}

var appleId: String {
guard let filePath = Bundle.main.path(forResource: "API_KEY", ofType: "plist") else {
fatalError("Could't find file 'API_KEY.plist'.")
}
let plist = NSDictionary(contentsOfFile: filePath)

guard let value = plist?.object(forKey: "APPLE_ID") as? String else {
fatalError("Couldn't find key 'APPLE_ID' in 'API_KEY.plist'.")
}
return value
}
}
29 changes: 29 additions & 0 deletions iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/CGSize+.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// CGSize+.swift
// iOS-NOTTODO
//
// Created by 강윤서 on 11/23/23.
//

import UIKit

extension CGSize {

func getDeviceWidth() -> CGFloat {
return UIScreen.main.bounds.width
}

func getDeviceHeight() -> CGFloat {
return UIScreen.main.bounds.height
}

/// 아이폰 13 미니(width 375)를 기준으로 레이아웃을 잡고, 기기의 width 사이즈를 곱해 대응 값을 구할 때 사용
func convertByWidthRatio(_ convert: CGFloat) -> CGFloat {
return (convert / 375) * getDeviceWidth()
}

/// 아이폰 13 미니(height 812)를 기준으로 레이아웃을 잡고, 기기의 height 사이즈를 곱해 대응 값을 구할 때 사용
func convertByHeightRatio(_ convert: CGFloat) -> CGFloat {
return (convert / 812) * getDeviceHeight()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,8 @@ extension UIColor {
static let green2 = UIColor(named: "green2")
static let systemBlack = UIColor(named: "systemBlack")
static let kakaoYellow = UIColor(named: "yellow")
static let notiBlack = UIColor(named: "notiBlack")
static let notiGreen = UIColor(named: "notiGreen")
static let notiBlue = UIColor(named: "notiBlue")
static let notiBg = UIColor(named: "notiBg")
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ extension UIImage {
static var calendarRight: UIImage { UIImage(named: "btn_calendar_right")! }
static var checkboxFill: UIImage { UIImage(named: "btn_checkbox_active")! }
static var checkbox: UIImage { UIImage(named: "btn_checkbox_inactive")! }
static var deprecatedCheckBoxFill: UIImage { UIImage(named: "btn_common_active")! }
static var deprecatedCheckBox: UIImage { UIImage(named: "btn_common_inactive")! }

// home

Expand Down Expand Up @@ -56,6 +58,9 @@ extension UIImage {
static var icSNS: UIImage { UIImage(named: "ic_snsmessage")! }
static var icTrashbin: UIImage { UIImage(named: "ic_trashbin")! }
static var icToastError: UIImage { UIImage(named: "ic_toast_error")! }
static var icBell: UIImage { UIImage(named: "ic_bell")! }
static var icCircle: UIImage { UIImage(named: "acceptCircle")! }
static var icStarbucks: UIImage { UIImage(named: "ic_starbucks")! }

// image

Expand Down Expand Up @@ -110,4 +115,5 @@ extension UIImage {

static var quit1: UIImage { UIImage(named: "img_quit1")! }
static var quit2: UIImage { UIImage(named: "img_quit2")! }
static var notificationDialog: UIImage { UIImage(named: "NotificationDialog")! }
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,26 @@ extension UIViewController {
$0.height.equalTo(61)
}

let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(deleteToast(_:)))
toastView.addGestureRecognizer(tapGestureRecognizer)
toastView.isUserInteractionEnabled = true

UIView.animate(withDuration: 0.4, delay: 0.0, options: .curveEaseIn) {
toastView.alpha = 1.0
} completion: { _ in
UIView.animate(withDuration: 0.4, delay: 1.0, options: .curveEaseOut) {
UIView.animate(withDuration: 0.4, delay: 1.5, options: .curveEaseOut) {
toastView.alpha = 0.0
} completion: { _ in
toastView.removeFromSuperview()
}
}
}

@objc
private func deleteToast(_ sender: UITapGestureRecognizer) {
sender.view?.removeFromSuperview()
}

/// html을 string으로 변환하는 메소드
func htmlToString(_ targetString: String) -> NSAttributedString? {
let text = targetString
Expand Down
25 changes: 25 additions & 0 deletions iOS-NOTTODO/iOS-NOTTODO/Global/Literals/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,31 @@ struct I18N {
static let delete = "삭제하기"
static let deleteModalTitle = "삭제하시겠습니까?"
static let deleteModalSubtitle = "한 번 삭제하면 되돌릴 수 없어요."
static let update = "업데이트"
static let updateAlert = """
최신 업데이트가 있습니다.
업데이트하시겠습니까?
"""
static let later = "나중에"
static let notiDialogTitle = """
알림을 허용하면
낫투두가 더 잘 도울 수 있어요!
"""
static let notiAllowTitle = """
'낫투두'에서 알림을
보내고자 합니다.
"""
static let notiAllowSubTitle = """
알림 기능이 꺼져있으면
알람이 울릴 때까지 확인하기 어려워요
"""
static let notAllow = "허용 안 함"
static let allow = "허용"
static let notiDialogButton = "네, 알겠어요 :)"

static let formButton = "이정도야 쉽지!"
static let deprecatedTitle = "더 이상 보지 않기"
static let close = "닫기"

/// home
static let subText = "*달성 가능한 계획을 위해 다가올 일주일만 선택할 수 있어요"
Expand Down
Loading

0 comments on commit 6296ed4

Please sign in to comment.