├── .githooks ├── commit-msg └── pre-commit ├── .github ├── ISSUE_TEMPLATE │ └── feature_request.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .swiftlint.yml ├── Mogakco.entitlements ├── Mogakco ├── Resources │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── 100.png │ │ │ ├── 102.png │ │ │ ├── 1024.png │ │ │ ├── 114.png │ │ │ ├── 120.png │ │ │ ├── 128.png │ │ │ ├── 144.png │ │ │ ├── 152.png │ │ │ ├── 16.png │ │ │ ├── 167.png │ │ │ ├── 172.png │ │ │ ├── 180.png │ │ │ ├── 196.png │ │ │ ├── 20.png │ │ │ ├── 216.png │ │ │ ├── 256.png │ │ │ ├── 29.png │ │ │ ├── 32.png │ │ │ ├── 40.png │ │ │ ├── 48.png │ │ │ ├── 50.png │ │ │ ├── 512.png │ │ │ ├── 55.png │ │ │ ├── 57.png │ │ │ ├── 58.png │ │ │ ├── 60.png │ │ │ ├── 64.png │ │ │ ├── 66.png │ │ │ ├── 72.png │ │ │ ├── 76.png │ │ │ ├── 80.png │ │ │ ├── 87.png │ │ │ ├── 88.png │ │ │ ├── 92.png │ │ │ └── Contents.json │ │ ├── Careers │ │ │ ├── Contents.json │ │ │ ├── baemin.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── baemin.png │ │ │ ├── carrot.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── carrot.png │ │ │ ├── facebook.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── facebook.png │ │ │ ├── kakao.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── kakao.png │ │ │ ├── line.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── line.png │ │ │ ├── naver.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── naver.png │ │ │ ├── toss.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── toss.png │ │ │ └── worksMobile.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── worksMobile.png │ │ ├── Categorys │ │ │ ├── Contents.json │ │ │ ├── ai.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── ai.png │ │ │ ├── algorithm.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── algorithm.png │ │ │ ├── android.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── android.png │ │ │ ├── backend.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── backend.png │ │ │ ├── bigdata.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── bigdata.png │ │ │ ├── contest.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── contest.png │ │ │ ├── cs.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── cs.png │ │ │ ├── frontend.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── frontend.png │ │ │ ├── hackathon.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── hackathon.png │ │ │ ├── iOS.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── iOS.png │ │ │ ├── interview.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── interview.png │ │ │ └── machineLearning.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── machineLearning.png │ │ ├── Colors │ │ │ ├── BackgroundDefault.colorset │ │ │ │ └── Contents.json │ │ │ ├── BorderDefault.colorset │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── PrimaryDefault.colorset │ │ │ │ └── Contents.json │ │ │ ├── PrimarySecondary.colorset │ │ │ │ └── Contents.json │ │ │ ├── PrimaryThird.colorset │ │ │ │ └── Contents.json │ │ │ ├── SemanticDisabled.colorset │ │ │ │ └── Contents.json │ │ │ ├── SemanticNegative.colorset │ │ │ │ └── Contents.json │ │ │ ├── SemanticSuccess.colorset │ │ │ │ └── Contents.json │ │ │ ├── TypographyPrimary.colorset │ │ │ │ └── Contents.json │ │ │ ├── TypographySecondary.colorset │ │ │ │ └── Contents.json │ │ │ ├── TypopraphyDisabled.colorset │ │ │ │ └── Contents.json │ │ │ ├── gradientEnd.colorset │ │ │ │ └── Contents.json │ │ │ └── gradientStart.colorset │ │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── Languages │ │ │ ├── Contents.json │ │ │ ├── c.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── pngegg (1).png │ │ │ ├── cShop.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── cShop.png │ │ │ ├── cpp.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── cpp.png │ │ │ ├── dart.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── pngegg (5).png │ │ │ ├── go.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── go.png │ │ │ ├── haskell.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── pngegg (2).png │ │ │ ├── javaScript.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── javaScript.jpeg │ │ │ ├── kotlin.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── kotlin.png │ │ │ ├── matlab.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── matlab.png │ │ │ ├── objectC.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── objectC.png │ │ │ ├── php.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── php.png │ │ │ ├── python.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── python.png │ │ │ ├── r.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── pngegg.png │ │ │ ├── ruby.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── ruby.png │ │ │ ├── rust.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── pngegg (3).png │ │ │ ├── scratch.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── pngegg (4).png │ │ │ ├── sql.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── sql.png │ │ │ ├── swift.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── swift.png │ │ │ └── visualBasic.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── visualBasic.png │ │ └── Profiles │ │ │ ├── Contents.json │ │ │ ├── profile.imageset │ │ │ ├── Contents.json │ │ │ └── profile.jpeg │ │ │ ├── profile1.imageset │ │ │ ├── Contents.json │ │ │ └── profile1.png │ │ │ ├── profile10.imageset │ │ │ ├── Contents.json │ │ │ └── profile10.png │ │ │ ├── profile11.imageset │ │ │ ├── Contents.json │ │ │ └── profile11.png │ │ │ ├── profile12.imageset │ │ │ ├── Contents.json │ │ │ └── profile12.png │ │ │ ├── profile13.imageset │ │ │ ├── Contents.json │ │ │ └── profile13.png │ │ │ ├── profile14.imageset │ │ │ ├── Contents.json │ │ │ └── profile14.png │ │ │ ├── profile15.imageset │ │ │ ├── Contents.json │ │ │ └── profile15.png │ │ │ ├── profile16.imageset │ │ │ ├── Contents.json │ │ │ └── profile16.png │ │ │ ├── profile17.imageset │ │ │ ├── Contents.json │ │ │ └── profile17.png │ │ │ ├── profile2.imageset │ │ │ ├── Contents.json │ │ │ └── profile2.png │ │ │ ├── profile3.imageset │ │ │ ├── Contents.json │ │ │ └── profile3.png │ │ │ ├── profile4.imageset │ │ │ ├── Contents.json │ │ │ └── profile4.png │ │ │ ├── profile5.imageset │ │ │ ├── Contents.json │ │ │ └── profile5.png │ │ │ ├── profile6.imageset │ │ │ ├── Contents.json │ │ │ └── profile6.png │ │ │ ├── profile7.imageset │ │ │ ├── Contents.json │ │ │ └── profile7.png │ │ │ ├── profile8.imageset │ │ │ ├── Contents.json │ │ │ └── profile8.png │ │ │ └── profile9.imageset │ │ │ ├── Contents.json │ │ │ └── profile9.png │ ├── Base.lproj │ │ └── LaunchScreen.storyboard │ ├── Fonts │ │ ├── SFProDisplay-Regular.ttf │ │ └── SFProDisplay-Semibold.ttf │ ├── en.lproj │ │ └── InfoPlist.strings │ └── ko.lproj │ │ ├── InfoPlist.strings │ │ └── LaunchScreen.strings └── Sources │ ├── App │ ├── AppDelegate.swift │ ├── DIContainer.swift │ └── SceneDelegate.swift │ ├── Data │ ├── DataMapping │ │ ├── AuthorizationResponseDTO.swift │ │ ├── Career.swift │ │ ├── Category.swift │ │ ├── ChatRequestDTO.swift │ │ ├── ChatResponseDTO.swift │ │ ├── ChatRoomResponseDTO.swift │ │ ├── CreateChatRoomRequestDTO.swift │ │ ├── EditCareersRequestDTO.swift │ │ ├── EditCategorysRequestDTO.swift │ │ ├── EditLanguagesRequestDTO.swift │ │ ├── EditProfileRequestDTO.swift │ │ ├── EmailAuthorizationRequestDTO.swift │ │ ├── FirestoreValueDTOs.swift │ │ ├── Language.swift │ │ ├── PushNotificationRequestDTO.swift │ │ ├── StudyRequestDTO.swift │ │ ├── StudyResponseDTO.swift │ │ ├── UpdateStudyIDsRequestDTO.swift │ │ ├── UpdateUserIDsRequestDTO.swift │ │ ├── UserRequestDTO.swift │ │ └── UserResponseDTO.swift │ ├── DataSources │ │ ├── Local │ │ │ ├── HashtagDataSource.swift │ │ │ ├── Keychain.swift │ │ │ ├── KeychainManager.swift │ │ │ └── ReportDataSource.swift │ │ ├── Protocol │ │ │ ├── AuthServiceProtocol.swift │ │ │ ├── ChatDataSourceProtocol.swift │ │ │ ├── ChatRoomDataSourceProtocol.swift │ │ │ ├── HashtagDataSourceProtocol.swift │ │ │ ├── KeychainManagerProtocol.swift │ │ │ ├── KeychainProtocol.swift │ │ │ ├── PushNotificationServiceProtocol.swift │ │ │ ├── RemoteUserDataSourceProtocol.swift │ │ │ ├── ReportDataSourceProtocol.swift │ │ │ └── StudyDataSourceProtocol.swift │ │ └── Remote │ │ │ ├── ChatDataSource.swift │ │ │ ├── ChatRoomDataSource.swift │ │ │ ├── FBAuthService.swift │ │ │ ├── PushNotificationService.swift │ │ │ ├── RemoteUserDataSource.swift │ │ │ └── StudyDataSource.swift │ └── Repositories │ │ ├── AuthRepository.swift │ │ ├── ChatRepository.swift │ │ ├── ChatRoomRepository.swift │ │ ├── HashtagRepository.swift │ │ ├── ReportRepository.swift │ │ ├── StudyRepository.swift │ │ ├── TokenRepository.swift │ │ └── UserRepository.swift │ ├── Domain │ ├── Entities │ │ ├── Authorization.swift │ │ ├── Chat.swift │ │ ├── ChatRoom.swift │ │ ├── EmailLogin.swift │ │ ├── Profile.swift │ │ ├── Study.swift │ │ ├── StudyFilter.swift │ │ ├── StudySort.swift │ │ └── User.swift │ ├── Repositories │ │ ├── AuthRepositoryProtocol.swift │ │ ├── ChatRepositoryProtocol.swift │ │ ├── ChatRoomRepositoryProtocol.swift │ │ ├── HashtagRepositoryProtocol.swift │ │ ├── ReportRepositoryProtocol.swift │ │ ├── StudyRepositoryProtocol.swift │ │ ├── TokenRepositoryProtocol.swift │ │ └── UserRepositoryProtocol.swift │ └── UseCases │ │ ├── AutoLoginUseCase.swift │ │ ├── ChatRoomListUseCase.swift │ │ ├── ChatUseCase.swift │ │ ├── CreateChatRoomUseCase.swift │ │ ├── CreateStudyUseCase.swift │ │ ├── EditProfileUseCase.swift │ │ ├── HashtagUseCase.swift │ │ ├── JoinStudyUseCase.swift │ │ ├── LeaveStudyUseCase.swift │ │ ├── LoginUseCase.swift │ │ ├── LogoutUseCase.swift │ │ ├── ProfileUseCase.swift │ │ ├── Protocol │ │ ├── AutoLoginUseCaseProtocol.swift │ │ ├── ChatRoomListUseCaseProtocol.swift │ │ ├── ChatUseCaseProtocol.swift │ │ ├── CreateChatRoomUseCaseProtocol.swift │ │ ├── CreateStudyUseCaseProtocol.swift │ │ ├── EditProfileUseCaseProtocol.swift │ │ ├── HashtagUseCaseProtocol.swift │ │ ├── JoinStudyUseCaseProtocol.swift │ │ ├── LeaveStudyUseCaseProtocol.swift │ │ ├── LoginUseCaseProtocol.swift │ │ ├── LogoutUseCaseProtocol.swift │ │ ├── ProfileUseCaseProtocol.swift │ │ ├── ReportUseCaseProtocol.swift │ │ ├── SignupUseCaseProtocol.swift │ │ ├── StudyDetailUseCaseProtocol.swift │ │ ├── StudyListUseCaseProtocol.swift │ │ ├── SubscribePushNotificationUseCaseProtocol.swift │ │ ├── UnsubscribePushNotificationUseCaseProtocol.swift │ │ ├── UserUseCaseProtocol.swift │ │ └── WithdrawUseCaseProtocol.swift │ │ ├── ReportUseCase.swift │ │ ├── SignupUseCase.swift │ │ ├── StudyDetailUseCase.swift │ │ ├── StudyListUseCase.swift │ │ ├── SubscribePushNotificationUseCase.swift │ │ ├── UnsubscribePushNotificationUseCase.swift │ │ ├── UserUseCase.swift │ │ └── WithdrawUseCase.swift │ ├── Presentation │ ├── Chat │ │ ├── View │ │ │ ├── ChatCell.swift │ │ │ ├── ChatRoomTableViewCell.swift │ │ │ ├── ChatRoomUsersImageView.swift │ │ │ ├── ChatSidebarTableViewCell.swift │ │ │ ├── ChatSidebarView.swift │ │ │ └── MessageInputView.swift │ │ ├── ViewController │ │ │ ├── ChatListViewController.swift │ │ │ └── ChatViewController.swift │ │ └── ViewModel │ │ │ ├── ChatListViewModel.swift │ │ │ └── ChatViewModel.swift │ ├── Common │ │ ├── Coordinator │ │ │ ├── AppCoordinator.swift │ │ │ ├── BaseCoordinator.swift │ │ │ ├── ChatRoomCoordinator.swift │ │ │ ├── ChatRoomListCoordinator.swift │ │ │ ├── EmailCoordinator.swift │ │ │ ├── HashtagCoordinator.swift │ │ │ ├── LoginCoordinator.swift │ │ │ ├── PasswordCoordinator.swift │ │ │ ├── ProfileCoordinator.swift │ │ │ ├── SettingCoordinator.swift │ │ │ ├── SignupCareerHashtagCoordinator.swift │ │ │ ├── SignupEditProfileCoordinator.swift │ │ │ ├── SignupLanguageHashtagCoordinator.swift │ │ │ ├── StudyDetailCoordinator.swift │ │ │ ├── StudyListCoordinator.swift │ │ │ └── TabCoordinator.swift │ │ ├── Protocol │ │ │ ├── Identifiable.swift │ │ │ └── ViewModel.swift │ │ ├── Skeleton │ │ │ ├── Extension │ │ │ │ ├── UIColor+SkeletonColor.swift │ │ │ │ ├── UIVIew+RxSkeleton.swift │ │ │ │ └── UIView+Animation.swift │ │ │ └── View │ │ │ │ ├── ChatRoom │ │ │ │ ├── ChatRoomListSkeletonView.swift │ │ │ │ └── ChatRoomLoadingCellSkeletonView.swift │ │ │ │ ├── Common │ │ │ │ ├── LoadingView.swift │ │ │ │ └── SkeletonView.swift │ │ │ │ ├── Image │ │ │ │ └── ImageSkeletonView.swift │ │ │ │ ├── SkeletonContentsViews.swift │ │ │ │ ├── StudyDetail │ │ │ │ └── StudyDetailSkeletonView.swift │ │ │ │ ├── StudyList │ │ │ │ ├── StudyListCellSkeletonView.swift │ │ │ │ └── StudyListSkeletonView.swift │ │ │ │ └── UserProfile │ │ │ │ └── UserProfileSkeletonView.swift │ │ ├── View │ │ │ ├── CountTextField.swift │ │ │ ├── CountTextView.swift │ │ │ ├── HalfModal │ │ │ │ └── HalfModalViewController.swift │ │ │ ├── HashtagBadgeCell.swift │ │ │ ├── MessageTextField.swift │ │ │ ├── RoundProfileImage.swift │ │ │ ├── SecureTextField.swift │ │ │ ├── TextField.swift │ │ │ ├── TextView.swift │ │ │ ├── TitleHeaderView.swift │ │ │ └── ValidationButton.swift │ │ └── ViewController │ │ │ ├── AlertModalViewController.swift │ │ │ └── ViewController.swift │ ├── Hashtag │ │ ├── Layout │ │ │ └── HashtagFlowLayout.swift │ │ ├── Protocol │ │ │ ├── HashtagProtocol.swift │ │ │ └── HashtagSelectProtocol.swift │ │ ├── View │ │ │ └── HashtagHeader.swift │ │ ├── ViewController │ │ │ └── HashtagSelectViewController.swift │ │ └── ViewModel │ │ │ ├── HashtagEditViewModel.swift │ │ │ ├── HashtagFilterViewModel.swift │ │ │ ├── HashtagSelectViewModel.swift │ │ │ └── HashtagViewModel.swift │ ├── Login │ │ ├── View │ │ │ └── LogoView.swift │ │ ├── ViewController │ │ │ └── LoginViewController.swift │ │ └── ViewModel │ │ │ └── LoginViewModel.swift │ ├── Profile │ │ ├── View │ │ │ ├── HashtagListView.swift │ │ │ ├── ProfileView.swift │ │ │ ├── StudyRatingListView.swift │ │ │ └── StudyRatingView.swift │ │ ├── ViewController │ │ │ ├── EditProfileViewController.swift │ │ │ └── ProfileViewController.swift │ │ └── ViewModel │ │ │ ├── EditProfileViewModel.swift │ │ │ └── ProfileViewModel.swift │ ├── Setting │ │ ├── View │ │ │ └── SettingTableViewCell.swift │ │ ├── ViewController │ │ │ ├── SettingViewController.swift │ │ │ └── WithdrawViewController.swift │ │ └── ViewModel │ │ │ ├── SettingViewModel.swift │ │ │ └── WithdrawViewModel.swift │ ├── Signup │ │ ├── Model │ │ │ ├── EmailProps.swift │ │ │ ├── LanguageProps.swift │ │ │ ├── PasswordProps.swift │ │ │ ├── ProfileProps.swift │ │ │ └── SignupProps.swift │ │ ├── View │ │ │ └── PolicyCheckBox.swift │ │ ├── ViewController │ │ │ ├── PolicyViewController.swift │ │ │ ├── SetEmailViewController.swift │ │ │ └── SetPasswordViewController.swift │ │ └── ViewModel │ │ │ ├── PolicyViewModel.swift │ │ │ ├── SetEmailViewModel.swift │ │ │ └── SetPasswordViewModel.swift │ └── Study │ │ ├── View │ │ ├── ParticipantCell.swift │ │ ├── StudyCell.swift │ │ ├── StudyInfoView.swift │ │ ├── StudyListHeader.swift │ │ ├── StudySelectView.swift │ │ ├── StudySortCell.swift │ │ ├── StudyStepperView.swift │ │ └── StudyTitleLabel.swift │ │ ├── ViewController │ │ ├── CreateStudyViewController.swift │ │ ├── SelectStudySortViewController.swift │ │ ├── StudyDetailViewController.swift │ │ └── StudyListViewController.swift │ │ └── ViewModel │ │ ├── CreateStudyViewModel.swift │ │ ├── SelectStudySortViewModel.swift │ │ ├── StudyDetailViewModel.swift │ │ └── StudyListViewModel.swift │ └── Util │ ├── Constant │ ├── Format.swift │ ├── Image.swift │ ├── Layout.swift │ └── Network.swift │ └── Extension │ ├── Array+Equtable.swift │ ├── Array+Hashable.swift │ ├── Date+Formatter.swift │ ├── Encodable+Dictionary.swift │ ├── Int+Convert.swift │ ├── Int+Formatter.swift │ ├── ObservableType+Result.swift │ ├── RxUIImageView+URL.swift │ ├── RxUIViewController+LifeCycle.swift │ ├── String+Date.swift │ ├── UIButton+BackgroundColor.swift │ ├── UIColor+MogakcoColor.swift │ ├── UIFont+CustomFont.swift │ ├── UIImageView+URL.swift │ ├── UILabel+LineSpacing.swift │ ├── UINavigation+Swipe.swift │ ├── UIView+AddSubViews.swift │ ├── UIView+Gradient.swift │ ├── UIView+Shadow.swift │ ├── UIViewController+Alert.swift │ ├── UIViewController+HalfModal.swift │ └── UIViewController+Keyboard.swift ├── Mogakmation └── Sources │ ├── AnimationImageView.swift │ └── AnimationView.swift ├── Plugins └── Mogakco │ ├── Package.swift │ ├── Plugin.swift │ ├── ProjectDescriptionHelpers │ └── LocalHelper.swift │ └── Sources │ └── tuist-my-cli │ └── main.swift ├── Project.swift ├── README.md ├── RxMGKfisher └── Sources │ ├── CacheConstants.swift │ ├── CacheableImage.swift │ └── MGKImageCacheService.swift ├── RxMogakcoYa └── Sources │ ├── NetworkEventLogger.swift │ ├── Provider.swift │ ├── ProviderProtocol.swift │ └── TargetType.swift ├── Scripts └── SwiftLintRunScript.sh └── Tuist ├── Config.swift ├── Dependencies.swift └── ProjectDescriptionHelpers └── Project+Templates.swift /.githooks/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ## 3 | # @author Prahlad Yeri 4 | # @email prahladyeri@yahoo.com 5 | # @title Git hook for enforcing conventional commit spec 6 | # 7 | # @todo Create folder ~/.git-templatesand set that value to init.templatedir git config key globally. 8 | # @todo Copy this script to ~/.git-templates/hooks/ and rename it to commit-msg. 9 | # @todo (Linux): Make the script executable. 10 | import re, sys, os 11 | 12 | examples = """+ 61c8ca9 fix: navbar not responsive on mobile 13 | + 479c48b test: prepared test cases for user authentication 14 | + a992020 chore: moved to semantic versioning 15 | + b818120 fix: button click even handler firing twice 16 | + c6e9a97 fix: login page css 17 | + dfdc715 feat(auth): added social login using twitter 18 | """ 19 | 20 | def main(): 21 | # example: 22 | # feat(apikey): added the ability to add api key to configuration 23 | pattern = r'(feat|fix|docs|refactor|test|build|style|chore)(\([\w\-]+\))?:\s.*' 24 | filename = sys.argv[1] 25 | ss = open(filename, 'r').read() 26 | m = re.match(pattern, ss) 27 | if m == None: 28 | #raise Exception("conventional commit validation failed") 29 | print("\nCOMMIT FAILED!") 30 | print("\nPlease enter commit message in the conventional format and try to commit again. Examples:") 31 | print("\n" + examples) 32 | sys.exit(1) 33 | 34 | if __name__ == "__main__": 35 | main() 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "" 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ##  설명 11 | 12 | ## ✓ 체크리스트 13 | - [ ] 14 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### PR Type 2 | 3 | - [ ] 기능 추가 🔨 4 | - [ ] 버그 수정 🐞 5 | - [ ] 리팩토링 🚧 6 | - [ ] 의존성, 환경 변수, 빌드 관련 코드 업데이트 ⚙️ 7 | - [ ] 기타 사소한 수정 🎸 8 | - [ ] 테스트 🔍 9 | 10 | 11 | ### Related Issue(작업 내용) 12 | 13 | > 이슈 번호와 구현 내용 및 작업 했던 내역을 입력해주세요! 14 | > 15 | - close #25 16 | - 작업 내역 작성 17 | 18 | ### 참고 사항 19 | 20 | ### Screenshots(Optional) 21 | 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Custom ### 2 | .xcuserstate 3 | GoogleService-Info.plist 4 | 5 | ### macOS ### 6 | # General 7 | .DS_Store 8 | .AppleDouble 9 | .LSOverride 10 | 11 | # Icon must end with two 12 | Icon 13 | 14 | # Thumbnails 15 | ._* 16 | 17 | # Files that might appear in the root of a volume 18 | .DocumentRevisions-V100 19 | .fseventsd 20 | .Spotlight-V100 21 | .TemporaryItems 22 | .Trashes 23 | .VolumeIcon.icns 24 | .com.apple.timemachine.donotpresent 25 | 26 | # Directories potentially created on remote AFP share 27 | .AppleDB 28 | .AppleDesktop 29 | Network Trash Folder 30 | Temporary Items 31 | .apdisk 32 | 33 | ### Xcode ### 34 | # Xcode 35 | # 36 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 37 | 38 | ## User settings 39 | xcuserdata/ 40 | 41 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 42 | *.xcscmblueprint 43 | *.xccheckout 44 | 45 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 46 | build/ 47 | DerivedData/ 48 | *.moved-aside 49 | *.pbxuser 50 | !default.pbxuser 51 | *.mode1v3 52 | !default.mode1v3 53 | *.mode2v3 54 | !default.mode2v3 55 | *.perspectivev3 56 | !default.perspectivev3 57 | 58 | ### Xcode Patch ### 59 | *.xcodeproj/* 60 | !*.xcodeproj/project.pbxproj 61 | !*.xcodeproj/xcshareddata/ 62 | !*.xcworkspace/contents.xcworkspacedata 63 | /*.gcno 64 | 65 | ### Projects ### 66 | *.xcodeproj 67 | *.xcworkspace 68 | 69 | ### Tuist derived files ### 70 | graph.dot 71 | Derived/ 72 | 73 | ### Tuist managed dependencies ### 74 | Tuist/Dependencies 75 | 76 | 77 | -------------------------------------------------------------------------------- /Mogakco.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | aps-environment 6 | development 7 | 8 | 9 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/100.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/102.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/102.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/114.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/128.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/144.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/152.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/16.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/167.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/172.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/172.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/196.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/20.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/216.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/256.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/29.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/32.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/48.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/50.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/512.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/55.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/57.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/64.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/66.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/66.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/72.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/76.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/88.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/88.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/92.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/AppIcon.appiconset/92.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/baemin.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "baemin.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/baemin.imageset/baemin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Careers/baemin.imageset/baemin.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/carrot.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "carrot.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/carrot.imageset/carrot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Careers/carrot.imageset/carrot.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/facebook.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "facebook.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/facebook.imageset/facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Careers/facebook.imageset/facebook.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/kakao.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "kakao.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/kakao.imageset/kakao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Careers/kakao.imageset/kakao.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/line.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "line.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/line.imageset/line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Careers/line.imageset/line.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/naver.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "naver.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/naver.imageset/naver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Careers/naver.imageset/naver.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/toss.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "toss.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/toss.imageset/toss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Careers/toss.imageset/toss.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/worksMobile.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "worksMobile.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Careers/worksMobile.imageset/worksMobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Careers/worksMobile.imageset/worksMobile.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/ai.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ai.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/ai.imageset/ai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Categorys/ai.imageset/ai.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/algorithm.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "algorithm.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/algorithm.imageset/algorithm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Categorys/algorithm.imageset/algorithm.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/android.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "android.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/android.imageset/android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Categorys/android.imageset/android.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/backend.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "backend.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/backend.imageset/backend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Categorys/backend.imageset/backend.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/bigdata.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "bigdata.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/bigdata.imageset/bigdata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Categorys/bigdata.imageset/bigdata.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/contest.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "contest.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/contest.imageset/contest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Categorys/contest.imageset/contest.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/cs.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "cs.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/cs.imageset/cs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Categorys/cs.imageset/cs.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/frontend.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "frontend.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/frontend.imageset/frontend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Categorys/frontend.imageset/frontend.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/hackathon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "hackathon.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/hackathon.imageset/hackathon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Categorys/hackathon.imageset/hackathon.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/iOS.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "iOS.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/iOS.imageset/iOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Categorys/iOS.imageset/iOS.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/interview.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "interview.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/interview.imageset/interview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Categorys/interview.imageset/interview.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/machineLearning.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "machineLearning.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Categorys/machineLearning.imageset/machineLearning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Categorys/machineLearning.imageset/machineLearning.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Colors/BackgroundDefault.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.141", 9 | "green" : "0.141", 10 | "red" : "0.141" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Colors/BorderDefault.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.944", 9 | "green" : "0.918", 10 | "red" : "0.915" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Colors/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Colors/PrimaryDefault.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.114", 9 | "green" : "0.431", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Colors/PrimarySecondary.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.208", 9 | "green" : "0.247", 10 | "red" : "0.310" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Colors/PrimaryThird.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "display-p3", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.188", 9 | "green" : "0.200", 10 | "red" : "0.227" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Colors/SemanticDisabled.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "display-p3", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.103", 9 | "green" : "0.221", 10 | "red" : "0.436" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Colors/SemanticNegative.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.196", 9 | "green" : "0.244", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Colors/SemanticSuccess.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.114", 9 | "green" : "0.431", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | }, 20 | "properties" : { 21 | "localizable" : true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Colors/TypographyPrimary.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "1.000", 9 | "green" : "1.000", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Colors/TypographySecondary.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.627", 9 | "green" : "0.527", 10 | "red" : "0.471" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Colors/TypopraphyDisabled.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.851", 9 | "green" : "0.807", 10 | "red" : "0.785" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Colors/gradientEnd.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x28", 9 | "green" : "0x37", 10 | "red" : "0xFF" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Colors/gradientStart.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x41", 9 | "green" : "0xAA", 10 | "red" : "0xF9" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/c.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "pngegg (1).png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/c.imageset/pngegg (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/c.imageset/pngegg (1).png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/cShop.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "cShop.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/cShop.imageset/cShop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/cShop.imageset/cShop.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/cpp.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "cpp.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/cpp.imageset/cpp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/cpp.imageset/cpp.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/dart.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "pngegg (5).png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/dart.imageset/pngegg (5).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/dart.imageset/pngegg (5).png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/go.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "go.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/go.imageset/go.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/go.imageset/go.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/haskell.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "pngegg (2).png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/haskell.imageset/pngegg (2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/haskell.imageset/pngegg (2).png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/javaScript.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "javaScript.jpeg", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/javaScript.imageset/javaScript.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/javaScript.imageset/javaScript.jpeg -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/kotlin.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "kotlin.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/kotlin.imageset/kotlin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/kotlin.imageset/kotlin.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/matlab.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "matlab.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/matlab.imageset/matlab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/matlab.imageset/matlab.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/objectC.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "objectC.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/objectC.imageset/objectC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/objectC.imageset/objectC.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/php.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "php.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/php.imageset/php.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/php.imageset/php.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/python.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "python.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/python.imageset/python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/python.imageset/python.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/r.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "pngegg.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/r.imageset/pngegg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/r.imageset/pngegg.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/ruby.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ruby.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/ruby.imageset/ruby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/ruby.imageset/ruby.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/rust.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "pngegg (3).png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/rust.imageset/pngegg (3).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/rust.imageset/pngegg (3).png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/scratch.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "pngegg (4).png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/scratch.imageset/pngegg (4).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/scratch.imageset/pngegg (4).png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/sql.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "sql.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/sql.imageset/sql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/sql.imageset/sql.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/swift.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "swift.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/swift.imageset/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/swift.imageset/swift.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/visualBasic.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "visualBasic.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Languages/visualBasic.imageset/visualBasic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Languages/visualBasic.imageset/visualBasic.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile.jpeg", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile.imageset/profile.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile.imageset/profile.jpeg -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile1.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile1.imageset/profile1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile1.imageset/profile1.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile10.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile10.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile10.imageset/profile10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile10.imageset/profile10.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile11.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile11.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile11.imageset/profile11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile11.imageset/profile11.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile12.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile12.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile12.imageset/profile12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile12.imageset/profile12.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile13.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile13.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile13.imageset/profile13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile13.imageset/profile13.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile14.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile14.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile14.imageset/profile14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile14.imageset/profile14.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile15.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile15.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile15.imageset/profile15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile15.imageset/profile15.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile16.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile16.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile16.imageset/profile16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile16.imageset/profile16.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile17.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile17.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile17.imageset/profile17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile17.imageset/profile17.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile2.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile2.imageset/profile2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile2.imageset/profile2.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile3.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile3.imageset/profile3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile3.imageset/profile3.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile4.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile4.imageset/profile4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile4.imageset/profile4.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile5.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile5.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile5.imageset/profile5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile5.imageset/profile5.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile6.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile6.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile6.imageset/profile6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile6.imageset/profile6.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile7.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile7.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile7.imageset/profile7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile7.imageset/profile7.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile8.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile8.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile8.imageset/profile8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile8.imageset/profile8.png -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile9.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "profile9.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Resources/Assets.xcassets/Profiles/profile9.imageset/profile9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Assets.xcassets/Profiles/profile9.imageset/profile9.png -------------------------------------------------------------------------------- /Mogakco/Resources/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Mogakco/Resources/Fonts/SFProDisplay-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Fonts/SFProDisplay-Regular.ttf -------------------------------------------------------------------------------- /Mogakco/Resources/Fonts/SFProDisplay-Semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostcampwm-2022/iOS04-Mogakco/d3661fa279d9034007468d508de3624d75d37466/Mogakco/Resources/Fonts/SFProDisplay-Semibold.ttf -------------------------------------------------------------------------------- /Mogakco/Resources/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | Mogakco 4 | 5 | Created by 김범수 on 2022/12/08. 6 | Copyright © 2022 Mogakco. All rights reserved. 7 | */ 8 | 9 | "CFBundleDisplayName" = "모각코"; 10 | -------------------------------------------------------------------------------- /Mogakco/Resources/ko.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | Mogakco 4 | 5 | Created by 김범수 on 2022/12/08. 6 | Copyright © 2022 Mogakco. All rights reserved. 7 | */ 8 | 9 | "CFBundleDisplayName" = "모각코"; 10 | -------------------------------------------------------------------------------- /Mogakco/Resources/ko.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataMapping/AuthorizationResponseDTO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AuthorizationResponseDTO.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/23. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct AuthorizationResponseDTO: Decodable { 12 | private let idToken: String 13 | private let email: String 14 | private let refreshToken: String 15 | private let expiresIn: String 16 | private let localId: String 17 | 18 | func toDomain() -> Authorization { 19 | return Authorization( 20 | idToken: idToken, 21 | email: email, 22 | refreshToken: refreshToken, 23 | expiresIn: expiresIn, 24 | localId: localId 25 | ) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataMapping/Career.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Career.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum Career: String, CaseIterable, Hashtag { 12 | case baemin 13 | case carrot 14 | case facebook 15 | case kakao 16 | case line 17 | case naver 18 | case toss 19 | case worksMobile 20 | 21 | static func idToHashtag(id: String) -> Hashtag? { 22 | switch id { 23 | case "baemin": return Career.baemin 24 | case "carrot": return Career.carrot 25 | case "facebook": return Career.facebook 26 | case "kakao": return Career.kakao 27 | case "line": return Career.line 28 | case "naver": return Career.naver 29 | case "toss": return Career.toss 30 | case "worksMobile": return Career.worksMobile 31 | default: return nil 32 | } 33 | } 34 | 35 | var id: String { 36 | return self.rawValue 37 | } 38 | 39 | var title: String { 40 | switch self { 41 | case .baemin: return "배달의민족" 42 | case .carrot: return "당근마켓" 43 | case .facebook: return "페이스북(메타)" 44 | case .kakao: return "카카오" 45 | case .line: return "라인" 46 | case .naver: return "네이버" 47 | case .toss: return "토스" 48 | case .worksMobile: return "웍스모바일" 49 | } 50 | } 51 | 52 | var image: UIImage { 53 | return UIImage(named: id) ?? UIImage() 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataMapping/ChatRequestDTO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatRequestDTO.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/12/12. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct ChatRequestDTO: Encodable { 12 | let id: String 13 | let userID: String 14 | let message: String 15 | let chatRoomID: String 16 | let date: Int 17 | let readUserIDs: [String] 18 | 19 | init(chat: Chat) { 20 | self.id = chat.id 21 | self.userID = chat.userID 22 | self.message = chat.message 23 | self.chatRoomID = chat.chatRoomID 24 | self.date = chat.date 25 | self.readUserIDs = chat.readUserIDs 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataMapping/ChatRoomResponseDTO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatRoomResponseDTO.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct ChatRoomResponseDTO: Codable { 12 | private let id: StringValue 13 | private let studyID: StringValue? 14 | private let userIDs: ArrayValue 15 | 16 | private enum RootKey: String, CodingKey { 17 | case fields 18 | } 19 | 20 | private enum FieldKeys: String, CodingKey { 21 | case id, studyID, userIDs 22 | } 23 | 24 | init(from decoder: Decoder) throws { 25 | let container = try decoder.container(keyedBy: RootKey.self) 26 | let fieldContainer = try container.nestedContainer(keyedBy: FieldKeys.self, forKey: .fields) 27 | self.id = try fieldContainer.decode(StringValue.self, forKey: .id) 28 | self.studyID = try fieldContainer.decodeIfPresent(StringValue.self, forKey: .studyID) 29 | self.userIDs = try fieldContainer.decode(ArrayValue.self, forKey: .userIDs) 30 | } 31 | 32 | func toDomain() -> ChatRoom { 33 | return ChatRoom( 34 | id: id.value, 35 | studyID: studyID?.value, 36 | userIDs: userIDs.arrayValue.map { $0.value }.flatMap { $0.map { $0.value } }, 37 | latestChat: nil, 38 | unreadChatCount: nil, 39 | users: nil 40 | ) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataMapping/CreateChatRoomRequestDTO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CreateChatRoomRequestDTO.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/24. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct CreateChatRoomRequestDTO: Encodable { 12 | let id: StringValue 13 | private let studyID: StringValue? 14 | private let userIDs: ArrayValue 15 | 16 | private enum RootKey: String, CodingKey { 17 | case fields 18 | } 19 | 20 | 21 | private enum FieldKeys: String, CodingKey { 22 | case id, studyID, userIDs 23 | } 24 | 25 | func encode(to encoder: Encoder) throws { 26 | var container = encoder.container(keyedBy: RootKey.self) 27 | var fieldContainer = container.nestedContainer(keyedBy: FieldKeys.self, forKey: .fields) 28 | try fieldContainer.encode(self.id, forKey: .id) 29 | try fieldContainer.encodeIfPresent(self.studyID, forKey: .studyID) 30 | try fieldContainer.encode(self.userIDs, forKey: .userIDs) 31 | } 32 | 33 | init(id: String, studyID: String?, userIDs: [String]) { 34 | self.id = StringValue(value: id) 35 | if let studyID = studyID { 36 | self.studyID = StringValue(value: studyID) 37 | } else { 38 | self.studyID = nil 39 | } 40 | self.userIDs = ArrayValue(values: userIDs.map { StringValue(value: $0) }) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataMapping/EditCareersRequestDTO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditCareersRequestDTO.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/25. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct EditCareersRequestDTO: Encodable { 12 | private let careers: ArrayValue 13 | 14 | private enum RootKey: String, CodingKey { 15 | case fields 16 | } 17 | 18 | private enum FieldKeys: String, CodingKey { 19 | case careers 20 | } 21 | 22 | init(careers: [String]) { 23 | self.careers = ArrayValue(values: careers.map { StringValue(value: $0) }) 24 | } 25 | 26 | func encode(to encoder: Encoder) throws { 27 | var container = encoder.container(keyedBy: RootKey.self) 28 | var fieldContainer = container.nestedContainer(keyedBy: FieldKeys.self, forKey: .fields) 29 | try fieldContainer.encode(self.careers, forKey: .careers) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataMapping/EditCategorysRequestDTO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditCategorysRequestDTO.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/25. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct EditCategorysRequestDTO: Encodable { 12 | private let categorys: ArrayValue 13 | 14 | private enum RootKey: String, CodingKey { 15 | case fields 16 | } 17 | 18 | private enum FieldKeys: String, CodingKey { 19 | case categorys 20 | } 21 | 22 | init(categorys: [String]) { 23 | self.categorys = ArrayValue(values: categorys.map { StringValue(value: $0) }) 24 | } 25 | 26 | func encode(to encoder: Encoder) throws { 27 | var container = encoder.container(keyedBy: RootKey.self) 28 | var fieldContainer = container.nestedContainer(keyedBy: FieldKeys.self, forKey: .fields) 29 | try fieldContainer.encode(self.categorys, forKey: .categorys) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataMapping/EditLanguagesRequestDTO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditLanguagesRequestDTO.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/25. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct EditLanguagesRequestDTO: Encodable { 12 | private let languages: ArrayValue 13 | 14 | private enum RootKey: String, CodingKey { 15 | case fields 16 | } 17 | 18 | private enum FieldKeys: String, CodingKey { 19 | case languages 20 | } 21 | 22 | init(languages: [String]) { 23 | self.languages = ArrayValue(values: languages.map { StringValue(value: $0) }) 24 | } 25 | 26 | func encode(to encoder: Encoder) throws { 27 | var container = encoder.container(keyedBy: RootKey.self) 28 | var fieldContainer = container.nestedContainer(keyedBy: FieldKeys.self, forKey: .fields) 29 | try fieldContainer.encode(self.languages, forKey: .languages) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataMapping/EditProfileRequestDTO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditProfileRequestDTO.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/22. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct EditProfileRequestDTO: Encodable { 12 | private let name: StringValue 13 | private let introduce: StringValue 14 | private let profileImageURLString: StringValue 15 | 16 | private enum RootKey: String, CodingKey { 17 | case fields 18 | } 19 | 20 | private enum FieldKeys: String, CodingKey { 21 | case name, introduce, profileImageURLString 22 | } 23 | 24 | init(name: String, introduce: String, profileImageURLString: String) { 25 | self.name = StringValue(value: name) 26 | self.introduce = StringValue(value: introduce) 27 | self.profileImageURLString = StringValue(value: profileImageURLString) 28 | } 29 | 30 | func encode(to encoder: Encoder) throws { 31 | var container = encoder.container(keyedBy: RootKey.self) 32 | var fieldContainer = container.nestedContainer(keyedBy: FieldKeys.self, forKey: .fields) 33 | try fieldContainer.encode(self.name, forKey: .name) 34 | try fieldContainer.encode(self.introduce, forKey: .introduce) 35 | try fieldContainer.encode(self.profileImageURLString, forKey: .profileImageURLString) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataMapping/EmailAuthorizationRequestDTO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EmailAuthorization.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/23. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct EmailAuthorizationRequestDTO: Encodable { 12 | private let email: String 13 | private let password: String 14 | private let returnSecureToken: Bool 15 | 16 | init(signupProps: SignupProps) { 17 | self.email = signupProps.email 18 | self.password = signupProps.password 19 | self.returnSecureToken = true 20 | } 21 | 22 | init(emailLogin: EmailLogin) { 23 | self.email = emailLogin.email 24 | self.password = emailLogin.password 25 | self.returnSecureToken = true 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataMapping/PushNotificationRequestDTO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PushNotificationRequestDTO.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/12/06. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct PushNotificationRequestDTO: Encodable { 12 | struct Notification: Encodable { 13 | let title: String 14 | let body: String 15 | } 16 | let to: String 17 | let notification: Notification 18 | 19 | init(token: String, title: String, body: String) { 20 | self.to = token 21 | self.notification = .init(title: title, body: body) 22 | } 23 | 24 | init(topic: String, title: String, body: String) { 25 | self.to = "/topics/\(topic)" 26 | self.notification = .init(title: title, body: body) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataMapping/UpdateStudyIDsRequestDTO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UpdateStudyIDsRequestDTO.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/26. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct UpdateStudyIDsRequestDTO: Encodable { 12 | private let chatRoomIDs: ArrayValue 13 | private let studyIDs: ArrayValue 14 | 15 | private enum RootKey: String, CodingKey { 16 | case fields 17 | } 18 | 19 | private enum FieldKeys: String, CodingKey { 20 | case chatRoomIDs, studyIDs 21 | } 22 | 23 | init(chatRoomIDs: [String], studyIDs: [String]) { 24 | self.chatRoomIDs = ArrayValue(values: chatRoomIDs.map { StringValue(value: $0) }) 25 | self.studyIDs = ArrayValue(values: studyIDs.map { StringValue(value: $0) }) 26 | } 27 | 28 | func encode(to encoder: Encoder) throws { 29 | var container = encoder.container(keyedBy: RootKey.self) 30 | var fieldContainer = container.nestedContainer(keyedBy: FieldKeys.self, forKey: .fields) 31 | try fieldContainer.encode(self.chatRoomIDs, forKey: .chatRoomIDs) 32 | try fieldContainer.encode(self.studyIDs, forKey: .studyIDs) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataMapping/UpdateUserIDsRequestDTO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UpdateUserIDsRequestDTO.swift.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/26. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct UpdateUserIDsRequestDTO: Encodable { 12 | private let userIDs: ArrayValue 13 | 14 | private enum RootKey: String, CodingKey { 15 | case fields 16 | } 17 | 18 | private enum FieldKeys: String, CodingKey { 19 | case userIDs 20 | } 21 | 22 | init(userIDs: [String]) { 23 | self.userIDs = ArrayValue(values: userIDs.map { StringValue(value: $0) }) 24 | } 25 | 26 | func encode(to encoder: Encoder) throws { 27 | var container = encoder.container(keyedBy: RootKey.self) 28 | var fieldContainer = container.nestedContainer(keyedBy: FieldKeys.self, forKey: .fields) 29 | try fieldContainer.encode(self.userIDs, forKey: .userIDs) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataSources/Local/HashtagDataSource.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HashtagDataSource.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/17. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | struct HashtagDataSource: HashtagDataSourceProtocol { 14 | 15 | func loadTagList(kind: KindHashtag) -> Observable<[Hashtag]> { 16 | return Observable.create { emitter in 17 | switch kind { 18 | case .language: emitter.onNext(loadLanguage()) 19 | case .career: emitter.onNext(loadCareer()) 20 | case .category: emitter.onNext(loadCategory()) 21 | } 22 | 23 | return Disposables.create() 24 | } 25 | } 26 | 27 | private func loadLanguage() -> [Hashtag] { 28 | return Language.allCases 29 | } 30 | 31 | private func loadCareer() -> [Hashtag] { 32 | return Career.allCases 33 | } 34 | 35 | private func loadCategory() -> [Hashtag] { 36 | return Category.allCases 37 | } 38 | 39 | func loadHashtagByString(kind: KindHashtag, tagTitle: [String]) -> Observable<[Hashtag]> { 40 | return Observable.create { emitter in 41 | let tagList: [Hashtag] 42 | var selectedTags: [Hashtag] = [] 43 | 44 | switch kind { 45 | case .language: tagList = loadLanguage() 46 | case .career: tagList = loadCareer() 47 | case .category: tagList = loadCategory() 48 | } 49 | 50 | tagList.forEach { 51 | if tagTitle.contains($0.id) {selectedTags.append($0)} 52 | } 53 | 54 | emitter.onNext(selectedTags) 55 | return Disposables.create() 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataSources/Local/Keychain.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Keychain.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/29. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Keychain: KeychainProtocol { 12 | 13 | func add(_ query: [String: Any]) -> OSStatus { 14 | return SecItemAdd(query as CFDictionary, nil) 15 | } 16 | 17 | func search(_ query: [String: Any]) -> Data? { 18 | var item: CFTypeRef? 19 | let status = SecItemCopyMatching(query as CFDictionary, &item) 20 | return status == noErr ? (item as? Data) : nil 21 | } 22 | 23 | func update(_ query: [String: Any], with attributes: [String: Any]) -> OSStatus { 24 | return SecItemUpdate(query as CFDictionary, attributes as CFDictionary) 25 | } 26 | 27 | func delete(_ query: [String: Any]) -> OSStatus { 28 | return SecItemDelete(query as CFDictionary) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataSources/Local/ReportDataSource.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ReportDataSource.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/12/06. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | struct ReportDataSource: ReportDataSourceProtocol { 14 | 15 | enum ReportType: String { 16 | case study = "study report" 17 | case user = "user report" 18 | } 19 | 20 | func reportStudy(id: String) -> Observable { 21 | return report(type: .study, id: id) 22 | } 23 | 24 | func reportUser(id: String) -> Observable { 25 | return report(type: .user, id: id) 26 | } 27 | 28 | func loadStudy() -> Observable<[String]> { 29 | return load(type: .study) 30 | } 31 | 32 | func loadUser() -> Observable<[String]> { 33 | return load(type: .user) 34 | } 35 | 36 | // MARK: - Private 37 | 38 | private func report(type: ReportType, id: String) -> Observable { 39 | return Observable.create { emitter in 40 | let list = (UserDefaults.standard.array(forKey: type.rawValue) as? [String]) ?? [] 41 | UserDefaults.standard.set(list + [id], forKey: type.rawValue) 42 | emitter.onNext(()) 43 | return Disposables.create() 44 | } 45 | } 46 | 47 | private func load(type: ReportType) -> Observable<[String]> { 48 | return Observable.create { emitter in 49 | let list = (UserDefaults.standard.array(forKey: type.rawValue) as? [String]) ?? [] 50 | emitter.onNext(list) 51 | return Disposables.create() 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataSources/Protocol/AuthServiceProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AuthServiceProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/16. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol AuthServiceProtocol { 12 | func signup(_ request: EmailAuthorizationRequestDTO) -> Observable 13 | func login(_ request: EmailAuthorizationRequestDTO) -> Observable 14 | } 15 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataSources/Protocol/ChatDataSourceProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatDataSourceProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol ChatDataSourceProtocol { 12 | func fetch(chatRoomID: String) -> Observable<[ChatResponseDTO]> 13 | func observe(chatRoomID: String) -> Observable 14 | func send(request: ChatRequestDTO) -> Observable 15 | func read(chat: Chat) -> Observable 16 | func stopObserving() 17 | } 18 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataSources/Protocol/ChatRoomDataSourceProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatRoomDataSourceProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol ChatRoomDataSourceProtocol { 12 | func list() -> Observable> 13 | func detail(id: String) -> Observable 14 | func chats(id: String) -> Observable> 15 | func create(request: CreateChatRoomRequestDTO) -> Observable 16 | func updateIDs(id: String, request: UpdateUserIDsRequestDTO) -> Observable 17 | } 18 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataSources/Protocol/HashtagDataSourceProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HashtagDataSourceProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/17. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | protocol HashtagDataSourceProtocol { 14 | func loadTagList(kind: KindHashtag) -> Observable<[Hashtag]> 15 | func loadHashtagByString(kind: KindHashtag, tagTitle: [String]) -> Observable<[Hashtag]> 16 | } 17 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataSources/Protocol/KeychainManagerProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeychainManagerProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/29. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol KeychainManagerProtocol { 12 | func save(key: KeychainKey, data: Data) -> Bool 13 | func load(key: KeychainKey) -> Data? 14 | func delete(key: KeychainKey) -> Bool 15 | func update(key: KeychainKey, data: Data) -> Bool 16 | } 17 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataSources/Protocol/KeychainProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeychainProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/29. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol KeychainProtocol { 12 | func add(_ query: [String: Any]) -> OSStatus 13 | func search(_ query: [String: Any]) -> Data? 14 | func update(_ query: [String: Any], with attributes: [String: Any]) -> OSStatus 15 | func delete(_ query: [String: Any]) -> OSStatus 16 | } 17 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataSources/Protocol/PushNotificationServiceProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PushNotificationServiceProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/12/06. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxMogakcoYa 10 | import RxSwift 11 | 12 | protocol PushNotificationServiceProtocol { 13 | // FCM Token을 이용하여 특정 유저에게 푸쉬 알림 전송 14 | func send(request: PushNotificationRequestDTO) -> Observable 15 | // 특정 Topic을 구독하고 있는 유저들에게 푸쉬 알림 전송 16 | func sendTopic(request: PushNotificationRequestDTO) -> Observable 17 | // Topic 구독 18 | func subscribeTopic(topic: String) -> Observable 19 | // Topic 구독 해제 20 | func unsubscribeTopic(topic: String) -> Observable 21 | // 토큰 제거 22 | func deleteToken() -> Observable 23 | } 24 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataSources/Protocol/RemoteUserDataSourceProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RemoteUserDataSourceProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxMogakcoYa 12 | import RxSwift 13 | 14 | protocol RemoteUserDataSourceProtocol { 15 | func allUsers() -> Observable> 16 | func user(id: String) -> Observable 17 | func create(request: UserRequestDTO) -> Observable 18 | func editProfile(id: String, request: EditProfileRequestDTO) -> Observable 19 | func editLanguages(id: String, request: EditLanguagesRequestDTO) -> Observable 20 | func editCareers(id: String, request: EditCareersRequestDTO) -> Observable 21 | func editCategorys(id: String, request: EditCategorysRequestDTO) -> Observable 22 | func uploadProfileImage(id: String, imageData: Data) -> Observable 23 | func updateIDs(id: String, request: UpdateStudyIDsRequestDTO) -> Observable 24 | func delete(_ id: String) -> Observable 25 | } 26 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataSources/Protocol/ReportDataSourceProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ReportDataSourceProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/12/06. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol ReportDataSourceProtocol { 12 | func reportStudy(id: String) -> Observable 13 | func reportUser(id: String) -> Observable 14 | func loadStudy() -> Observable<[String]> 15 | func loadUser() -> Observable<[String]> 16 | } 17 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/DataSources/Protocol/StudyDataSourceProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StudyDataSourceProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/22. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol StudyDataSourceProtocol { 12 | func list() -> Observable> 13 | func detail(id: String) -> Observable 14 | func create(study: StudyRequestDTO) -> Observable 15 | func updateIDs(id: String, request: UpdateUserIDsRequestDTO) -> Observable 16 | } 17 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/Repositories/HashtagRepository.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HashtagRepository.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/17. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | struct HashtagRepository: HashtagRepositoryProtocol { 14 | 15 | var localHashtagDataSource: HashtagDataSourceProtocol? 16 | 17 | func loadTagList(kind: KindHashtag) -> Observable<[Hashtag]> { 18 | return localHashtagDataSource?.loadTagList(kind: kind) ?? .empty() 19 | } 20 | 21 | func loadHashtagByString(kind: KindHashtag, tagTitle: [String]) -> Observable<[Hashtag]> { 22 | return localHashtagDataSource?.loadHashtagByString(kind: kind, tagTitle: tagTitle) ?? .empty() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Mogakco/Sources/Data/Repositories/ReportRepository.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ReportRepository.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/12/06. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | struct ReportRepository: ReportRepositoryProtocol { 12 | 13 | var reportDataSource: ReportDataSourceProtocol? 14 | 15 | func reportStudy(id: String) -> Observable { 16 | return reportDataSource?.reportStudy(id: id) ?? .empty() 17 | } 18 | 19 | func reportUser(id: String) -> Observable { 20 | return reportDataSource?.reportUser(id: id) ?? .empty() 21 | } 22 | 23 | func loadStudy() -> Observable<[String]> { 24 | return reportDataSource?.loadStudy() ?? .empty() 25 | } 26 | 27 | func loadUser() -> Observable<[String]> { 28 | return reportDataSource?.loadUser() ?? .empty() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Entities/Authorization.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Authorization.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/23. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Authorization: Codable { 12 | let idToken: String 13 | let email: String 14 | let refreshToken: String 15 | let expiresIn: String 16 | let localId: String 17 | } 18 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Entities/Chat.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Chat.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Chat: Codable { 12 | let id: String 13 | let userID: String 14 | let message: String 15 | let chatRoomID: String 16 | let date: Int 17 | let readUserIDs: [String] 18 | var user: User? 19 | var isFromCurrentUser: Bool? 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Entities/ChatRoom.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatRoom.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct ChatRoom { 12 | let id: String 13 | let studyID: String? 14 | let userIDs: [String] 15 | let latestChat: Chat? 16 | let unreadChatCount: Int? 17 | let users: [User]? 18 | } 19 | 20 | extension ChatRoom { 21 | init(chatRoom: ChatRoom, latestChat: Chat?, unreadChatCount: Int) { 22 | self.id = chatRoom.id 23 | self.studyID = chatRoom.studyID 24 | self.userIDs = chatRoom.userIDs 25 | self.latestChat = latestChat 26 | self.unreadChatCount = unreadChatCount 27 | self.users = nil 28 | } 29 | 30 | init(chatRoom: ChatRoom, users: [User]) { 31 | self.id = chatRoom.id 32 | self.studyID = chatRoom.studyID 33 | self.userIDs = chatRoom.userIDs 34 | self.latestChat = chatRoom.latestChat 35 | self.unreadChatCount = chatRoom.unreadChatCount 36 | self.users = users 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Entities/EmailLogin.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EmailLogin.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct EmailLogin { 12 | let email: String 13 | let password: String 14 | } 15 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Entities/Profile.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Profile.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/12/01. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | struct Profile { 12 | let name: String 13 | let introduce: String 14 | let image: UIImage 15 | } 16 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Entities/Study.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Study.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/22. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Study { 12 | let id: String 13 | let chatRoomID: String 14 | var userIDs: [String] 15 | let title: String 16 | let content: String 17 | let date: Int 18 | let place: String 19 | let maxUserCount: Int 20 | let languages: [String] 21 | let category: String 22 | } 23 | 24 | extension Study { 25 | init(study: Study, userIDs: [String]) { 26 | self.id = study.id 27 | self.chatRoomID = study.chatRoomID 28 | self.userIDs = userIDs 29 | self.title = study.title 30 | self.content = study.content 31 | self.date = study.date 32 | self.place = study.place 33 | self.maxUserCount = study.maxUserCount 34 | self.languages = study.languages 35 | self.category = study.category 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Entities/StudyFilter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StudyFilter.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/25. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum StudyFilter: Equatable { 12 | case languages([String]) 13 | case category(String) 14 | 15 | static func == (lhs: Self, rhs: Self) -> Bool { 16 | switch (lhs, rhs) { 17 | case (.languages, .languages), (.category, .category): 18 | return true 19 | default: 20 | return false 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Entities/StudySort.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StudySort.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/25. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum StudySort: CaseIterable { 12 | case latest, oldest 13 | 14 | var title: String { 15 | switch self { 16 | case .latest: 17 | return "최신순" 18 | case .oldest: 19 | return "오래된순" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Entities/User.swift: -------------------------------------------------------------------------------- 1 | // 2 | // User.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/16. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | struct User: Codable { 12 | let id: String 13 | let profileImageURLString: String? 14 | let email: String 15 | let introduce: String 16 | let password: String? 17 | let name: String 18 | let languages: [String] 19 | let careers: [String] 20 | let categorys: [String] 21 | let studyIDs: [String] 22 | let chatRoomIDs: [String] 23 | let fcmToken: String? 24 | } 25 | 26 | extension User { 27 | init(id: String, signupProps: SignupProps) { 28 | self.id = id 29 | self.profileImageURLString = nil 30 | self.email = signupProps.email 31 | self.introduce = signupProps.introduce 32 | self.password = nil 33 | self.name = signupProps.name 34 | self.languages = signupProps.languages 35 | self.careers = signupProps.careers 36 | self.categorys = [] 37 | self.studyIDs = [] 38 | self.chatRoomIDs = [] 39 | self.fcmToken = nil 40 | } 41 | 42 | init(profileImageURLString: String, fcmToken: String, user: User) { 43 | self.id = user.id 44 | self.profileImageURLString = profileImageURLString 45 | self.email = user.email 46 | self.introduce = user.introduce 47 | self.password = user.password 48 | self.name = user.name 49 | self.languages = user.languages 50 | self.careers = user.careers 51 | self.categorys = user.categorys 52 | self.studyIDs = user.studyIDs 53 | self.chatRoomIDs = user.chatRoomIDs 54 | self.fcmToken = fcmToken 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Repositories/AuthRepositoryProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AuthRepositoryProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/16. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol AuthRepositoryProtocol { 12 | func signup(signupProps: SignupProps) -> Observable 13 | func login(emailLogin: EmailLogin) -> Observable 14 | } 15 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Repositories/ChatRepositoryProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatRepositoryProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 오국원 on 2022/11/27. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol ChatRepositoryProtocol { 12 | func fetch(chatRoomID: String) -> Observable<[Chat]> 13 | func observe(chatRoomID: String) -> Observable 14 | func send(chat: Chat) -> Observable 15 | func read(chat: Chat) -> Observable 16 | func stopObserving() 17 | } 18 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Repositories/ChatRoomRepositoryProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatRoomRepositoryProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol ChatRoomRepositoryProtocol { 12 | func list(id: String, ids: [String]) -> Observable<[ChatRoom]> 13 | func detail(id: String) -> Observable 14 | func create(studyID: String?, userIDs: [String]) -> Observable 15 | func updateIDs(id: String, userIDs: [String]) -> Observable 16 | func leave(user: User, chatRoom: ChatRoom) -> Observable 17 | func create(currentUserID: String, otherUserID: String) -> Observable 18 | } 19 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Repositories/HashtagRepositoryProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HashtagRepositoryProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/17. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | protocol HashtagRepositoryProtocol { 14 | func loadTagList(kind: KindHashtag) -> Observable<[Hashtag]> 15 | func loadHashtagByString(kind: KindHashtag, tagTitle: [String]) -> Observable<[Hashtag]> 16 | } 17 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Repositories/ReportRepositoryProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ReportRepositoryProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/12/06. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol ReportRepositoryProtocol { 12 | func reportStudy(id: String) -> Observable 13 | func reportUser(id: String) -> Observable 14 | func loadStudy() -> Observable<[String]> 15 | func loadUser() -> Observable<[String]> 16 | } 17 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Repositories/StudyRepositoryProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StudyRepositoryProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/22. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol StudyRepositoryProtocol { 12 | func list(sort: StudySort, filters: [StudyFilter]) -> Observable<[Study]> 13 | func list(ids: [String]) -> Observable<[Study]> 14 | func detail(id: String) -> Observable 15 | func create(user: User, study: Study) -> Observable 16 | func updateIDs(id: String, userIDs: [String]) -> Observable 17 | func join(user: User, id: String) -> Observable 18 | func leaveStudy(user: User, id: String) -> Observable 19 | } 20 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Repositories/TokenRepositoryProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AutoLoginRepositoryProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/29. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol TokenRepositoryProtocol { 12 | func save(_ auth: Authorization) -> Observable 13 | func load() -> Observable 14 | func delete() -> Observable 15 | } 16 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/Repositories/UserRepositoryProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserRepositoryProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/16. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | protocol UserRepositoryProtocol { 14 | func user(id: String) -> Observable 15 | func allUsers() -> Observable<[User]> 16 | func load() -> Observable 17 | func create(user: User, imageData: Data) -> Observable 18 | func delete(id: String) -> Observable 19 | func editProfile(id: String, name: String, introduce: String, imageData: Data) -> Observable 20 | func editLanguages(id: String, languages: [String]) -> Observable 21 | func editCareers(id: String, careers: [String]) -> Observable 22 | func editCategorys(id: String, categorys: [String]) -> Observable 23 | func updateIDs(id: String, chatRoomIDs: [String], studyIDs: [String]) -> Observable 24 | } 25 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/AutoLoginUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AutoLoginUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/29. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | struct AutoLoginUseCase: AutoLoginUseCaseProtocol { 12 | 13 | var tokenRepository: TokenRepositoryProtocol? 14 | private let disposeBag = DisposeBag() 15 | 16 | func load() -> Observable { 17 | return tokenRepository?.load() ?? .empty() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/ChatRoomListUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatRoomListUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | struct ChatRoomListUseCase: ChatRoomListUseCaseProtocol { 14 | 15 | enum ChatRoomListUseCaseError: Error, LocalizedError { 16 | case nonUserID 17 | } 18 | 19 | var chatRoomRepository: ChatRoomRepositoryProtocol? 20 | var userRepository: UserRepositoryProtocol? 21 | private let disposeBag = DisposeBag() 22 | 23 | func chatRooms() -> Observable<[ChatRoom]> { 24 | let user = userRepository?.load() ?? .empty() 25 | return user 26 | .flatMap { chatRoomRepository?.list(id: $0.id, ids: $0.chatRoomIDs) ?? .empty() } 27 | .withLatestFrom(user) { chatRooms, user in 28 | return chatRooms.map { chatRoom in 29 | ChatRoom(chatRoom: chatRoom, users: chatRoom.users?.filter { $0.id != user.id } ?? []) 30 | } 31 | } 32 | } 33 | 34 | func leave(chatRoom: ChatRoom) -> Observable { 35 | return (userRepository?.load() ?? .empty()) 36 | .flatMap { chatRoomRepository?.leave(user: $0, chatRoom: chatRoom) ?? .empty() } 37 | .map { _ in () } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/CreateChatRoomUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CreateChatRoomUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/30. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | struct CreateChatRoomUseCase: CreateChatRoomUseCaseProtocol { 14 | 15 | var chatRoomRepository: ChatRoomRepositoryProtocol? 16 | var userRepository: UserRepositoryProtocol? 17 | private let disposeBag = DisposeBag() 18 | 19 | func create(otherUser: User) -> Observable { 20 | return userRepository?.load() 21 | .flatMap { chatRoomRepository?.create(currentUserID: $0.id, otherUserID: otherUser.id) ?? .empty() } ?? .empty() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/CreateStudyUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CreateStudyUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/23. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | struct CreateStudyUseCase: CreateStudyUseCaseProtocol { 14 | 15 | var studyRepository: StudyRepositoryProtocol? 16 | var userRepository: UserRepositoryProtocol? 17 | private let disposeBag = DisposeBag() 18 | 19 | func create(study: Study) -> Observable { 20 | return (userRepository?.load() ?? .empty()) 21 | .flatMap { studyRepository?.create(user: $0, study: study) ?? .empty() } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/HashtagUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HashtagUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/17. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | struct HashtagUseCase: HashtagUseCaseProtocol { 14 | 15 | var hashtagRepository: HashtagRepositoryProtocol? 16 | 17 | func loadTagList(kind: KindHashtag) -> Observable<[Hashtag]> { 18 | return hashtagRepository?.loadTagList(kind: kind) ?? .empty() 19 | } 20 | 21 | func loadHashtagByString(kind: KindHashtag, tagTitle: [String]) -> Observable<[Hashtag]> { 22 | return hashtagRepository?.loadHashtagByString(kind: kind, tagTitle: tagTitle) ?? .empty() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/JoinStudyUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JoinStudyUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/28. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | struct JoinStudyUseCase: JoinStudyUseCaseProtocol { 14 | 15 | enum JoinStudyUseCaseError: Error, LocalizedError { 16 | case max 17 | } 18 | 19 | var studyRepository: StudyRepositoryProtocol? 20 | var userRepository: UserRepositoryProtocol? 21 | private let disposeBag = DisposeBag() 22 | 23 | func join(id: String) -> Observable { 24 | return (userRepository?.load() ?? .empty()) 25 | .flatMap { studyRepository?.join(user: $0, id: id) ?? .empty() } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/LeaveStudyUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LeaveStudyUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/29. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | struct LeaveStudyUseCase: LeaveStudyUseCaseProtocol { 14 | var studyRepository: StudyRepositoryProtocol? 15 | var userRepository: UserRepositoryProtocol? 16 | 17 | var disposeBag = DisposeBag() 18 | 19 | func leaveStudy(id: String) -> Observable { 20 | return (userRepository?.load() ?? .empty()) 21 | .flatMap { studyRepository?.leaveStudy(user: $0, id: id) ?? .empty() } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/LoginUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LoginUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | struct LoginUseCase: LoginUseCaseProtocol { 14 | 15 | var authRepository: AuthRepositoryProtocol? 16 | var userRepository: UserRepositoryProtocol? 17 | var tokenRepository: TokenRepositoryProtocol? 18 | private let disposeBag = DisposeBag() 19 | 20 | func login(emailLogin: EmailLogin) -> Observable { 21 | return (authRepository?.login(emailLogin: emailLogin) ?? .empty()) 22 | .flatMap { tokenRepository?.save($0) ?? .empty() } 23 | .map { _ in () } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/LogoutUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LogoutUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 오국원 on 2022/12/07. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | struct LogoutUseCase: LogoutUseCaseProtocol { 14 | 15 | var tokenRepository: TokenRepositoryProtocol? 16 | var pushNotificationService: PushNotificationServiceProtocol? 17 | private let disposeBag = DisposeBag() 18 | 19 | func logout() -> Observable { 20 | return tokenRepository?.delete() 21 | .flatMap { _ in pushNotificationService?.deleteToken() ?? .empty() } ?? .empty() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/ProfileUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | struct ProfileUseCase: ProfileUseCaseProtocol { 12 | 13 | var userRepository: UserRepositoryProtocol? 14 | private let disposeBag = DisposeBag() 15 | 16 | func profile() -> Observable { 17 | return (userRepository?.load() ?? .empty()) 18 | .compactMap { $0.id } 19 | .flatMap { userRepository?.user(id: $0) ?? .empty() } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/AutoLoginUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AutoLoginUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/29. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol AutoLoginUseCaseProtocol { 12 | func load() -> Observable 13 | } 14 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/ChatRoomListUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatRoomListUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol ChatRoomListUseCaseProtocol { 12 | func chatRooms() -> Observable<[ChatRoom]> 13 | func leave(chatRoom: ChatRoom) -> Observable 14 | } 15 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/ChatUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 오국원 on 2022/11/27. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol ChatUseCaseProtocol { 12 | func fetch(chatRoomID: String) -> Observable<[Chat]> 13 | func observe(chatRoomID: String) -> Observable 14 | func send(chat: Chat) -> Observable 15 | func read(chat: Chat, userID: String) -> Observable 16 | func stopObserving() 17 | func myProfile() -> Observable 18 | } 19 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/CreateChatRoomUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CreateChatRoomUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/30. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | protocol CreateChatRoomUseCaseProtocol { 14 | func create(otherUser: User) -> Observable 15 | } 16 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/CreateStudyUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CreateStudyUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/23. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol CreateStudyUseCaseProtocol { 12 | func create(study: Study) -> Observable 13 | } 14 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/EditProfileUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditProfileUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/22. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | import RxSwift 12 | 13 | protocol EditProfileUseCaseProtocol { 14 | func editProfile(name: String, introduce: String, image: UIImage) -> Observable 15 | func editLanguages(languages: [String]) -> Observable 16 | func editCareers(careers: [String]) -> Observable 17 | func editCategorys(categorys: [String]) -> Observable 18 | } 19 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/HashtagUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HashtagUsecaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/17. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | protocol HashtagUseCaseProtocol { 14 | func loadTagList(kind: KindHashtag) -> Observable<[Hashtag]> 15 | func loadHashtagByString(kind: KindHashtag, tagTitle: [String]) -> Observable<[Hashtag]> 16 | } 17 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/JoinStudyUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JoinStudyUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/28. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol JoinStudyUseCaseProtocol { 12 | func join(id: String) -> Observable 13 | } 14 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/LeaveStudyUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LeaveStudyUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/29. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | protocol LeaveStudyUseCaseProtocol { 14 | func leaveStudy(id: String) -> Observable 15 | } 16 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/LoginUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LoginUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | protocol LoginUseCaseProtocol { 14 | func login(emailLogin: EmailLogin) -> Observable 15 | } 16 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/LogoutUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LogoutUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 오국원 on 2022/12/07. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | protocol LogoutUseCaseProtocol { 14 | func logout() -> Observable 15 | } 16 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/ProfileUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol ProfileUseCaseProtocol { 12 | func profile() -> Observable 13 | } 14 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/ReportUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ReportUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/12/06. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol ReportUseCaseProtocol { 12 | func reportStudy(id: String) -> Observable 13 | func reportUser(id: String) -> Observable 14 | } 15 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/SignupUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SignupUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol SignupUseCaseProtocol { 12 | func signup(signupProps: SignupProps) -> Observable 13 | } 14 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/StudyDetailUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StudyDetailUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/23. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol StudyDetailUseCaseProtocol { 12 | func study(id: String) -> Observable 13 | } 14 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/StudyListUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StudyListUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/22. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol StudyListUseCaseProtocol { 12 | func list(sort: StudySort, filters: [StudyFilter]) -> Observable<[Study]> 13 | } 14 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/SubscribePushNotificationUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SubscribePushNotificationUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/12/07. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol SubscribePushNotificationUseCaseProtocol { 12 | func excute(topic: String) -> Observable 13 | } 14 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/UnsubscribePushNotificationUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UnsubscribePushNotificationUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/12/07. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol UnsubscribePushNotificationUseCaseProtocol { 12 | func excute(topic: String) -> Observable 13 | } 14 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/UserUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | protocol UserUseCaseProtocol { 12 | func user(id: String) -> Observable 13 | func users(ids: [String]) -> Observable<[User]> 14 | func myProfile() -> Observable 15 | func studyRatingList(studyIDs: [String]) -> Observable<[(String, Int)]> 16 | } 17 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/Protocol/WithdrawUseCaseProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WithdrawUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 오국원 on 2022/12/05. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | protocol WithdrawUseCaseProtocol { 14 | func excute() -> Observable 15 | } 16 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/ReportUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ReportStudyUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/12/06. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | struct ReportUseCase: ReportUseCaseProtocol { 12 | 13 | var reportRepository: ReportRepositoryProtocol? 14 | 15 | func reportStudy(id: String) -> Observable { 16 | return reportRepository?.reportStudy(id: id) ?? .empty() 17 | } 18 | 19 | func reportUser(id: String) -> Observable { 20 | return reportRepository?.reportUser(id: id) ?? .empty() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/SignupUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SignupUseCaseProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/16. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | struct SignupUseCase: SignupUseCaseProtocol { 14 | 15 | enum SignupUseCaseError: Error, LocalizedError { 16 | case imageCompress 17 | } 18 | 19 | var authRepository: AuthRepositoryProtocol? 20 | var userRepository: UserRepositoryProtocol? 21 | var tokenRepository: TokenRepositoryProtocol? 22 | private let disposeBag = DisposeBag() 23 | 24 | func signup(signupProps: SignupProps) -> Observable { 25 | guard let imageData = signupProps.profileImage.jpegData(compressionQuality: 0.5) else { 26 | return Observable.error(SignupUseCaseError.imageCompress) 27 | } 28 | return (authRepository?.signup(signupProps: signupProps) ?? .empty()) 29 | .flatMap { tokenRepository?.save($0) ?? .empty() } 30 | .compactMap { $0 } 31 | .map { $0.localId } 32 | .map { User(id: $0, signupProps: signupProps) } 33 | .flatMap { userRepository?.create(user: $0, imageData: imageData) ?? .empty() } 34 | .map { _ in () } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/StudyDetailUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StudyDetailUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/23. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | struct StudyDetailUseCase: StudyDetailUseCaseProtocol { 12 | 13 | var studyRepository: StudyRepositoryProtocol? 14 | 15 | func study(id: String) -> Observable { 16 | return studyRepository?.detail(id: id) ?? .empty() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/StudyListUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StudyListUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/22. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | struct StudyListUseCase: StudyListUseCaseProtocol { 12 | 13 | var studyRepository: StudyRepositoryProtocol? 14 | 15 | func list(sort: StudySort, filters: [StudyFilter]) -> Observable<[Study]> { 16 | return studyRepository?.list(sort: sort, filters: filters) ?? .empty() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/SubscribePushNotificationUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SubscribePushNotificationUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/12/07. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | struct SubscribePushNotificationUseCase: SubscribePushNotificationUseCaseProtocol { 12 | 13 | var pushNotificationService: PushNotificationServiceProtocol? 14 | 15 | func excute(topic: String) -> Observable { 16 | return pushNotificationService?.subscribeTopic(topic: topic) ?? .empty() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/UnsubscribePushNotificationUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UnsubscribePushNotificationUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/12/07. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | struct UnsubscribePushNotificationUseCase: UnsubscribePushNotificationUseCaseProtocol { 12 | 13 | var pushNotificationService: PushNotificationServiceProtocol? 14 | 15 | func excute(topic: String) -> Observable { 16 | return pushNotificationService?.unsubscribeTopic(topic: topic) ?? .empty() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/UserUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | struct UserUseCase: UserUseCaseProtocol { 12 | 13 | var userRepository: UserRepositoryProtocol? 14 | var studyRepository: StudyRepositoryProtocol? 15 | private let disposeBag = DisposeBag() 16 | 17 | func user(id: String) -> Observable { 18 | return userRepository?.user(id: id) ?? .empty() 19 | } 20 | 21 | func users(ids: [String]) -> Observable<[User]> { 22 | return userRepository?.allUsers() 23 | .flatMap { 24 | var filteredUser: [User] = [] 25 | $0.forEach { user in 26 | if ids.contains(user.id) { filteredUser.append(user) } 27 | } 28 | return Observable.just(filteredUser) 29 | } ?? .empty() 30 | } 31 | 32 | func myProfile() -> Observable { 33 | return (userRepository?.load() ?? .empty()) 34 | .map { $0.id } 35 | .flatMap { userRepository?.user(id: $0) ?? .empty() } 36 | } 37 | 38 | func studyRatingList(studyIDs: [String]) -> Observable<[(String, Int)]> { 39 | return (studyRepository?.list(ids: studyIDs) ?? .empty()) 40 | .map { $0.map { $0.category } } 41 | .map { $0.countDictionary } 42 | .map { $0.sorted { 43 | if $0.value != $1.value { 44 | return $0.value < $1.value 45 | } else { 46 | return $0.key < $1.key 47 | } 48 | }.map { 49 | ($0.key, $0.value) } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Mogakco/Sources/Domain/UseCases/WithdrawUseCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WithdrawUseCase.swift 3 | // Mogakco 4 | // 5 | // Created by 오국원 on 2022/12/05. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxSwift 12 | 13 | struct WithdrawUseCase: WithdrawUseCaseProtocol { 14 | 15 | var userRepository: UserRepositoryProtocol? 16 | var tokenRepository: TokenRepositoryProtocol? 17 | var studyRepository: StudyRepositoryProtocol? 18 | var pushNotificationService: PushNotificationServiceProtocol? 19 | private let disposeBag = DisposeBag() 20 | 21 | func excute() -> Observable { 22 | return userRepository?.load() 23 | .flatMap { user in 24 | let observe: [Observable] = user.studyIDs.map { 25 | studyRepository?.leaveStudy(user: user, id: $0) ?? .empty() 26 | } 27 | return Observable 28 | .combineLatest(observe) 29 | .map { _ in return user } 30 | } 31 | .flatMap { userRepository?.delete(id: $0.id) ?? .empty() } 32 | .flatMap { tokenRepository?.delete() ?? .empty() } 33 | .flatMap { _ in pushNotificationService?.deleteToken() ?? .empty() } 34 | .map { _ in } ?? .empty() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Chat/View/ChatSidebarTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatSidebarTableViewCell.swift 3 | // Mogakco 4 | // 5 | // Created by 오국원 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | import SnapKit 12 | import Then 13 | 14 | final class ChatSidebarTableViewCell: UITableViewCell, Identifiable { 15 | 16 | static let cellHeight = 60.0 17 | 18 | var menuLabel = UILabel().then { 19 | $0.textAlignment = .left 20 | $0.font = .mogakcoFont.mediumRegular 21 | $0.textColor = .mogakcoColor.typographyPrimary 22 | } 23 | 24 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { 25 | super.init(style: style, reuseIdentifier: reuseIdentifier) 26 | layout() 27 | } 28 | 29 | required init?(coder: NSCoder) { 30 | fatalError("init(coder:) has not been implemented") 31 | } 32 | 33 | private func layout() { 34 | layoutSelf() 35 | layoutMenuLabel() 36 | } 37 | 38 | private func layoutSelf() { 39 | selectionStyle = .none 40 | } 41 | 42 | private func layoutMenuLabel() { 43 | addSubview(menuLabel) 44 | 45 | menuLabel.snp.makeConstraints { 46 | $0.top.left.bottom.right.equalToSuperview().inset(5) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Common/Coordinator/AppCoordinator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppCoordinator.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/12/01. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | import RxSwift 12 | 13 | final class AppCoordinator: BaseCoordinator { 14 | 15 | let window: UIWindow? 16 | 17 | init(_ window: UIWindow?) { 18 | self.window = window 19 | super.init(UINavigationController()) 20 | } 21 | 22 | private func setup(with window: UIWindow?) { 23 | window?.rootViewController = navigationController 24 | window?.makeKeyAndVisible() 25 | window?.backgroundColor = .mogakcoColor.backgroundDefault 26 | } 27 | 28 | override func start() -> Observable { 29 | setup(with: window) 30 | showLogin() 31 | return Observable.never() 32 | } 33 | 34 | private func showLogin() { 35 | navigationController.setNavigationBarHidden(true, animated: true) 36 | let login = LoginCoordinator(navigationController) 37 | coordinate(to: login) 38 | .subscribe(onNext: { [weak self] in 39 | switch $0 { 40 | case .finish: 41 | self?.showTab() 42 | } 43 | }) 44 | .disposed(by: disposeBag) 45 | } 46 | 47 | private func showTab() { 48 | navigationController.setNavigationBarHidden(true, animated: true) 49 | let tab = TabCoordinator(navigationController) 50 | coordinate(to: tab) 51 | .subscribe(onNext: { [weak self] in 52 | switch $0 { 53 | case .finish: 54 | self?.showLogin() 55 | } 56 | }) 57 | .disposed(by: disposeBag) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Common/Coordinator/HashtagCoordinator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HashtagCoordinator.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/12/03. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | import RxSwift 12 | 13 | enum HashtagCoordinatorResult { 14 | case finish([Hashtag]) 15 | } 16 | 17 | final class HashtagCoordinator: BaseCoordinator { 18 | 19 | private let kind: KindHashtag 20 | private let selectedHashtag: [Hashtag] 21 | private let finish = PublishSubject() 22 | 23 | init( 24 | kind: KindHashtag, 25 | selectedHashtag: [Hashtag], 26 | _ navigationController: UINavigationController 27 | ) { 28 | self.kind = kind 29 | self.selectedHashtag = selectedHashtag 30 | super.init(navigationController) 31 | } 32 | 33 | override func start() -> Observable { 34 | showHashtag() 35 | return finish 36 | .do(onNext: { [weak self] _ in self?.popTabbar(animated: true) }) 37 | } 38 | 39 | func showHashtag() { 40 | guard let viewModel = DIContainer.shared.container.resolve(HashtagFilterViewModel.self) else { return } 41 | viewModel.selectedHashtags = selectedHashtag 42 | 43 | viewModel.finish 44 | .map { HashtagCoordinatorResult.finish($0) } 45 | .bind(to: finish) 46 | .disposed(by: disposeBag) 47 | 48 | let viewController = HashtagSelectViewController( 49 | kind: kind, 50 | viewModel: viewModel 51 | ) 52 | 53 | pushTabbar(viewController, animated: true) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Common/Protocol/Identifiable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Identifiable.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/14. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol Identifiable { 11 | static var identifier: String { get } 12 | } 13 | 14 | extension Identifiable { 15 | static var identifier: String { return "\(self)" } 16 | } 17 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Common/Protocol/ViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewModel.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/14. 6 | // 7 | 8 | import Foundation 9 | import RxSwift 10 | 11 | protocol ViewModel { 12 | associatedtype Input 13 | associatedtype Output 14 | 15 | var disposeBag: DisposeBag { get set } 16 | func transform(input: Input) -> Output 17 | } 18 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Common/Skeleton/Extension/UIColor+SkeletonColor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+SkeletonColor.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/12/08. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIColor { 12 | static let backColor = UIColor.mogakcoColor.primaryThird 13 | static let baseColor = UIColor.mogakcoColor.primarySecondary 14 | static let pointColor = UIColor.mogakcoColor.primaryDefault 15 | } 16 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Common/Skeleton/Extension/UIView+Animation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Animation.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/12/08. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIView { 12 | func loadinAnimation() { 13 | let gradient = CAGradientLayer() 14 | let colors = [UIColor.baseColor, UIColor.pointColor, UIColor.pointColor, UIColor.baseColor] 15 | gradient.frame = self.bounds 16 | gradient.startPoint = CGPoint(x: 0.0, y: 0.5) 17 | gradient.endPoint = CGPoint(x: 1.0, y: 0.5) 18 | gradient.colors = colors.map { $0?.cgColor ?? UIColor.clear.cgColor } 19 | gradient.locations = [0, 0.2, 0.8, 1.0] 20 | layer.addSublayer(gradient) 21 | 22 | let animation = CABasicAnimation(keyPath: "locations") 23 | animation.fromValue = [-1.0, -0.7, -0.3, 0.0] 24 | animation.toValue = [1.0, 1.3, 1.7, 2.0] 25 | animation.repeatCount = .infinity 26 | animation.duration = 1.5 27 | animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) 28 | gradient.add(animation, forKey: animation.keyPath) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Common/Skeleton/View/ChatRoom/ChatRoomListSkeletonView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ListSkeletonView.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/12/08. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | import RxSwift 12 | import RxCocoa 13 | import SnapKit 14 | import Then 15 | 16 | final class ChatRoomListSkeletonView: UIView { 17 | 18 | override init(frame: CGRect) { 19 | super.init(frame: frame) 20 | layout() 21 | } 22 | 23 | required init?(coder: NSCoder) { 24 | fatalError("init(coder:) has not been implemented") 25 | } 26 | 27 | private func layout() { 28 | let cellCount = Int(frame.height / (frame.width / 6)) 29 | let stackView = UIStackView().then { 30 | $0.spacing = 20 31 | $0.axis = .vertical 32 | } 33 | addSubview(stackView) 34 | 35 | (0.. [UICollectionViewLayoutAttributes]? { 26 | guard let attributes = super.layoutAttributesForElements(in: rect) else { return [] } 27 | 28 | for (index, value) in attributes.enumerated() where attributes[index].representedElementCategory == .cell { 29 | if value.frame.origin.x == 0 { continue } 30 | value.frame.origin.x = attributes[index - 1].frame.maxX + minimumInteritemSpacing 31 | } 32 | return attributes 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Hashtag/Protocol/HashtagProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Hashtag.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/22. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol Hashtag { 12 | var id: String { get } 13 | var title: String { get } 14 | var image: UIImage { get } 15 | 16 | static func idToHashtag(id: String) -> Hashtag? 17 | } 18 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Hashtag/Protocol/HashtagSelectProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HashtagSelectProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/22. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol HashtagSelectProtocol: AnyObject { 12 | func selectedHashtag(kind: KindHashtag, hashTags: [Hashtag]) 13 | } 14 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Hashtag/ViewModel/HashtagEditViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HashtagEditViewModel.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/17. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | import RxSwift 12 | import RxCocoa 13 | 14 | class HashtagEditViewModel: HashtagViewModel { 15 | 16 | var editProfileUseCase: EditProfileUseCaseProtocol? 17 | let finish = PublishSubject() 18 | 19 | override func transform(input: Input) -> Output { 20 | 21 | input.nextButtonTapped 22 | .subscribe(onNext: { [weak self] in 23 | self?.tapButton() 24 | }) 25 | .disposed(by: disposeBag) 26 | 27 | input.backButtonTapped 28 | .subscribe(onNext: { [weak self] in 29 | self?.finish.onNext(()) 30 | }) 31 | .disposed(by: disposeBag) 32 | 33 | return super.transform(input: input) 34 | } 35 | 36 | private func tapButton() { 37 | let hashtagTitles = selectedHashtags.map { $0.id } 38 | let changeProfile: Observable 39 | 40 | switch kind { 41 | case .language: changeProfile = editProfileUseCase?.editLanguages(languages: hashtagTitles) ?? .empty() 42 | case .career: changeProfile = editProfileUseCase?.editCareers(careers: hashtagTitles) ?? .empty() 43 | case .category: changeProfile = editProfileUseCase?.editCategorys(categorys: hashtagTitles) ?? .empty() 44 | } 45 | 46 | changeProfile 47 | .subscribe(onNext: { [weak self] in 48 | self?.finish.onNext(()) 49 | }) 50 | .disposed(by: disposeBag) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Hashtag/ViewModel/HashtagFilterViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HashtagFilterViewModel.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/22. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | import RxSwift 12 | import RxCocoa 13 | 14 | class HashtagFilterViewModel: HashtagViewModel { 15 | 16 | let finish = PublishSubject<[Hashtag]>() 17 | 18 | override func transform(input: Input) -> Output { 19 | 20 | input.nextButtonTapped 21 | .subscribe(onNext: { [weak self] in 22 | let selectedHashtag = self?.selectedHashtags ?? [] 23 | self?.finish.onNext(selectedHashtag) 24 | }) 25 | .disposed(by: disposeBag) 26 | 27 | input.backButtonTapped 28 | .subscribe(onNext: { [weak self] in 29 | self?.finish.onNext([]) 30 | }) 31 | .disposed(by: disposeBag) 32 | 33 | return super.transform(input: input) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Setting/View/SettingTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SettingTableViewCell.swift 3 | // Mogakco 4 | // 5 | // Created by 오국원 on 2022/12/05. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | import RxCocoa 12 | import RxSwift 13 | import SnapKit 14 | import Then 15 | 16 | final class SettingTableViewCell: UITableViewCell, Identifiable { 17 | 18 | enum Constant { 19 | static let cellHeight = 60.0 20 | } 21 | 22 | let titleLabel = UILabel().then { 23 | $0.textAlignment = .left 24 | $0.font = UIFont.mogakcoFont.mediumBold 25 | $0.textColor = .mogakcoColor.typographyPrimary 26 | } 27 | 28 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { 29 | super.init(style: style, reuseIdentifier: reuseIdentifier) 30 | layout() 31 | } 32 | 33 | override func layoutSubviews() { 34 | super.layoutSubviews() 35 | 36 | contentView.frame = contentView.frame.inset(by: UIEdgeInsets(top: 8.0, left: 0, bottom: 8.0, right: 0)) 37 | } 38 | 39 | 40 | required init?(coder: NSCoder) { 41 | fatalError("init(coder:) has not been implemented") 42 | } 43 | 44 | private func layout() { 45 | layoutCell() 46 | layoutTitleLabel() 47 | } 48 | 49 | private func layoutCell() { 50 | selectionStyle = .none 51 | backgroundColor = .mogakcoColor.backgroundDefault 52 | } 53 | 54 | private func layoutTitleLabel() { 55 | addSubview(titleLabel) 56 | 57 | titleLabel.snp.makeConstraints { 58 | $0.left.equalToSuperview().offset(16) 59 | $0.centerY.equalToSuperview() 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Signup/Model/EmailProps.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EmailProps.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/23. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct EmailProps { 12 | let email: String 13 | 14 | func toPasswordProps(password: String) -> PasswordProps { 15 | return PasswordProps( 16 | email: email, 17 | password: password 18 | ) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Signup/Model/LanguageProps.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LanguageProps.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/23. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | struct LanguageProps { 12 | let email: String 13 | let password: String 14 | let name: String 15 | let introduce: String 16 | let profileImage: UIImage 17 | let languages: [String] 18 | 19 | func toSignupProps(careers: [String]) -> SignupProps { 20 | return SignupProps( 21 | email: email, 22 | password: password, 23 | name: name, 24 | introduce: introduce, 25 | profileImage: profileImage, 26 | languages: languages, 27 | careers: careers 28 | ) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Signup/Model/PasswordProps.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordProps.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/23. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | struct PasswordProps { 12 | let email: String 13 | let password: String 14 | 15 | func toProfileProps(profile: Profile) -> ProfileProps { 16 | return ProfileProps( 17 | email: email, 18 | password: password, 19 | name: profile.name, 20 | introduce: profile.introduce, 21 | profileImage: profile.image 22 | ) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Signup/Model/ProfileProps.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileProps.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/23. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | struct ProfileProps { 12 | let email: String 13 | let password: String 14 | let name: String 15 | let introduce: String 16 | let profileImage: UIImage 17 | 18 | func toLanguageProps(languages: [String]) -> LanguageProps { 19 | return LanguageProps( 20 | email: email, 21 | password: password, 22 | name: name, 23 | introduce: introduce, 24 | profileImage: profileImage, 25 | languages: languages 26 | ) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Signup/Model/SignupProps.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SignupProps.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/24. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | struct SignupProps { 12 | let email: String 13 | let password: String 14 | let name: String 15 | let introduce: String 16 | let profileImage: UIImage 17 | let languages: [String] 18 | let careers: [String] 19 | } 20 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Signup/ViewModel/PolicyViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PolicyViewModel.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/12/08. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import RxCocoa 12 | import RxSwift 13 | 14 | enum PolicyNavigation { 15 | case next 16 | case back 17 | } 18 | 19 | final class PolicyViewModel: ViewModel { 20 | 21 | struct Input { 22 | let totalPolicy: Observable 23 | let servicePolicy: Observable 24 | let contentPolicy: Observable 25 | let nextButtonTapped: Observable 26 | let backButtonTapped: Observable 27 | } 28 | 29 | struct Output { 30 | let nextButtonEnabled: Signal 31 | } 32 | 33 | let navigation = PublishSubject() 34 | var disposeBag = DisposeBag() 35 | 36 | func transform(input: Input) -> Output { 37 | let nextButtonEnabled = PublishSubject() 38 | 39 | input.totalPolicy 40 | .bind(to: nextButtonEnabled) 41 | .disposed(by: disposeBag) 42 | 43 | Observable.combineLatest(input.servicePolicy, input.contentPolicy) 44 | .map { $0 == true && $1 == true } 45 | .bind(to: nextButtonEnabled) 46 | .disposed(by: disposeBag) 47 | 48 | input.nextButtonTapped 49 | .map { .next } 50 | .bind(to: navigation) 51 | .disposed(by: disposeBag) 52 | 53 | input.backButtonTapped 54 | .map { .back } 55 | .bind(to: navigation) 56 | .disposed(by: disposeBag) 57 | 58 | return Output(nextButtonEnabled: nextButtonEnabled.asSignal(onErrorJustReturn: false)) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Study/View/StudyInfoView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StudyInfoView.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/14. 6 | // 7 | 8 | import UIKit 9 | 10 | import SnapKit 11 | import Then 12 | 13 | final class StudyInfoView: UIView { 14 | 15 | let imageView = UIImageView().then { 16 | $0.tintColor = .mogakcoColor.typographySecondary 17 | $0.contentMode = .scaleAspectFit 18 | } 19 | 20 | let textLabel = UILabel().then { 21 | $0.textColor = .mogakcoColor.typographySecondary 22 | $0.font = .mogakcoFont.smallRegular 23 | } 24 | 25 | convenience init(image: UIImage?, text: String) { 26 | self.init(frame: .zero) 27 | imageView.image = image 28 | textLabel.text = text 29 | } 30 | 31 | override init(frame: CGRect) { 32 | super.init(frame: frame) 33 | layout() 34 | } 35 | 36 | required init?(coder: NSCoder) { 37 | fatalError("init(coder:) has not been implemented") 38 | } 39 | 40 | private func layout() { 41 | addSubViews([imageView, textLabel]) 42 | 43 | imageView.snp.makeConstraints { 44 | $0.top.leading.bottom.equalToSuperview() 45 | $0.width.height.equalTo(15) 46 | } 47 | 48 | textLabel.snp.makeConstraints { 49 | $0.leading.equalTo(imageView.snp.trailing).offset(10) 50 | $0.top.trailing.bottom.equalToSuperview() 51 | $0.height.equalTo(15) 52 | } 53 | } 54 | 55 | func setInfo(image: UIImage?, text: String) { 56 | imageView.image = image 57 | textLabel.text = text 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Study/View/StudySortCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StudySortCell.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/29. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | import SnapKit 12 | import Then 13 | 14 | final class StudySortCell: UICollectionViewCell, Identifiable { 15 | 16 | private let titleLabel = UILabel().then { 17 | $0.font = UIFont(name: SFPro.regular.rawValue, size: 13) 18 | $0.textColor = .mogakcoColor.typographyPrimary 19 | $0.textAlignment = .center 20 | } 21 | 22 | override init(frame: CGRect) { 23 | super.init(frame: frame) 24 | layout() 25 | attribute() 26 | } 27 | 28 | required init?(coder: NSCoder) { 29 | fatalError("init(coder:) has not been implemented") 30 | } 31 | 32 | // MARK: - Methods 33 | 34 | func configure(studySort: StudySort) { 35 | titleLabel.text = studySort.title 36 | } 37 | 38 | private func layout() { 39 | addSubview(titleLabel) 40 | titleLabel.snp.makeConstraints { 41 | $0.edges.equalToSuperview().inset(8.0) 42 | } 43 | } 44 | 45 | private func attribute() { 46 | layer.borderWidth = 0.2 47 | layer.borderColor = UIColor.mogakcoColor.primarySecondary?.cgColor 48 | layer.cornerRadius = 8.0 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Study/View/StudyTitleLabel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StudyTitleLabel.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/14. 6 | // 7 | 8 | import UIKit 9 | 10 | import SnapKit 11 | import Then 12 | 13 | final class StudyTitleLabel: UILabel { 14 | 15 | convenience init(title: String) { 16 | self.init(frame: .zero) 17 | text = title 18 | } 19 | 20 | override init(frame: CGRect) { 21 | super.init(frame: frame) 22 | layout() 23 | } 24 | 25 | required init?(coder: NSCoder) { 26 | fatalError("init(coder:) has not been implemented") 27 | } 28 | 29 | func layout() { 30 | textColor = .mogakcoColor.typographyPrimary 31 | font = UIFont.mogakcoFont.mediumBold 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Mogakco/Sources/Presentation/Study/ViewModel/SelectStudySortViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SelectStudySortViewModel.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/29. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxCocoa 10 | import RxSwift 11 | 12 | final class SelectStudySortViewModel: ViewModel { 13 | 14 | struct Input { 15 | let selectedStudySort: Observable 16 | } 17 | 18 | struct Output { 19 | let studySorts: Driver<[StudySort]> 20 | } 21 | 22 | var sortObserver: AnyObserver? 23 | let finish = PublishSubject() 24 | var disposeBag = DisposeBag() 25 | 26 | func transform(input: Input) -> Output { 27 | input.selectedStudySort 28 | .subscribe(onNext: { [weak self] in 29 | self?.sortObserver?.onNext($0) 30 | self?.finish.onNext(()) 31 | }) 32 | .disposed(by: disposeBag) 33 | 34 | return Output( 35 | studySorts: Driver.just(StudySort.allCases) 36 | ) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Constant/Format.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Format.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/23. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum Format { 12 | static let chatDateFormat: String = "yyyyMMddHHmmss" 13 | static let compactDateFormat: String = "yyyyMMddHHmm" 14 | static let detailDateFormat: String = "yyyy년 MM월 dd일 HH시 mm분" 15 | } 16 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Constant/Image.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Image.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/25. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum Image { 12 | static let profiles = (1...17).compactMap { 13 | UIImage(named: "profile\($0)") 14 | } 15 | static let profileDefault = UIImage(named: "profile") ?? UIImage() 16 | } 17 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Constant/Layout.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Layout.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/18. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum Layout { 12 | static let minimumButtonHeight: CGFloat = 46 13 | static let minimumTextFieldHeight: CGFloat = 46 14 | static let minimumTextViewHeight: CGFloat = 54 15 | static let buttonHeight: CGFloat = 50 16 | static let textFieldHeight: CGFloat = 54 17 | static let textViewHeight: CGFloat = 54 18 | static let tapbarHeaderViewHeight: CGFloat = 68 19 | static let buttonBottomInset: CGFloat = 16 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Constant/Network.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Network.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/30. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum Network { 12 | static let baseURLString: String = "https://firestore.googleapis.com/v1/projects/mogakco-69b97/databases/(default)" 13 | static let authBaseURLString: String = "https://identitytoolkit.googleapis.com/v1" 14 | static let webAPIKey: String = "AIzaSyDZYeWGCGv_NZpqRrTiKfmlqbPD9nIGzJk" 15 | static let fcmAPIKey: String = "AAAA6-cpVGg:APA91bHWQzHyJQspWpt1C3Mjm0M9ACaa4rw6LlL2kYPM_f41vEtb50fcUQY6QAX8a3CsRG28MVFgt2JFocl1TIpVyKq-gBIolEKIb55ahvpcopf2mcBNGR38jBRrBWqK19sj1Me9RGJJ" 16 | static let fcmBaseURLStirng: String = "https://fcm.googleapis.com/fcm" 17 | static let servicePolicyURLString: String = "https://complete-health-026.notion.site/28fa997c334b4442b4af9d87174df248" 18 | static let contentPolicyURLString: String = "https://complete-health-026.notion.site/93c1f73ed6414d78a7aaaeb4fe9446ad" 19 | } 20 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/Array+Equtable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Array+Equtable.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/25. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Array where Element: Equatable { 12 | func allContains(_ elements: [Element]) -> Bool { 13 | return elements.filter { self.contains($0) }.count == elements.count 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/Array+Hashable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Array+Hashable.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/25. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Array where Element: Hashable { 12 | var countDictionary: [Element: Int] { 13 | var dictionary: [Element: Int] = [:] 14 | self.forEach { element in 15 | dictionary[element, default: 0] += 1 16 | } 17 | return dictionary 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/Date+Formatter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Date+Formatter.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/22. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Date { 12 | 13 | func toString(dateFormat: String) -> String { 14 | let formatter = DateFormatter() 15 | formatter.dateFormat = dateFormat 16 | formatter.locale = Locale(identifier: "ko_KR") 17 | formatter.timeZone = TimeZone(abbreviation: "KST") 18 | return formatter.string(from: self) 19 | } 20 | 21 | func toInt(dateFormat: String) -> Int { 22 | let formatter = DateFormatter() 23 | formatter.dateFormat = dateFormat 24 | formatter.locale = Locale(identifier: "ko_KR") 25 | formatter.timeZone = TimeZone(abbreviation: "KST") 26 | return Int(formatter.string(from: self)) ?? 0 27 | } 28 | 29 | var relativeTime: String { 30 | let formatter = RelativeDateTimeFormatter() 31 | formatter.locale = Locale(identifier: "ko_KR") 32 | formatter.unitsStyle = .abbreviated 33 | return formatter.localizedString(for: self, relativeTo: Date()) 34 | } 35 | 36 | func dateToStr() -> String { 37 | let dateFormatter = DateFormatter() 38 | dateFormatter.dateFormat = "yyyyMMddHHmm" 39 | let dateStr = dateFormatter.string(from: self) 40 | return dateStr 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/Encodable+Dictionary.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Encodable+Dictionary.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/12/12. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Encodable { 12 | func toDictionary() -> [String: Any] { 13 | guard let data = try? JSONEncoder().encode(self), 14 | let jsonData = try? JSONSerialization.jsonObject(with: data), 15 | let dictionaryData = jsonData as? [String: Any] else { return [:] } 16 | return dictionaryData 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/Int+Convert.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Int+Convert.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/28. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Int { 12 | var toString: String { 13 | return String(self) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/ObservableType+Result.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ObservableType+Result.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/30. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import RxSwift 10 | 11 | extension ObservableType { 12 | func asResult() -> Observable> { 13 | return self.map { .success($0) } 14 | .catch { .just(.failure($0)) } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/RxUIImageView+URL.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RxUIImageView+URL.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/22. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | import RxSwift 12 | 13 | extension Reactive where Base: UIImageView { 14 | var loadImage: Binder { 15 | let disposeBag = DisposeBag() 16 | return Binder(base) { base, url in 17 | base.load(url: url, disposeBag: disposeBag) 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/String+Date.swift: -------------------------------------------------------------------------------- 1 | // 2 | // String+Date.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/28. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension String { 12 | func toDate(dateFormat: String) -> Date? { 13 | let dateFormatter = DateFormatter() 14 | dateFormatter.dateFormat = dateFormat 15 | let date = dateFormatter.date(from: self) 16 | return date 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/UIButton+BackgroundColor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIButton+BackgroundColor.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/14. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIButton { 11 | func setBackgroundColor(_ color: UIColor, for state: UIControl.State) { 12 | UIGraphicsBeginImageContext(CGSize(width: 1.0, height: 1.0)) 13 | guard let context = UIGraphicsGetCurrentContext() else { return } 14 | context.setFillColor(color.cgColor) 15 | context.fill(CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)) 16 | let backgroundImage = UIGraphicsGetImageFromCurrentImageContext() 17 | UIGraphicsEndImageContext() 18 | self.setBackgroundImage(backgroundImage, for: state) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/UIColor+MogakcoColor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/14. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIColor { 11 | static let mogakcoColor = MogakcoColor() 12 | } 13 | 14 | struct MogakcoColor { 15 | // Primary 16 | let primaryDefault = UIColor(named: "PrimaryDefault") 17 | let primarySecondary = UIColor(named: "PrimarySecondary") 18 | let primaryThird = UIColor(named: "PrimaryThird") 19 | 20 | // Typography 21 | let typographyPrimary = UIColor(named: "TypographyPrimary") 22 | let typographySecondary = UIColor(named: "TypographySecondary") 23 | let typopraphyDisabled = UIColor(named: "TypopraphyDisabled") 24 | 25 | // Semantic 26 | let semanticSuccess = UIColor(named: "SemanticSuccess") 27 | let semanticNegative = UIColor(named: "SemanticNegative") 28 | let semanticDisabled = UIColor(named: "SemanticDisabled") 29 | 30 | // Border 31 | let borderDefault = UIColor(named: "BorderDefault") 32 | 33 | // Background 34 | let backgroundDefault = UIColor(named: "BackgroundDefault") 35 | 36 | // Gradient 37 | let gradientStart = UIColor(named: "gradientStart") 38 | let gradientEnd = UIColor(named: "gradientEnd") 39 | } 40 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/UIFont+CustomFont.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIFont+CustomFont.swift 3 | // Mogakco 4 | // 5 | // Created by 오국원 on 2022/11/14. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIFont { 11 | static let mogakcoFont = MogakcoFont() 12 | } 13 | 14 | struct MogakcoFont { 15 | 16 | // Regular 17 | let largeRegular = MogakcoFontFamily.SFProDisplay.regular.font(size: 30) 18 | let mediumRegular = MogakcoFontFamily.SFProDisplay.regular.font(size: 17) 19 | let smallRegular = MogakcoFontFamily.SFProDisplay.regular.font(size: 14) 20 | 21 | // Bold 22 | let largeBold = MogakcoFontFamily.SFProDisplay.semibold.font(size: 30) 23 | let title1Bold = MogakcoFontFamily.SFProDisplay.semibold.font(size: 24) 24 | let title2Bold = MogakcoFontFamily.SFProDisplay.semibold.font(size: 22) 25 | let title3Bold = MogakcoFontFamily.SFProDisplay.semibold.font(size: 20) 26 | let mediumBold = MogakcoFontFamily.SFProDisplay.semibold.font(size: 18) 27 | let smallBold = MogakcoFontFamily.SFProDisplay.semibold.font(size: 14) 28 | let caption = MogakcoFontFamily.SFProDisplay.semibold.font(size: 12) 29 | } 30 | 31 | enum SFPro: String { 32 | case regular = "SFProDisplay-Regular" 33 | case bold = "SFProDisplay-Semibold" 34 | } 35 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/UIImageView+URL.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIImageView+URL.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/22. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | import RxMGKfisher 12 | import RxSwift 13 | import RxCocoa 14 | 15 | extension UIImageView { 16 | 17 | func load(url: URL, disposeBag: DisposeBag) { 18 | MGKImageCacheService.shared.setImage(url) // setImage를 통해 각 메모리를 체크 19 | .observe(on: MainScheduler.instance) 20 | .subscribe(onNext: { [weak self] image in 21 | self?.image = UIImage(data: image) 22 | }) 23 | .disposed(by: disposeBag) 24 | } 25 | 26 | func loadAndEvent(url: URL) -> Observable { 27 | return Observable.create { emitter in 28 | DispatchQueue.global().async { [weak self] in 29 | if let data = try? Data(contentsOf: url) { 30 | if let image = UIImage(data: data) { 31 | DispatchQueue.main.async { 32 | self?.image = image 33 | emitter.onNext(false) 34 | } 35 | } 36 | } 37 | } 38 | return Disposables.create() 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/UILabel+LineSpacing.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UILabel+LineSpacing.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/11/15. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UILabel { 11 | 12 | func setLineSpacing(spacing: CGFloat) { 13 | guard let text = self.text else { return } 14 | let paragraphStyle = NSMutableParagraphStyle() 15 | paragraphStyle.lineSpacing = spacing 16 | let attributedString = NSMutableAttributedString(string: text) 17 | attributedString.addAttribute( 18 | .paragraphStyle, 19 | value: paragraphStyle, 20 | range: NSRange(location: 0, length: attributedString.length) 21 | ) 22 | self.attributedText = attributedString 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/UINavigation+Swipe.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigation+Swipe.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/12/08. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UINavigationController: UIGestureRecognizerDelegate { 12 | override open func viewDidLoad() { 13 | super.viewDidLoad() 14 | interactivePopGestureRecognizer?.delegate = self 15 | } 16 | 17 | public func gestureRecognizerShouldBegin(_: UIGestureRecognizer) -> Bool { 18 | return viewControllers.count > 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/UIView+AddSubViews.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+AddSubViews.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/14. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIView { 11 | func addSubViews(_ subViews: [UIView]) { 12 | subViews.forEach { addSubview($0) } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/UIView+Gradient.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Gradient.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/12/07. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIView { 12 | func setGradient(startColor: UIColor, endColor: UIColor, startPoint: CGPoint, endPoint: CGPoint) { 13 | let gradient = CAGradientLayer() 14 | gradient.colors = [startColor.cgColor, endColor.cgColor] 15 | gradient.locations = [0.0, 1.0] 16 | gradient.startPoint = startPoint 17 | gradient.endPoint = endPoint 18 | gradient.frame = bounds 19 | layer.insertSublayer(gradient, at: 0) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/UIView+Shadow.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Shadow.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/14. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIView { 11 | 12 | func addShadow(offset: CGSize, color: UIColor = .lightGray, opacity: Float = 0.35, radius: CGFloat = 3.0) { 13 | layer.masksToBounds = false 14 | layer.shadowColor = color.cgColor 15 | layer.shadowOffset = offset 16 | layer.shadowOpacity = opacity 17 | layer.shadowRadius = radius 18 | } 19 | 20 | func removeShadow() { 21 | layer.shadowOpacity = Float(0.0) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/UIViewController+Alert.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+Alert.swift 3 | // Mogakco 4 | // 5 | // Created by 신소민 on 2022/12/06. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIViewController { 12 | 13 | func alert(title: String, message: String, actions: [UIAlertAction]) { 14 | let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) 15 | actions.forEach { alert.addAction($0) } 16 | present(alert, animated: true, completion: nil) 17 | } 18 | } 19 | 20 | extension UIAlertAction { 21 | 22 | static func cancel() -> UIAlertAction { 23 | return UIAlertAction(title: "취소", style: .cancel) 24 | } 25 | 26 | static func destructive(title: String, handler: ((UIAlertAction) -> Void)?) -> UIAlertAction { 27 | return UIAlertAction(title: title, style: .destructive, handler: handler) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/UIViewController+HalfModal.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+HalfModal.swift 3 | // Mogakco 4 | // 5 | // Created by 오국원 on 2022/11/15. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIViewController { 11 | 12 | func halfModal(_ title: String, _ subTitle: String) { 13 | let modalVC = HalfModalViewController(title, subTitle) 14 | modalVC.modalPresentationStyle = .pageSheet 15 | guard let sheet = modalVC.sheetPresentationController else { return } 16 | sheet.detents = [ 17 | .custom(resolver: { _ in 18 | return 180 19 | }) 20 | ] 21 | sheet.prefersGrabberVisible = true 22 | 23 | present(modalVC, animated: true) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Mogakco/Sources/Util/Extension/UIViewController+Keyboard.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+Keyboard.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/16. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIViewController { 12 | func hideKeyboardWhenTappedAround() { 13 | let tap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard)) 14 | tap.cancelsTouchesInView = false 15 | view.addGestureRecognizer(tap) 16 | } 17 | 18 | @objc private func dismissKeyboard() { 19 | view.endEditing(true) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Mogakmation/Sources/AnimationImageView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnimationImageView.swift 3 | // Mogakco 4 | // 5 | // Created by 이주훈 on 2022/11/30. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | import SnapKit 12 | 13 | final class AnimationImageView: UIView { 14 | let iconImage = UIImageView() 15 | 16 | let rotateDuration: Int 17 | 18 | init(frame: CGRect, image: UIImage?, rotateDuration: Int) { 19 | self.rotateDuration = rotateDuration 20 | super.init(frame: frame) 21 | configImage(image: image) 22 | addRotation() 23 | } 24 | 25 | required init?(coder: NSCoder) { 26 | fatalError("init(coder:) has not been implemented") 27 | } 28 | 29 | private func configImage(image: UIImage?) { 30 | iconImage.image = image 31 | addSubview(iconImage) 32 | iconImage.snp.makeConstraints { 33 | $0.edges.equalToSuperview() 34 | } 35 | } 36 | 37 | private func addRotation() { 38 | let randomRotaionDirection = Double( 39 | [-1, 1].randomElement() ?? 1 40 | ) 41 | let rotation = CABasicAnimation(keyPath: "transform.rotation.z") 42 | rotation.fromValue = 0 43 | rotation.toValue = Double.pi / 180 * 360 * randomRotaionDirection 44 | rotation.duration = CFTimeInterval(rotateDuration) 45 | rotation.repeatCount = Float.infinity 46 | iconImage.layer.add(rotation, forKey: "rotationAnimation") 47 | } 48 | 49 | func removeRotation() { 50 | iconImage.layer.removeAnimation(forKey: "rotationAnimation") 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Plugins/Mogakco/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.4 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "MyPlugin", 7 | products: [ 8 | .executable(name: "tuist-my-cli", targets: ["tuist-my-cli"]), 9 | ], 10 | targets: [ 11 | .executableTarget( 12 | name: "tuist-my-cli" 13 | ), 14 | ] 15 | ) 16 | -------------------------------------------------------------------------------- /Plugins/Mogakco/Plugin.swift: -------------------------------------------------------------------------------- 1 | import ProjectDescription 2 | 3 | let plugin = Plugin(name: "MyPlugin") -------------------------------------------------------------------------------- /Plugins/Mogakco/ProjectDescriptionHelpers/LocalHelper.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public struct LocalHelper { 4 | let name: String 5 | 6 | public init(name: String) { 7 | self.name = name 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Plugins/Mogakco/Sources/tuist-my-cli/main.swift: -------------------------------------------------------------------------------- 1 | print("Hello, from your Tuist Task") -------------------------------------------------------------------------------- /RxMGKfisher/Sources/CacheConstants.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CacheConstants.swift 3 | // Mogakco 4 | // 5 | // Created by 오국원 on 2022/12/06. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | import Foundation 9 | 10 | enum CacheConstants { 11 | static let maximumMemoryCacheSize = 52428800 12 | static let maximumDiskCacheSize = 52428800 13 | } 14 | -------------------------------------------------------------------------------- /RxMGKfisher/Sources/CacheableImage.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CachableImage.swift 3 | // Mogakco 4 | // 5 | // Created by 오국원 on 2022/12/06. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | final class CacheableImage { 12 | let imageData: Data 13 | let cacheInfo: CacheInfo 14 | 15 | init(imageData: Data, etag: String) { 16 | self.cacheInfo = CacheInfo(etag: etag, lastRead: Date()) 17 | self.imageData = imageData 18 | } 19 | } 20 | 21 | struct CacheInfo: Codable { 22 | let etag: String 23 | let lastRead: Date 24 | } 25 | -------------------------------------------------------------------------------- /RxMogakcoYa/Sources/ProviderProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkProtocol.swift 3 | // Mogakco 4 | // 5 | // Created by 김범수 on 2022/11/21. 6 | // Copyright © 2022 Mogakco. All rights reserved. 7 | // 8 | 9 | import Alamofire 10 | import RxSwift 11 | 12 | public protocol ProviderProtocol: AnyObject { 13 | func request(_ urlConvertible: URLRequestConvertible) -> Observable 14 | } 15 | -------------------------------------------------------------------------------- /Scripts/SwiftLintRunScript.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # SwiftLintRunScript.sh 4 | # Manifests 5 | # 6 | # Created by 오 국 원 on 2022/11/15. 7 | # 8 | 9 | export PATH="$PATH:/opt/homebrew/bin" 10 | if which swiftlint >/dev/null; then 11 | swiftlint 12 | else 13 | echo "warning: SwiftLint not installed, download form https://github.com/realm/SwiftLint" 14 | fi 15 | -------------------------------------------------------------------------------- /Tuist/Config.swift: -------------------------------------------------------------------------------- 1 | import ProjectDescription 2 | 3 | let config = Config() 4 | -------------------------------------------------------------------------------- /Tuist/Dependencies.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Dependencies.swift 3 | // Config 4 | // 5 | // Created by 김범수 on 2022/11/15. 6 | // 7 | 8 | import ProjectDescription 9 | 10 | let spm = SwiftPackageManagerDependencies([ 11 | .remote(url: "https://github.com/ReactiveX/RxSwift", requirement: .upToNextMajor(from: "6.5.0")), 12 | .remote(url: "https://github.com/RxSwiftCommunity/RxKeyboard", requirement: .upToNextMajor(from: "2.0.0")), 13 | .remote(url: "https://github.com/firebase/firebase-ios-sdk", requirement: .upToNextMajor(from: "8.10.0")), 14 | .remote(url: "https://github.com/devxoul/Then", requirement: .upToNextMajor(from: "3.0.0")), 15 | .remote(url: "https://github.com/Alamofire/Alamofire", requirement: .upToNextMajor(from: "5.6.2")), 16 | .remote(url: "https://github.com/SnapKit/SnapKit", requirement: .upToNextMajor(from: "5.6.0")), 17 | .remote(url: "https://github.com/Swinject/Swinject", requirement: .upToNextMajor(from: "2.8.3")) 18 | ]) 19 | 20 | let dependencies = Dependencies( 21 | swiftPackageManager: spm, 22 | platforms: [.iOS] 23 | ) 24 | --------------------------------------------------------------------------------