Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#114] Album cover 안보이는 이슈 해결 #117

Open
wants to merge 5 commits into
base: Develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1530"
version = "1.7">
version = "1.8">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
Expand Down
10 changes: 5 additions & 5 deletions MinGenie/MinGenie/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import SwiftUI

struct ContentView: View {
@Environment(\.scenePhase) var phase
@EnvironmentObject var musicPlayer: MusicPlayerModel

@StateObject var shakeDetectionModel = ShakeDetectionModel()
@StateObject var musicPlayerModel = MusicPlayerModel.shared

@AppStorage("Onboarding") var hasSeenOnboarding = false
@AppStorage("BackgroundInfo") var hasSeenBackgroundInfoView = false
Expand All @@ -23,24 +23,24 @@ struct ContentView: View {
ZStack(alignment: .bottom) {
HomeView()
.modelContainer(for: StoredTrackID.self)
.environmentObject(musicPlayerModel)
.environmentObject(musicPlayer)
.onChange(of: phase) { _, newValue in
if newValue == .background && musicPlayerModel.isPlaying {
if newValue == .background && musicPlayer.isPlaying {
shakeDetectionModel.startDetection()
} else {
shakeDetectionModel.stopDetection()
}
}
.onChange(of: shakeDetectionModel.shakeDetected) { _, newValue in
if newValue && musicPlayerModel.isPlaying {
if newValue && musicPlayer.isPlaying {
print("🎧 Music Change")

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate) //진동 주기

// 노래 교체가 끝나면 다시 시작
shakeDetectionModel.stopDetection()
Task {
await musicPlayerModel.updatePlaylistAfterShaking()
await musicPlayer.updatePlaylistAfterShaking()
if phase == .background {
shakeDetectionModel.startDetection()
}
Expand Down
4 changes: 3 additions & 1 deletion MinGenie/MinGenie/MinGenieApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import SwiftUI

@main
struct MinGenieApp: App {

@StateObject var musicPlayerModel = MusicPlayerModel()

var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(musicPlayerModel)
}
}
}
10 changes: 3 additions & 7 deletions MinGenie/MinGenie/Playback/Cells/NowQueueItemCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import SwiftUI
/// A view that displays information about a music item.
struct NowQueueItemCell: View {
// MARK: - Properties
private var artworkSize: CGFloat = 51
private var artworkCornerRadius: CGFloat = 11
private var subtitleVerticalOffset: CGFloat = -8
private let artworkSize: CGFloat = 51
private let artworkCornerRadius: CGFloat = 11
private let subtitleVerticalOffset: CGFloat = -8

let artwork: Artwork?
let title: String
Expand All @@ -27,19 +27,15 @@ struct NowQueueItemCell: View {
// MARK: - View
var body: some View {
HStack {

if let itemArtwork = artwork {
imageContainer(for: itemArtwork)
.frame(width: artworkSize, height: artworkSize)
} else {

Image("FlowishGray")
.resizable()
.frame(width: artworkSize, height: artworkSize)
}



VStack(alignment: .leading) {
Text(title)
.font(.system(size: 17, weight: .semibold))
Expand Down
10 changes: 3 additions & 7 deletions MinGenie/MinGenie/Playback/MiniPlayerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,11 @@ import SwiftUI
/// ✏️ 하단에 띄워 둘 미니플레이어 View입니다 (완성) ✏️

struct MiniPlayerView: View {

/// musicPlayer 관련 변수
@ObservedObject private var playbackQueue = ApplicationMusicPlayer.shared.queue
@ObservedObject private var musicPlayer = MusicPlayerModel.shared
@EnvironmentObject var musicPlayer: MusicPlayerModel

/// fullscreen전환 관련 변수
@State private var isShowingNowPlaying = false


// MARK: - View
var body: some View {
content
Expand All @@ -25,13 +21,13 @@ struct MiniPlayerView: View {
.shadow(radius: 20)
)
.fullScreenCover(isPresented: $isShowingNowPlaying) {
NowPlayingView(playbackQueue: playbackQueue)
NowPlayingView()
}
}

@ViewBuilder
private var content: some View {
if let currentPlayerEntry = playbackQueue.currentEntry {
if let currentPlayerEntry = musicPlayer.playbackQueue.currentEntry {
HStack {
VStack(alignment: .leading){
Button(action: handleTap) {
Expand Down
34 changes: 27 additions & 7 deletions MinGenie/MinGenie/Playback/MusicPlayerModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import MusicKit
import SwiftUI

final class MusicPlayerModel: ObservableObject {
static let shared = MusicPlayerModel()

private init() {}

// MARK: - Properties
@Published var isPlaying = false
@Published var playbackQueue = ApplicationMusicPlayer.shared.queue
@Published var currentMusicIndex: Int = 0
// Track 캐싱을 위한 배열
@Published var queueTracks: [Track] = []

var playbackStateObserver: AnyCancellable?

Expand Down Expand Up @@ -153,15 +153,18 @@ final class MusicPlayerModel: ObservableObject {
/// - Returns: 필터링된 트랙 배열
private func filterInstrumentalTracks(from tracks: MusicItemCollection<Track>) -> [Track] {
return tracks.filter { track in
// 대, 소문자 구분 없이 제외
return track.title.range(of: "(instrumental)", options: .caseInsensitive) == nil
// 대, 소문자 구분 없이 'instrumental' 및 'inst.'를 제외
let lowercasedTitle = track.title.lowercased()
return !lowercasedTitle.contains("instrumental") && !lowercasedTitle.contains("inst.")
}
}

/// 🐯 특정 노래를 재생하고 그 뒤에 추천 플레이리스트 붙여주기
/// - Parameter song: 관련된 노래를 찾을 때 사용할 노래
func playMusicWithRecommendedList(_ song: Song) {
let track = fromSongToTrack(song)
queueTracks.removeAll()
saveTracks(for: [track])

// 개별 곡 재생
play(track, in: nil, with: nil)
Expand All @@ -170,25 +173,29 @@ final class MusicPlayerModel: ObservableObject {
Task {
let recommendedList = try await getRelatedSongs(song)
if let recommendedList {
saveTracks(for: recommendedList)
try await ApplicationMusicPlayer.shared.queue.insert(recommendedList, position: .tail)
}
}
}


/// 🐯 앨범 전체 재생하고 그 뒤에 추천 플레이리스트 붙여주기
/// - Parameter tracks: 사용자가 선택한 전체 재생할 앨범에 담긴 트랙
/// - Parameter album: 관련된 노래를 찾을 때 사용할 앨범
func playAlbumWithRecommendedList(_ tracks: MusicItemCollection<Track>, album: Album) {
// ⁉️호랑: 이후에 DetailedAlbumModel에서 진행중인 로직을 여기다가 합칠 지 고민해보기 -> 현재는 앨범을 통해 트랙 배열을 받고 해당 메서드에 파라미터로 사용하는 로직

queueTracks.removeAll()
saveTracks(for: tracks)

// 앨범 재생
play(tracks[0], in: tracks, with: nil)

// 추천 트랙 추가
Task {
let recommendedList = try await getRelatedSongs(album)
if let recommendedList {
saveTracks(for: recommendedList)
try await ApplicationMusicPlayer.shared.queue.insert(recommendedList, position: .tail)
}
}
Expand Down Expand Up @@ -250,7 +257,20 @@ final class MusicPlayerModel: ObservableObject {
}

private func handlePlaybackStateDidChange() {
isPlaying = (musicPlayer.state.playbackStatus == .playing)
DispatchQueue.main.async {
self.isPlaying = (self.musicPlayer.state.playbackStatus == .playing)
}
}

}


extension MusicPlayerModel {
/// queue에 음악을 넣기 전에 따로 배열에 저장을 해주는 메서드
private func saveTracks(for tracks: MusicItemCollection<Track>) {
DispatchQueue.main.async {
self.queueTracks += tracks
}
}
}

Loading