Skip to content

Commit

Permalink
feat: init artist search
Browse files Browse the repository at this point in the history
  • Loading branch information
angristan committed Jul 8, 2021
1 parent 8953b37 commit 88092bb
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 7 deletions.
8 changes: 8 additions & 0 deletions firstfm.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
82D5B4D42696DC7800716931 /* RecentTracks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82D5B4D32696DC7800716931 /* RecentTracks.swift */; };
82D5B4D62696E0E100716931 /* ScrobbledTrackRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82D5B4D52696E0E100716931 /* ScrobbledTrackRowView.swift */; };
82E80C39269777C60098DC3C /* SwiftUIRefresh in Frameworks */ = {isa = PBXBuildFile; productRef = 82E80C38269777C60098DC3C /* SwiftUIRefresh */; };
82F0D54D2697AAC7007CEA98 /* SearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82F0D54C2697AAC7007CEA98 /* SearchViewModel.swift */; };
82F0D54F2697AC66007CEA98 /* ArtistSearch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82F0D54E2697AC66007CEA98 /* ArtistSearch.swift */; };
82FBAE472674B8FC000D8E29 /* Artist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82FBAE462674B8FC000D8E29 /* Artist.swift */; };
82FBAE492674BB55000D8E29 /* ChartViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82FBAE482674BB55000D8E29 /* ChartViewModel.swift */; };
82FBAE4C2674BCB7000D8E29 /* ArtistResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82FBAE4B2674BCB7000D8E29 /* ArtistResponse.swift */; };
Expand Down Expand Up @@ -76,6 +78,8 @@
82D5B4D12696DBD700716931 /* ScrobblesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrobblesViewModel.swift; sourceTree = "<group>"; };
82D5B4D32696DC7800716931 /* RecentTracks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentTracks.swift; sourceTree = "<group>"; };
82D5B4D52696E0E100716931 /* ScrobbledTrackRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrobbledTrackRowView.swift; sourceTree = "<group>"; };
82F0D54C2697AAC7007CEA98 /* SearchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchViewModel.swift; sourceTree = "<group>"; };
82F0D54E2697AC66007CEA98 /* ArtistSearch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArtistSearch.swift; sourceTree = "<group>"; };
82FBAE462674B8FC000D8E29 /* Artist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Artist.swift; sourceTree = "<group>"; };
82FBAE482674BB55000D8E29 /* ChartViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChartViewModel.swift; sourceTree = "<group>"; };
82FBAE4B2674BCB7000D8E29 /* ArtistResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArtistResponse.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -192,6 +196,7 @@
82A006BB2679631A0009BD71 /* TopTracksResponseContainer.swift */,
821493A32694C427007A21C8 /* UserInfoResponse.swift */,
82D5B4D32696DC7800716931 /* RecentTracks.swift */,
82F0D54E2697AC66007CEA98 /* ArtistSearch.swift */,
);
path = API;
sourceTree = "<group>";
Expand All @@ -203,6 +208,7 @@
820455DF267ABC930009A418 /* AuthViewModel.swift */,
8214939F2694C349007A21C8 /* UserViewModel.swift */,
82D5B4D12696DBD700716931 /* ScrobblesViewModel.swift */,
82F0D54C2697AAC7007CEA98 /* SearchViewModel.swift */,
);
path = ViewModel;
sourceTree = "<group>";
Expand Down Expand Up @@ -319,7 +325,9 @@
82A006B8267960D90009BD71 /* Track.swift in Sources */,
82A006BC2679631A0009BD71 /* TopTracksResponseContainer.swift in Sources */,
82505CE72675300400CCCB58 /* ArtistSearchResponse.swift in Sources */,
82F0D54D2697AAC7007CEA98 /* SearchViewModel.swift in Sources */,
82D5B4D22696DBD700716931 /* ScrobblesViewModel.swift in Sources */,
82F0D54F2697AC66007CEA98 /* ArtistSearch.swift in Sources */,
82A006BE2679636F0009BD71 /* TrackSearchResponse.swift in Sources */,
820455E0267ABC930009A418 /* AuthViewModel.swift in Sources */,
820455DC267AA8E70009A418 /* LoginView.swift in Sources */,
Expand Down
22 changes: 22 additions & 0 deletions firstfm/Data/Entities/API/ArtistSearch.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// ArtistSearch.swift
// firstfm
//
// Created by Stanislas Lange on 08/07/2021.
//

import Foundation

struct ArtistSearchResponse: Codable {
let results: ArtistSearchResult
}

// MARK: - Results
struct ArtistSearchResult: Codable {
let artistmatches: Artistmatches
}

