Skip to content

Commit

Permalink
πŸ’„#298: API 연동
Browse files Browse the repository at this point in the history
  • Loading branch information
wendoei committed Dec 15, 2024
1 parent 37dbc4f commit 76ac8b9
Show file tree
Hide file tree
Showing 13 changed files with 240 additions and 230 deletions.
4 changes: 2 additions & 2 deletions StreetDrop/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ PODS:
- GoogleUserMessagingPlatform (>= 1.1)
- GoogleUserMessagingPlatform (2.1.0)
- NMapsGeometry (1.0.1)
- NMapsMap (3.16.2):
- NMapsMap (3.18.0):
- NMapsGeometry

DEPENDENCIES:
Expand All @@ -21,7 +21,7 @@ SPEC CHECKSUMS:
Google-Mobile-Ads-SDK: 7a466427864972f5229f1f89d004b998a28ddcae
GoogleUserMessagingPlatform: dce302b8f1b84d6e945812ee7a15c3f65a102cbf
NMapsGeometry: 53c573ead66466681cf123f99f698dc8071a4b83
NMapsMap: aaa64717249b06ae82c3a3addb3a01f0e33100ab
NMapsMap: 36dc18a1f5f315121b33fccd2398c7a702bf0fc8

PODFILE CHECKSUM: c1edcf3d49503875acf5f6e7bfd364191c925046

