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
24 changes: 20 additions & 4 deletions Wable-iOS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@
DDCCA3932D738CD500658122 /* UserSessionRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCCA3922D738CD100658122 /* UserSessionRepository.swift */; };
DDCCA3952D73928900658122 /* UserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCCA3942D73928400658122 /* UserSession.swift */; };
DDCCA3972D73988000658122 /* UserSessionRepositoryImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCCA3962D73987600658122 /* UserSessionRepositoryImpl.swift */; };
DDCD66E12D7C8A4A00EF4C28 /* jinung.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCD66E02D7C8A4900EF4C28 /* jinung.swift */; };
DDCD66E32D7DB11D00EF4C28 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCD66E22D7DB11500EF4C28 /* TabBarController.swift */; };
DDCD66E52D7DC0EB00EF4C28 /* NavigationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCD66E42D7DC0DB00EF4C28 /* NavigationView.swift */; };
DDCD66EA2D7DD72F00EF4C28 /* LottieType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCD66E92D7DD72800EF4C28 /* LottieType.swift */; };
Expand Down Expand Up @@ -184,6 +183,10 @@
DDF2CC9C2D71FECB000F1919 /* FirebaseCore in Frameworks */ = {isa = PBXBuildFile; productRef = DDF2CC9B2D71FECB000F1919 /* FirebaseCore */; };
DDF2CC9E2D71FECB000F1919 /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = DDF2CC9D2D71FECB000F1919 /* FirebaseMessaging */; };
DDF2CCA12D71FF27000F1919 /* AmplitudeSwift in Frameworks */ = {isa = PBXBuildFile; productRef = DDF2CCA02D71FF27000F1919 /* AmplitudeSwift */; };
DE54B03C2D82C43F009A7C34 /* PhotoDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE54B03B2D82C43F009A7C34 /* PhotoDetailViewController.swift */; };
DE54B03E2D82CD82009A7C34 /* NotFoundViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE54B03D2D82CD82009A7C34 /* NotFoundViewController.swift */; };
DE54B0402D832E78009A7C34 /* LoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE54B03F2D832E78009A7C34 /* LoadingViewController.swift */; };
DE54B0422D833B0B009A7C34 /* WableActionSheetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE54B0412D833B0B009A7C34 /* WableActionSheetViewController.swift */; };
DE67A9EB2D7211070021BDE1 /* Like.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE67A9EA2D7211070021BDE1 /* Like.swift */; };
DE67A9EF2D7213D90021BDE1 /* Opacity.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE67A9EE2D7213D90021BDE1 /* Opacity.swift */; };
DE7C530C2D761DCA00076E5D /* ViewModelType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE7C530B2D761DCA00076E5D /* ViewModelType.swift */; };
Expand All @@ -193,6 +196,7 @@
DE7C53142D761EE500076E5D /* UIView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE7C53132D761EE500076E5D /* UIView+.swift */; };
DE7C53182D761F3A00076E5D /* ReuseIdentifiable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE7C53172D761F3A00076E5D /* ReuseIdentifiable.swift */; };
DE7C531A2D76202B00076E5D /* UITextField+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE7C53192D76202B00076E5D /* UITextField+.swift */; };
DE8FF1912D8155DD00C41880 /* WableButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE8FF1902D8155DD00C41880 /* WableButton.swift */; };
DEDC29142D7208A00073D512 /* GameStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEDC29132D7208A00073D512 /* GameStatus.swift */; };
DEDC29162D72099C0073D512 /* InfoNotificationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEDC29152D72099C0073D512 /* InfoNotificationType.swift */; };
DEDC29182D720D030073D512 /* PostStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEDC29172D720D030073D512 /* PostStatus.swift */; };
Expand Down Expand Up @@ -339,7 +343,6 @@
DDCCA3922D738CD100658122 /* UserSessionRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionRepository.swift; sourceTree = "<group>"; };
DDCCA3942D73928400658122 /* UserSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSession.swift; sourceTree = "<group>"; };
DDCCA3962D73987600658122 /* UserSessionRepositoryImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionRepositoryImpl.swift; sourceTree = "<group>"; };
DDCD66E02D7C8A4900EF4C28 /* jinung.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = jinung.swift; sourceTree = "<group>"; };
DDCD66E22D7DB11500EF4C28 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = "<group>"; };
DDCD66E42D7DC0DB00EF4C28 /* NavigationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationView.swift; sourceTree = "<group>"; };
DDCD66E92D7DD72800EF4C28 /* LottieType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LottieType.swift; sourceTree = "<group>"; };
Expand All @@ -366,6 +369,10 @@
DDED59852D7965DB00A0BEF1 /* OverviewUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverviewUseCase.swift; sourceTree = "<group>"; };
DDED59872D7965EC00A0BEF1 /* NotificationUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationUseCase.swift; sourceTree = "<group>"; };
DDED59892D7965F400A0BEF1 /* ProfileUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileUseCase.swift; sourceTree = "<group>"; };
DE54B03B2D82C43F009A7C34 /* PhotoDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoDetailViewController.swift; sourceTree = "<group>"; };
DE54B03D2D82CD82009A7C34 /* NotFoundViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotFoundViewController.swift; sourceTree = "<group>"; };
DE54B03F2D832E78009A7C34 /* LoadingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingViewController.swift; sourceTree = "<group>"; };
DE54B0412D833B0B009A7C34 /* WableActionSheetViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WableActionSheetViewController.swift; sourceTree = "<group>"; };
DE67A9EA2D7211070021BDE1 /* Like.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Like.swift; sourceTree = "<group>"; };
DE67A9EE2D7213D90021BDE1 /* Opacity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Opacity.swift; sourceTree = "<group>"; };
DE7C530B2D761DCA00076E5D /* ViewModelType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModelType.swift; sourceTree = "<group>"; };
Expand All @@ -375,6 +382,7 @@
DE7C53132D761EE500076E5D /* UIView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+.swift"; sourceTree = "<group>"; };
DE7C53172D761F3A00076E5D /* ReuseIdentifiable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReuseIdentifiable.swift; sourceTree = "<group>"; };
DE7C53192D76202B00076E5D /* UITextField+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextField+.swift"; sourceTree = "<group>"; };
DE8FF1902D8155DD00C41880 /* WableButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WableButton.swift; sourceTree = "<group>"; };
DEDC29112D7207610073D512 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/LaunchScreen.strings; sourceTree = "<group>"; };
DEDC29132D7208A00073D512 /* GameStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameStatus.swift; sourceTree = "<group>"; };
DEDC29152D72099C0073D512 /* InfoNotificationType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoNotificationType.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -952,7 +960,11 @@
DDCD66DC2D7C8A2500EF4C28 /* Jinung */ = {
isa = PBXGroup;
children = (
DDCD66E02D7C8A4900EF4C28 /* jinung.swift */,
DE8FF1902D8155DD00C41880 /* WableButton.swift */,
DE54B03B2D82C43F009A7C34 /* PhotoDetailViewController.swift */,
DE54B03D2D82CD82009A7C34 /* NotFoundViewController.swift */,
DE54B03F2D832E78009A7C34 /* LoadingViewController.swift */,
DE54B0412D833B0B009A7C34 /* WableActionSheetViewController.swift */,
);
path = Jinung;
sourceTree = "<group>";
Expand Down Expand Up @@ -1239,6 +1251,7 @@
DDED597E2D79578C00A0BEF1 /* AuthProvider.swift in Sources */,
DD29680A2D6DACF700143851 /* User.swift in Sources */,
DD29680B2D6DACF700143851 /* UserProfile.swift in Sources */,
DE54B03E2D82CD82009A7C34 /* NotFoundViewController.swift in Sources */,
DD29680C2D6DACF700143851 /* LCKTeamRank.swift in Sources */,
DD29680D2D6DACF700143851 /* Content.swift in Sources */,
DD29680E2D6DACF700143851 /* Token.swift in Sources */,
Expand All @@ -1255,6 +1268,7 @@
DD2968522D6DAD4400143851 /* DTO.swift in Sources */,
DDED594C2D784EB100A0BEF1 /* KeychainStorage.swift in Sources */,
DDED594D2D784EB100A0BEF1 /* UserDefaultsStorage.swift in Sources */,
DE54B0422D833B0B009A7C34 /* WableActionSheetViewController.swift in Sources */,
DDED595C2D78C3B700A0BEF1 /* AppleAuthProvider.swift in Sources */,
DDCD67052D7E272200EF4C28 /* ToastView.swift in Sources */,
DD2968532D6DAD4400143851 /* BaseResponse.swift in Sources */,
Expand Down Expand Up @@ -1294,7 +1308,6 @@
DDED59532D785B9700A0BEF1 /* TokenError.swift in Sources */,
DD29686F2D6DAD5F00143851 /* MoyaLoggingPlugin.swift in Sources */,
DD2968702D6DAD5F00143851 /* TokenStorage.swift in Sources */,
DDCD66E12D7C8A4A00EF4C28 /* jinung.swift in Sources */,
DD2968732D6DAD5F00143851 /* APIProvider.swift in Sources */,
DD2968742D6DAD5F00143851 /* NetworkError.swift in Sources */,
DD2968432D6DAD2F00143851 /* FetchGameSchedules.swift in Sources */,
Expand Down Expand Up @@ -1326,6 +1339,7 @@
DD29687C2D6DB27F00143851 /* OAuthenticator.swift in Sources */,
DDED59512D7850E600A0BEF1 /* LocalError.swift in Sources */,
DD2968602D6DAD5500143851 /* GhostTargetType.swift in Sources */,
DE54B03C2D82C43F009A7C34 /* PhotoDetailViewController.swift in Sources */,
DD2968612D6DAD5500143851 /* ViewitTargetType.swift in Sources */,
DD2968622D6DAD5500143851 /* CommentLikedTargetType.swift in Sources */,
DD2968632D6DAD5500143851 /* ContentTargetType.swift in Sources */,
Expand All @@ -1350,6 +1364,7 @@
DDCCA3952D73928900658122 /* UserSession.swift in Sources */,
DD2967FB2D6DAC4800143851 /* DIContainer.swift in Sources */,
DD2968022D6DAC9B00143851 /* ViewController.swift in Sources */,
DE8FF1912D8155DD00C41880 /* WableButton.swift in Sources */,
DDCD66FD2D7DF6D900EF4C28 /* ProfileViewController.swift in Sources */,
DE7C53182D761F3A00076E5D /* ReuseIdentifiable.swift in Sources */,
DD2967FC2D6DAC4800143851 /* Injected.swift in Sources */,
Expand Down Expand Up @@ -1386,6 +1401,7 @@
DD2968272D6DAD0B00143851 /* LoginMapper.swift in Sources */,
DDED594F2D784EC000A0BEF1 /* LocalKeyValueProvider.swift in Sources */,
DDED59752D78F16400A0BEF1 /* FetchNicknameDuplicationUseCase.swift in Sources */,
DE54B0402D832E78009A7C34 /* LoadingViewController.swift in Sources */,
DD2968282D6DAD0B00143851 /* InformationMapper.swift in Sources */,
DD2968292D6DAD0B00143851 /* WableError.swift in Sources */,
DD29682A2D6DAD0B00143851 /* ErrorMapper.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
//
// LoadingViewController.swift
// Wable-iOS
//
// Created by 김진웅 on 3/14/25.
//

import UIKit

import Lottie
import SnapKit
import Then

final class LoadingViewController: UIViewController {

// MARK: - UIComponent

private let loadingAnimationView = LottieAnimationView(
name: LottieType.loading.rawValue
).then{
$0.contentMode = .scaleAspectFit
$0.loopMode = .playOnce
}

private lazy var messageLabel = UILabel().then {
$0.attributedText = Self.messages.randomElement()?.pretendardString(with: .head1)
$0.textAlignment = .center
$0.numberOfLines = 0
}

// MARK: - Property

private let loadingDuration: TimeInterval = 1.6

// MARK: - Initializer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

init()도 LifeCycle에 포함되는데 따로 분리하신 이유가 궁금해요 !!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

물론 이니셜라이저도 라이프 사이클에 포함되나, 의존성 주입이나 객체 구성 방식을 결정하며 이니셜라이저는 외부에서 명시적으로 호출됩니다.
그렇기 때문에 라이프 사이클의 다른 메서드와는 특징이 다르다고 생각하는데요.
그러한 이유로 저는 별도의 마크 주석으로 작성하고 있습니다.


init() {
super.init(nibName: nil, bundle: nil)

modalTransitionStyle = .crossDissolve
modalPresentationStyle = .overFullScreen
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: - Life Cycle

override func viewDidLoad() {
super.viewDidLoad()

setupView()
setupConstraint()
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

startAnimationAndDismiss()
}

private func startAnimationAndDismiss() {
loadingAnimationView.play()

DispatchQueue.main.asyncAfter(deadline: .now() + loadingDuration) {
self.loadingAnimationView.pause()
self.dismiss(animated: true)
}
}
Comment on lines +63 to +70
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 ... 다른 뷰컨에서도 쓸 수 있을 것 같은데 익스텐션으로 분리해보는 것도 좋을 것 같아요!

}

// MARK: - Setup Method

private extension LoadingViewController {
func setupView() {
view.backgroundColor = .wableWhite

view.addSubviews(
loadingAnimationView,
messageLabel
)
}

func setupConstraint() {
loadingAnimationView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(252)
make.centerX.equalToSuperview()
make.adjustedWidthEqualTo(160)
make.height.equalTo(loadingAnimationView.snp.width)
}

messageLabel.snp.makeConstraints { make in
make.top.equalTo(loadingAnimationView.snp.bottom).offset(36)
make.horizontalEdges.equalToSuperview().inset(30)
}
}
}

// MARK: - Messages

private extension LoadingViewController {
static let messages: [String] = [
"경기 보고 어디서 모여?\n와블에서",
"와블와블",
"팬으로서 저의가 해야 할 건\n끊임없는 응원이에요",
"우리는 선수와 팀을 대표하는 얼굴이에요",
"선수들을 응원하되 스포츠의 시각으로\n바라봐주세요",
"온화함을 해치는 글에 슬며시 투명도를\n눌러주세요",
"이기면 함께 축하하고, 지면 다음에\n잘하면 된다고 격려해 주세요",
"일부 팬의 행동으로 전체 팬을\n욕하지 말아주세요",
"말하기 전에 항상\n다시 한번 생각하기 약속!",
"숨어있는 롤잘알분들 나와주세요",
"함께 경기 볼 사람들은 여기로 모여~",
"유쾌하면서도 편안할 수 있는 공간\n함께 만들어 주실 거죠?",
"'나는 와블해'라고 말할 수 있는\n커뮤니티가 되고 싶어요!",
"와블은 온화한 LCK 팬들이\n모이는 공간을 지향해요",
"와블이라는 이름은 새가 부르는 노래라는\n뜻을 가진 Warble에서 유래했어요",
"경기 라이브로 챙겨 본 후, 하이라이트\n보고, BJ 경기 후기, 전문가 평가까지\n싹 찾아보는 사람 손~!",
"와글와글"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
//
// NotFoundViewController.swift
// Wable-iOS
//
// Created by 김진웅 on 3/13/25.
//

import UIKit

import SnapKit
import Then

final class NotFoundViewController: UIViewController {

// MARK: - UIComponent

private let notFoundImageView = UIImageView().then {
$0.image = .imgError
$0.contentMode = .scaleAspectFit
}

private let titleLabel = UILabel().then {
$0.attributedText = "이런!".pretendardString(with: .head0)
$0.textAlignment = .center
$0.textColor = .wableBlack
}

private let subtitleLabel = UILabel().then {
$0.attributedText = "현재 요청하신 페이지를 찾을 수 없어요!".pretendardString(with: .head2)
$0.textAlignment = .center
$0.textColor = .wableBlack
}

private let backToHomeButton = WableButton(style: .black).then {
var config = $0.configuration
config?.attributedTitle = "홈으로 가기".pretendardString(with: .body1)
$0.configuration = config
}

// MARK: - Property

private let backToHomeAction: () -> Void

// MARK: - Initializer

init(backToHomeAction: @escaping () -> Void) {
self.backToHomeAction = backToHomeAction

super.init(nibName: nil, bundle: nil)

modalTransitionStyle = .crossDissolve
modalPresentationStyle = .overFullScreen
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: - Life Cycle

override func viewDidLoad() {
super.viewDidLoad()

setupView()
setupConstraint()
setupAction()
}
}

// MARK: - Setup Method

private extension NotFoundViewController {
func setupView() {
view.backgroundColor = .wableWhite

view.addSubviews(
notFoundImageView,
titleLabel,
subtitleLabel,
backToHomeButton
)
}

func setupConstraint() {
notFoundImageView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(196)
make.centerX.equalToSuperview()
make.adjustedWidthEqualTo(220)
make.height.equalTo(notFoundImageView.snp.width)
}

titleLabel.snp.makeConstraints { make in
make.top.equalTo(notFoundImageView.snp.bottom).offset(12)
make.horizontalEdges.equalToSuperview().inset(16)
}

subtitleLabel.snp.makeConstraints { make in
make.top.equalTo(titleLabel.snp.bottom).offset(16)
make.horizontalEdges.equalTo(titleLabel)
}

backToHomeButton.snp.makeConstraints { make in
make.top.equalTo(subtitleLabel.snp.bottom).offset(44)
make.horizontalEdges.equalToSuperview().inset(48)
make.height.equalTo(backToHomeButton.snp.width).multipliedBy(48.0/280.0)
}
}

func setupAction() {
let dismissAction = UIAction { [weak self] _ in
self?.backToHomeAction()
self?.dismiss(animated: true)
}

backToHomeButton.addAction(dismissAction, for: .touchUpInside)
}
}
Loading