Skip to content

Commit

Permalink
Add searchSummaries
Browse files Browse the repository at this point in the history
  • Loading branch information
rudrankriyam committed Apr 6, 2023
1 parent b2118be commit d0a462e
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 101 deletions.
21 changes: 0 additions & 21 deletions Sources/MusanovaKit/Replay/MReplaySummaries.swift

This file was deleted.

70 changes: 0 additions & 70 deletions Sources/MusanovaKit/Replay/MSummariesRequest.swift

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// MReplaySummary.swift
// MusicSummarySearch.swift
// MusanovaKit
//
// Created by Rudrank Riyam on 04/04/23.
Expand All @@ -9,16 +9,16 @@ import Foundation

/// A summary of a user's music listening history for a specific year.
///
/// The `MReplaySummary` struct represents a summary of a user's music listening
/// The `MusicSummarySearch` struct represents a summary of a user's music listening
/// history for a specific year. It includes information such as the year,
/// and the associated playlist.
///
/// Example usage:
///
/// let summary: MReplaySummary = ...
/// let summary: MusicSummarySearch = ...
/// print("Year: \(summary.year), Playlist: \(summary.playlist)")
///
public struct MReplaySummary: Decodable, MusicItem {
public struct MusicSummarySearch: Decodable, MusicItem {

/// The unique identifier of the `MReplaySummary`.
///
Expand Down Expand Up @@ -60,7 +60,7 @@ public struct MReplaySummary: Decodable, MusicItem {
public let playlist: Playlist
}

extension MReplaySummary {
extension MusicSummarySearch {
enum CodingKeys: String, CodingKey {
case id, attributes, relationships
}
Expand All @@ -74,7 +74,7 @@ extension MReplaySummary {
}
}

extension MReplaySummary {
extension MusicSummarySearch {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let attributesContainer = try container.nestedContainer(keyedBy: AttributesKeys.self, forKey: .attributes)
Expand Down
99 changes: 99 additions & 0 deletions Sources/MusanovaKit/Replay/MusicSummarySearchRequest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//
// MusicSummarySearchRequest.swift
// MusanovaKit
//
// Created by Rudrank Riyam on 04/04/23.
//

import Foundation

public extension MReplay {
/// Searches music summaries for the user's library.
///
/// Use this method to search music summary playlists over the years.
///
/// Example usage:
///
/// do {
/// let summaries = try await MReplay.searchSummaries(developerToken: "your_developer_token")
///
/// for summary in summaries {
/// print("Year: \(summary.year), Playlist: \(summary.playlist)")
/// }
/// } catch {
/// print(error)
/// }
///
/// - Parameters:
/// - developerToken: The developer token used to authorize the request.
///
/// - Returns: An instance of `MusicSummarySearches` containing the search results for music summary data for the user's library.
///
/// - Throws: An error of type `URLError` or `DecodingError` if the request fails or the response cannot be decoded.
static func searchSummaries(developerToken: String) async throws -> MusicSummarySearches {
let request = MusicSummarySearchRequest(developerToken: developerToken)
let response = try await request.response()
return response
}
}

/// A request that your app uses to fetch music summaries for the user's library.
///
/// Use this request to fetch music summary data for the user's library, such as their most frequently played songs, albums, and playlists over the course of a year.
/// After creating an instance of this request, call the `response()` method to retrieve the music summary data for the user's library.
struct MusicSummarySearchRequest {

/// The developer token used to authorize the request.
private var developerToken: String

/// Initializes a new `MusicSummarySearchRequest` instance.
///
/// - Parameter developerToken: The priviledged developer token used to authorize the request.
init(developerToken: String) {
self.developerToken = developerToken
}

/// Fetches music summaries for the user's library.
///
/// - Returns: An instance of `MusicSummarySearches` containing the music summary data for the user's library.
/// - Throws: An error of type `URLError` or `DecodingError` if the request fails or the response cannot be decoded.
///
/// Example usage:
///
/// let request = MusicSummarySearchRequest(developerToken: "your_developer_token")
/// do {
/// let summaries = try await request.response()
///
/// for summary in summaries {
/// print("Year: \(summary.year), Playlist: \(summary.playlist)")
/// }
/// } catch {
/// print(error)
/// }
func response() async throws -> MusicSummarySearches {
let url = try musicSummariesSeaarhEndpointURL
let request = MPriviledgedDataRequest(url: url, developerToken: developerToken)
let response = try await request.response()
return try JSONDecoder().decode(MusicSummarySearches.self, from: response.data)
}
}

extension MusicSummarySearchRequest {
internal var musicSummariesSeaarhEndpointURL: URL {
get throws {
var components = AppleMusicAMPURLComponents()
components.path = "me/music-summaries/search"

components.queryItems = [
URLQueryItem(name: "period", value: "year"),
URLQueryItem(name: "fields[music-summaries]", value: "period,year"),
URLQueryItem(name: "include[music-summaries]", value: "playlist")
]

guard let url = components.url else {
throw URLError(.badURL)
}
return url
}
}
}
21 changes: 21 additions & 0 deletions Sources/MusanovaKit/Replay/MusicSummarySearches.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// MusicSummarySearches.swift
// MusanoveKit
//
// Created by Rudrank Riyam on 04/04/23.
//

/// A collection of MusicSummarySearch objects.
///
/// The MusicSummarySearches typealias is a convenient way to represent a collection
/// of MusicSummarySearch objects. It uses MusicKit's MusicItemCollection to store
/// and manage the collection.
///
/// Example usage:
///
/// let summaries: MusicSummarySearches = ...
/// for summary in summaries {
/// print("Year: \(summary.year), Playlist: \(summary.playlist)")
/// }
///
public typealias MusicSummarySearches = MusicItemCollection<MusicSummarySearch>
8 changes: 4 additions & 4 deletions Tests/MusanovaKitTests/MReplaySummariesTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import XCTest

final class MReplaySummariesTests: XCTestCase {
func testMusicSummariesEndpointURL() throws {
let request = MSummariesRequest(developerToken: "")
let endpointURL = try request.musicSummariesEndpointURL
let request = MusicSummarySearchRequest(developerToken: "")
let endpointURL = try request.musicSummariesSeaarhEndpointURL
let url = "https://amp-api.music.apple.com/v1/me/music-summaries/search?period=year&fields[music-summaries]=period,year&include[music-summaries]=playlist"
XCTAssertEqualEndpoint(endpointURL, url)
}
Expand All @@ -25,12 +25,12 @@ final class MReplaySummariesTests: XCTestCase {
// let url = URL(fileURLWithPath: path)
//
// let data = try Data(contentsOf: url)
// let summaries = try JSONDecoder().decode(MReplaySummaries.self, from: data)
// let summaries = try JSONDecoder().decode(MusicSummarySearches.self, from: data)
//
// XCTAssertEqual(summaries.count, 9)
// XCTAssertEqual(summaries.first?.year, 2016)
//
// // Assert that the `playlist` property of the `MReplaySummary` is decoded correctly
// // Assert that the `playlist` property of the `MusicSummarySearch` is decoded correctly
// let playlist = summaries.first?.playlist
// XCTAssertNotNil(playlist)
// XCTAssertEqual(playlist?.id, "pl.rp-bppRCjG6wWzB")
Expand Down

0 comments on commit d0a462e

Please sign in to comment.