// MARK: - Artistmatches
struct Artistmatches: Codable {
let artist: [Artist]
}
2 changes: 1 addition & 1 deletion firstfm/Data/Entities/Artist.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ struct Artist: Codable, Identifiable {

var mbid: String
var name: String
var playcount: String
var playcount: String?
var listeners: String
var image: [LastFMImage]
}
Expand Down
23 changes: 21 additions & 2 deletions firstfm/Data/ViewModel/ChartViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,16 @@ class ChartViewModel: ObservableObject {
do{
let jsonResponse = try JSONDecoder().decode(ArtistResponse.self, from: data)

var artists = jsonResponse.artists.artist

for (index, _) in artists.enumerated() {
if artists[index].image[0].url == "" {
artists[index].image[0].url = "https://lastfm.freetls.fastly.net/i/u/64s/4128a6eb29f94943c9d206c08e625904.webp"
}
}

DispatchQueue.main.async {
self.artists = jsonResponse.artists.artist
self.artists = artists
// Let's stop the loader, the images will be loaded aynchronously
self.isLoading = false
}
Expand Down Expand Up @@ -105,7 +113,18 @@ class ChartViewModel: ObservableObject {
let jsonResponse = try JSONDecoder().decode(SpotifyArtistSearchResponse.self, from: data)

// TODO: match image sizes
completion(jsonResponse.artists.items[0].images[0].url)
if jsonResponse.artists.items.count > 0 {
if jsonResponse.artists.items[0].images.count > 0 {
print(jsonResponse.artists.items[0].images[0].url)
completion(jsonResponse.artists.items[0].images[0].url)
} else {
completion("https://lastfm.freetls.fastly.net/i/u/64s/4128a6eb29f94943c9d206c08e625904.webp")
}
} else {
completion("https://lastfm.freetls.fastly.net/i/u/64s/4128a6eb29f94943c9d206c08e625904.webp")
}


}
}
}
Expand Down
1 change: 0 additions & 1 deletion firstfm/Data/ViewModel/ScrobblesViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ class ScrobblesViewModel: ObservableObject {
// TODO: match image sizes
if jsonResponse.tracks.items.count > 0 {
if jsonResponse.tracks.items[0].album.images.count > 0 {
print("ok")
print(jsonResponse.tracks.items[0].album.images[0].url)
completion(jsonResponse.tracks.items[0].album.images[0].url)
}
Expand Down
79 changes: 79 additions & 0 deletions firstfm/Data/ViewModel/SearchViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//
// SearchViewModel.swift
// firstfm
//
// Created by Stanislas Lange on 08/07/2021.
//

import Foundation

class SearchViewModel: ObservableObject {
@Published var artists: [Artist] = []
var isLoading = false

// swiftlint:disable force_cast
let lastFMAPIKey = Bundle.main.object(forInfoDictionaryKey: "LastFMAPIKey") as! String

func searchForArtist(artist: String) {
self.isLoading = true

var request = URLRequest(url: URL(string: "https://ws.audioscrobbler.com/2.0/?format=json")!)

let data : Data = "api_key=\(lastFMAPIKey)&method=artist.search&artist=\(artist)".data(using: .utf8)!

request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField:"Content-Type");
request.httpBody = data

URLSession.shared.dataTask(with: request) { (data, response, error) -> Void in
do {
if let response = response {
let nsHTTPResponse = response as? HTTPURLResponse
if let statusCode = nsHTTPResponse?.statusCode {
print ("status code = \(statusCode)")
}
// TODO
}
if let error = error {
print (error)
// TODO
}
if let data = data {
do{
let jsonResponse = try JSONDecoder().decode(ArtistSearchResponse.self, from: data)


var artists = jsonResponse.results.artistmatches.artist

for (index, _) in artists.enumerated() {
if artists[index].image[0].url == "" {
artists[index].image[0].url = "https://lastfm.freetls.fastly.net/i/u/64s/4128a6eb29f94943c9d206c08e625904.webp"
}
}

DispatchQueue.main.async {
self.artists = artists
// Let's stop the loader, the images will be loaded aynchronously
self.isLoading = false
}

for (index, artist) in jsonResponse.results.artistmatches.artist.enumerated() {
// Get image URL for each artist and trigger a View update through the observed object
ChartViewModel().getImageForArtist(artistName: artist.name) { imageURL in
if let imageURL = imageURL {
DispatchQueue.main.async {
self.artists[index].image[0].url = imageURL
}
}
}
}
}
}
}
catch {
print(error)
// TODO
}
}.resume()
}
}
18 changes: 15 additions & 3 deletions firstfm/Views/SearchView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import SwiftUI

struct SearchView: View {

@ObservedObject var search = SearchViewModel()
@State var searchString: String = ""

var body: some View {
Expand All @@ -22,12 +22,24 @@ struct SearchView: View {
Image(systemName: "magnifyingglass")
}
}.padding()
Spacer()
List {
ForEach(search.artists) { artist in
ZStack {
Button("") {}
NavigationLink(
destination: ArtistView(artist: artist),
label: {
ArtistRow(artist: artist)
})
}
}
}
}
}

func performSearch() {

print("searching for \(searchString)")
self.search.searchForArtist(artist: searchString)
}
}

Expand Down

0 comments on commit 88092bb

Please sign in to comment.