Expand Down
20 changes: 12 additions & 8 deletions StreetDrop/StreetDrop.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -256,13 +256,14 @@
C4E4C6BD2A5AE6F500B1C84A /* MusicApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E4C6BC2A5AE6F500B1C84A /* MusicApp.swift */; };
C4E68C852C2A996000742464 /* AsynchronousError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E68C842C2A996000742464 /* AsynchronousError.swift */; };
C51230A18096B11C82137084 /* libPods-StreetDrop.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 642A4AE13B198B9F5F5F76E4 /* libPods-StreetDrop.a */; };
F47C1B982CCD242B00C2D546 /* RecommendSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F47C1B972CCD242600C2D546 /* RecommendSection.swift */; };
F48DF73A2C1DD8F500F6DEA1 /* SettingPushNotificationCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F48DF7392C1DD8F500F6DEA1 /* SettingPushNotificationCell.swift */; };
F48DF73C2C1DD91C00F6DEA1 /* SettingMusicSelectCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F48DF73B2C1DD91C00F6DEA1 /* SettingMusicSelectCell.swift */; };
F49CC9F22C638691007484EE /* RecommendMusicUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = F49CC9F12C638691007484EE /* RecommendMusicUsecase.swift */; };
F49CC9F62C638CCF007484EE /* DefaultRecommendMusicRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = F49CC9F52C638CCF007484EE /* DefaultRecommendMusicRepository.swift */; };
F49CC9F82C638DC6007484EE /* RecommendMusicRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = F49CC9F72C638DC6007484EE /* RecommendMusicRepository.swift */; };
F49CC9FC2C6411E5007484EE /* RecommendMusicCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F49CC9FB2C6411E5007484EE /* RecommendMusicCell.swift */; };
F49CC9FE2C6411F9007484EE /* RecommendArtistCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F49CC9FD2C6411F9007484EE /* RecommendArtistCell.swift */; };
F49CC9FC2C6411E5007484EE /* RecommendBasicCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F49CC9FB2C6411E5007484EE /* RecommendBasicCell.swift */; };
F49CC9FE2C6411F9007484EE /* RecommendKeywordCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F49CC9FD2C6411F9007484EE /* RecommendKeywordCell.swift */; };
F49CCA002C667111007484EE /* RecommendHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F49CC9FF2C667111007484EE /* RecommendHeaderView.swift */; };
F49DB0B42C6E6E3400686E5F /* RecommendMusicListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F49DB0B32C6E6E3400686E5F /* RecommendMusicListViewController.swift */; };
F49DB0B62C6E6F2100686E5F /* RecommendMusicListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F49DB0B52C6E6F2100686E5F /* RecommendMusicListViewModel.swift */; };
Expand Down Expand Up @@ -520,13 +521,14 @@
C4E4C6B92A5AE40900B1C84A /* UserDefaultsError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsError.swift; sourceTree = "<group>"; };
C4E4C6BC2A5AE6F500B1C84A /* MusicApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicApp.swift; sourceTree = "<group>"; };
C4E68C842C2A996000742464 /* AsynchronousError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsynchronousError.swift; sourceTree = "<group>"; };
F47C1B972CCD242600C2D546 /* RecommendSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendSection.swift; sourceTree = "<group>"; };
F48DF7392C1DD8F500F6DEA1 /* SettingPushNotificationCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingPushNotificationCell.swift; sourceTree = "<group>"; };
F48DF73B2C1DD91C00F6DEA1 /* SettingMusicSelectCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingMusicSelectCell.swift; sourceTree = "<group>"; };
F49CC9F12C638691007484EE /* RecommendMusicUsecase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendMusicUsecase.swift; sourceTree = "<group>"; };
F49CC9F52C638CCF007484EE /* DefaultRecommendMusicRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultRecommendMusicRepository.swift; sourceTree = "<group>"; };
F49CC9F72C638DC6007484EE /* RecommendMusicRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendMusicRepository.swift; sourceTree = "<group>"; };
F49CC9FB2C6411E5007484EE /* RecommendMusicCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendMusicCell.swift; sourceTree = "<group>"; };
F49CC9FD2C6411F9007484EE /* RecommendArtistCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendArtistCell.swift; sourceTree = "<group>"; };
F49CC9FB2C6411E5007484EE /* RecommendBasicCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendBasicCell.swift; sourceTree = "<group>"; };
F49CC9FD2C6411F9007484EE /* RecommendKeywordCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendKeywordCell.swift; sourceTree = "<group>"; };
F49CC9FF2C667111007484EE /* RecommendHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendHeaderView.swift; sourceTree = "<group>"; };
F49DB0B32C6E6E3400686E5F /* RecommendMusicListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendMusicListViewController.swift; sourceTree = "<group>"; };
F49DB0B52C6E6F2100686E5F /* RecommendMusicListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendMusicListViewModel.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1114,6 +1116,7 @@
41396DA72A51B8E600B69341 /* Entity */ = {
isa = PBXGroup;
children = (
F47C1B972CCD242600C2D546 /* RecommendSection.swift */,
C472B1872AC5523300482B2D /* DroppingInfo.swift */,
41396DA82A51B8F700B69341 /* EditInfo.swift */,
C40008E92A32012B00EA7FA9 /* Music.swift */,
Expand Down Expand Up @@ -1272,8 +1275,8 @@
C45BF3AB2A1EF64300CEDE74 /* RecentQueryCell.swift */,
B4B9EE852ADEB2AC000A6507 /* RecommendKeywordItemCell.swift */,
B46578C22B00BC060024B066 /* LeftAlignedCollectionViewFlowLayout.swift */,
F49CC9FB2C6411E5007484EE /* RecommendMusicCell.swift */,
F49CC9FD2C6411F9007484EE /* RecommendArtistCell.swift */,
F49CC9FB2C6411E5007484EE /* RecommendBasicCell.swift */,
F49CC9FD2C6411F9007484EE /* RecommendKeywordCell.swift */,
F49CC9FF2C667111007484EE /* RecommendHeaderView.swift */,
F4CBD7BD2C6A534600A5FD91 /* RecentSearchesHeaderView.swift */,
F4CBD7BF2C6C181900A5FD91 /* GuideDetailView.swift */,
Expand Down Expand Up @@ -1986,14 +1989,15 @@
C41972572ABED40100211222 /* DefaultFetchingMyInfoUseCase.swift in Sources */,
C419723A2ABDB50B00211222 /* DefaultFetchingMusicCountUseCase.swift in Sources */,
F4C996AD2C1EEF2500FF7B9A /* NoticeRepository.swift in Sources */,
F49CC9FE2C6411F9007484EE /* RecommendArtistCell.swift in Sources */,
F49CC9FE2C6411F9007484EE /* RecommendKeywordCell.swift in Sources */,
F4AA84DB2C1F106300CADB1A /* NoticeDetailViewController.swift in Sources */,
C47F02282A3864A500F48884 /* SettingElementCell.swift in Sources */,
1876F0472A66EDA20064B887 /* MyPageModel.swift in Sources */,
18683FDC2A348B15005A94AC /* DefaultMainRepository.swift in Sources */,
1876F03F2A66E4E30064B887 /* MyLikeListResponseDTO+Mapping.swift in Sources */,
6A7D73DD2BB14015009340E3 /* GradientProgressBar.swift in Sources */,
B46578C32B00BC060024B066 /* LeftAlignedCollectionViewFlowLayout.swift in Sources */,
F47C1B982CCD242B00C2D546 /* RecommendSection.swift in Sources */,
C41BD2E92A38467A0090EF2B /* UIImageView+ImageCache.swift in Sources */,
41D0974F2A19065B00C011A0 /* UIView+generateCircleGradientView.swift in Sources */,
C4BB15982A5EC507001BC5E8 /* FCMRepository.swift in Sources */,
Expand All @@ -2017,7 +2021,7 @@
1876F0412A66E5440064B887 /* MyLevelResponseDTO+Mapping.swift in Sources */,
C4685B3D2B7261A000F514C7 /* SplashViewModel.swift in Sources */,
F4AA84DF2C1F3B0200CADB1A /* Array+Extension.swift in Sources */,
F49CC9FC2C6411E5007484EE /* RecommendMusicCell.swift in Sources */,
F49CC9FC2C6411E5007484EE /* RecommendBasicCell.swift in Sources */,
082F17062AB6DFEC00174D98 /* MusicDropUseCase.swift in Sources */,
18683FD92A2A251E005A94AC /* ViewModel.swift in Sources */,
C41972442ABDC43C00211222 /* ClaimingCommentUseCase.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import Foundation
import RxSwift

protocol RecommendMusicRepository {
func fetchPromptOfTheDay() -> Single<String>
func fetchTrendingMusicList() -> Single<[Music]>
func fetchMostDroppedMusicList() -> Single<[Music]>
func fetchArtistList() -> Single<[Artist]>
func fetchPromptOfTheDay() -> Single<String?>
func fetchRecommendSectionList() -> Single<[RecommendSectionDTO]>
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,47 +21,19 @@ final class DefaultRecommendMusicRepository: RecommendMusicRepository {
self.networkManager = networkManager
}

// TODO: jihye - update api

func fetchPromptOfTheDay() -> Single<String> {
Single.just("λΉ„μ˜€λŠ” λ‚ , μ–΄λ–€ μŒμ•…μ΄ λ– μ˜€λ₯΄μ‹œλ‚˜μš”?")
}

func fetchTrendingMusicList() -> Single<[Music]> {
Single.just([
Music(
albumName: "",
artistName: "ILLIT",
songName: "Magnetic",
durationTime: "2:41",
albumImage: "https://is2-ssl.mzstatic.com/image/thumb/Music126/v4/03/8d/0e/038d0e52-e96d-f386-b8eb-9f77fa013543/195497146918_Cover.jpg/300x300bb.jpg",
albumThumbnailImage: "https://is2-ssl.mzstatic.com/image/thumb/Music126/v4/03/8d/0e/038d0e52-e96d-f386-b8eb-9f77fa013543/195497146918_Cover.jpg/100x100bb.jpg",
genre: []
)
])
}

func fetchMostDroppedMusicList() -> Single<[Music]> {
Single.just([
Music(
albumName: "",
artistName: "NewJeans",
songName: "Supernatural",
durationTime: "3:11",
albumImage: "https://is2-ssl.mzstatic.com/image/thumb/Music126/v4/03/8d/0e/038d0e52-e96d-f386-b8eb-9f77fa013543/195497146918_Cover.jpg/300x300bb.jpg",
albumThumbnailImage: "https://is2-ssl.mzstatic.com/image/thumb/Music126/v4/03/8d/0e/038d0e52-e96d-f386-b8eb-9f77fa013543/195497146918_Cover.jpg/100x100bb.jpg",
genre: []
)
])
func fetchRecommendSectionList() -> Single<[RecommendSectionDTO]> {
return networkManager.request(
target: .init(NetworkService.getRecommendList),
responseType: RecommendSectionResponse.self
)
.map { $0.data }
}

func fetchArtistList() -> Single<[Artist]> {
return Single.just([
Artist(name: "NewJeans", image: "https://is2-ssl.mzstatic.com/image/thumb/Music126/v4/03/8d/0e/038d0e52-e96d-f386-b8eb-9f77fa013543/195497146918_Cover.jpg/100x100bb.jpg"),
Artist(name: "SEVENTEEN", image: "https://is2-ssl.mzstatic.com/image/thumb/Music126/v4/03/8d/0e/038d0e52-e96d-f386-b8eb-9f77fa013543/195497146918_Cover.jpg/100x100bb.jpg"),
Artist(name: "μ•„μ΄μœ ", image: "https://is2-ssl.mzstatic.com/image/thumb/Music126/v4/03/8d/0e/038d0e52-e96d-f386-b8eb-9f77fa013543/195497146918_Cover.jpg/100x100bb.jpg"),
Artist(name: "aespa", image: "https://is2-ssl.mzstatic.com/image/thumb/Music126/v4/03/8d/0e/038d0e52-e96d-f386-b8eb-9f77fa013543/195497146918_Cover.jpg/100x100bb.jpg"),
Artist(name: "졜유리", image: "https://is2-ssl.mzstatic.com/image/thumb/Music126/v4/03/8d/0e/038d0e52-e96d-f386-b8eb-9f77fa013543/195497146918_Cover.jpg/100x100bb.jpg")
])

func fetchPromptOfTheDay() -> Single<String?> {
return networkManager.request(
target: .init(NetworkService.getPromptOfTheDay),
responseType: PromptOfTheDayResponse.self
)
.map { $0.sentence }
}
}
6 changes: 0 additions & 6 deletions StreetDrop/StreetDrop/Domain/Entity/RecommendMusic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,3 @@ struct RecommendMusicData: Decodable {
let text: String
let color: String
}

// TODO: jihye - api update
struct Artist: Hashable {
let name: String
let image: String
}
103 changes: 103 additions & 0 deletions StreetDrop/StreetDrop/Domain/Entity/RecommendSection.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
//
// RecommendSection.swift
// StreetDrop
//
// Created by jihye kim on 26/10/2024.
//

struct RecommendSectionResponse: Decodable {
let data: [RecommendSectionDTO]
}

struct PromptOfTheDayResponse: Decodable {
let sentence: String?
}

struct RecommendSectionDTO: Decodable {
// Header
let title: String
let description: String?

// Content
let type: ContentType
let content: Content

enum ContentType: String, Decodable {
case basic
case keyword

init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let rawValue = try container.decode(String.self)
self = ContentType(rawValue: rawValue.lowercased()) ?? .basic
}
}

struct Content: Decodable {
let basic: [MusicContent]?
let keyword: [KeywordContent]?
}

struct MusicContent: Decodable {
let albumName: String
let artistName: String
let songName: String
let durationTime: String
let albumImage: String
let albumThumbnailImage: String
let genre: [String]
}

struct KeywordContent: Decodable {
let artistName: String
let albumImage: String
let albumThumbnailImage: String
}
}

// MARK: Conversion

extension RecommendSectionDTO {
typealias HeaderInfo = RecommendMusicSectionModel.Header
typealias Item = RecommendMusicSectionModel.Item

var sectionModel: RecommendMusicSectionModel? {
switch type {
case .basic:
guard let basic = content.basic else { return nil }
let musicList = basic.map { basicContent in
Music(
albumName: basicContent.albumName,
artistName: basicContent.artistName,
songName: basicContent.songName,
durationTime: basicContent.durationTime,
albumImage: basicContent.albumImage,
albumThumbnailImage: basicContent.albumThumbnailImage,
genre: basicContent.genre
)
}
return .init(
type: .basic(.init(title: title, info: description), musicList),
items: musicList.map { Item.basic($0) }
)
case .keyword:
guard let keyword = content.keyword else { return nil }
return .init(
type: .keyword(.init(title: title, info: description)),
items: keyword.map { keywordContent in
Item.keyword(
.init(
text: keywordContent.artistName,
image: keywordContent.albumThumbnailImage
)
)
}
)
}
}
}

struct SearchKeywordEntity: Hashable {
let text: String
let image: String
}
20 changes: 5 additions & 15 deletions StreetDrop/StreetDrop/Domain/UseCase/RecommendMusicUsecase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ import Foundation
import RxSwift

protocol RecommendMusicUsecase {
func getPromptOfTheDay() -> Single<String>
func getTrendingMusicList() -> Single<[Music]>
func getMostDroppedMusicList() -> Single<[Music]>
func getArtistList() -> Single<[Artist]>
func getPromptOfTheDay() -> Single<String?>
func getRecommendSections() -> Single<[RecommendSectionDTO]>
}

final class DefaultRecommendMusicUsecase: RecommendMusicUsecase {
Expand All @@ -23,19 +21,11 @@ final class DefaultRecommendMusicUsecase: RecommendMusicUsecase {
self.recommendMusicRepository = recommendMusicRepository
}

func getPromptOfTheDay() -> Single<String> {
func getPromptOfTheDay() -> Single<String?> {
recommendMusicRepository.fetchPromptOfTheDay()
}

func getTrendingMusicList() -> Single<[Music]> {
recommendMusicRepository.fetchTrendingMusicList()
}

func getMostDroppedMusicList() -> Single<[Music]> {
recommendMusicRepository.fetchMostDroppedMusicList()
}

func getArtistList() -> Single<[Artist]> {
recommendMusicRepository.fetchArtistList()
func getRecommendSections() -> Single<[RecommendSectionDTO]> {
recommendMusicRepository.fetchRecommendSectionList()
}
}
13 changes: 11 additions & 2 deletions StreetDrop/StreetDrop/Network/NetworkService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ enum NetworkService {
case getNoticeList
case getNoticeDetail(id: Int)
case checkNewNotice(lastNoticeId: Int?)
case getRecommendList
case getPromptOfTheDay
}

extension NetworkService: TargetType {
Expand Down Expand Up @@ -119,6 +121,10 @@ extension NetworkService: TargetType {
return "/notices/\(id)"
case .checkNewNotice:
return "/notices/new"
case .getRecommendList:
return "/v2/search-term/recommend"
case .getPromptOfTheDay:
return "/post-recommend/random-sentence"
}
}

Expand All @@ -142,7 +148,9 @@ extension NetworkService: TargetType {
.getPopUpInfomation,
.getNoticeList,
.getNoticeDetail,
.checkNewNotice:
.checkNewNotice,
.getRecommendList,
.getPromptOfTheDay:
return .get
case .dropMusic,
.postLikeUp,
Expand All @@ -162,7 +170,8 @@ extension NetworkService: TargetType {
var task: Moya.Task {
switch self {
case .getMyInfo, .myDropList, .myLikeList, .myLevel, .myLevelProgress, .levelPolicy, .recommendMusic, .userCircleRadius, .getPopUpInfomation,
.getNoticeList, .getNoticeDetail:
.getNoticeList, .getNoticeDetail, .getRecommendList,
.getPromptOfTheDay:
return .requestPlain
case .searchMusic(let keyword):
return .requestParameters(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ private extension MainViewModel {
recommendMusicUsecase.getPromptOfTheDay().subscribe { [weak self] result in
switch result {
case .success(let prompt):
guard let prompt else { return }
self?.showPromptIfFirstLaunchedToday(prompt: prompt, output: output)
case .failure(let error):
print(error)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// RecommendMusicCell.swift
// RecommendBasicCell.swift
// StreetDrop
//
// Created by jihye kim on 07/08/2024.
Expand All @@ -9,7 +9,7 @@ import UIKit

import Kingfisher

class RecommendMusicCell: UICollectionViewCell {
class RecommendBasicCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
configureUI()
Expand Down Expand Up @@ -59,7 +59,7 @@ class RecommendMusicCell: UICollectionViewCell {
}
}

private extension RecommendMusicCell {
private extension RecommendBasicCell {
func configureUI() {
let infoStackView = UIStackView()
infoStackView.axis = .vertical
Expand Down
Loading

0 comments on commit 76ac8b9

Please sign in to comment.