Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct LyricsMainView: View {
- @State var songName: String = "Adventure of a Lifetime"
- @State var artistName: String = "Coldplay."
- @ObservedObject var viewModel = ViewModel()
- var body: some View {
- HStack {
- Spacer()
- Button(action: {
- viewModel.loadApiSongData(songName: songName, artistName: artistName)
- }, label: {
- Text("Search Lyrics!")
- })
- .alert(isPresented: $viewModel.noConnectionAlert) {
- Alert(title: Text("No internet connection"), message: Text("Oops! It seems you arent connected to the internet. Please connect and try again!"), dismissButton: .default(Text("Got it!")))
- }
- Spacer()
- }
- .padding(.top, 20)
- .sheet(item: $viewModel.apiResponse) { item in
- LyricsView(vm: self.viewModel, songName: songName, artistName: artistName, arrLyrics: item.apiValues)
- }
- }
- }
- struct LyricsView: View {
- var vm: ViewModel
- var songName: String
- var artistName: String
- var arrLyrics: String
- var body: some View {
- VStack {
- Text(songName)
- Text(artistName)
- Text(arrLyrics)
- }
- }
- }
- struct LyricsView_Previews: PreviewProvider {
- static var previews: some View {
- LyricsView(vm: ViewModel(),
- songName: "",
- artistName: "",
- arrLyrics: ""
- )
- }
- }
- class ViewModel : ObservableObject {
- @Published var searchedSongs = [SongDetails]() {
- didSet {
- print(searchedSongs)
- }
- }
- @Published var apiResponse : APIResponse?
- @Published var noConnectionAlert = false
- var apiError: APIError? {
- didSet {
- noConnectionAlert = true
- }
- }
- func loadApiSongData(songName: String, artistName: String) {
- let rawUrl = "https://api.lyrics.ovh/v1/\(artistName)/\(songName)"
- let fixedUrl = rawUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
- print("Old url: \(rawUrl)")
- print("New url: \(fixedUrl!)")
- guard let url = URL(string: fixedUrl!) else {
- print("Invalid URL")
- return
- }
- let request = URLRequest(url: url)
- URLSession.shared.dataTask(with: request) { data, response, error in
- DispatchQueue.main.async {
- self.responseHandler(data, response, error, songName, artistName)
- }
- }.resume()
- }
- private func responseHandler(_ data: Data?,
- _ response: URLResponse?,
- _ error: Error?,
- _ songName: String,
- _ artistName: String) {
- if let error = error {
- if error._code == -1009 {
- apiError = .offline
- } else {
- apiError = .sessionError
- }
- return
- }
- guard let response = response as? HTTPURLResponse, let data = data else {
- apiError = .missingDataError
- return
- }
- guard (200..<300).contains(response.statusCode) else {
- switch Status(rawValue: response.statusCode) {
- case .requestTimeout:
- apiError = .timeoutError
- case .internalServerError:
- apiError = .internalServerError
- case .notFound:
- apiError = .notFound
- default:
- apiError = .requestError
- }
- return
- }
- do {
- let decodedResponse = try JSONDecoder().decode(Song.self, from: data)
- if(!songAlreadySearched(songName: songName)) {
- let song = SongDetails(songName: songName, artistName: artistName, lyrics: decodedResponse.lyrics)
- searchedSongs.append(song)
- }
- apiResponse = APIResponse(apiValues: decodedResponse.lyrics)
- } catch {
- apiError = .parsingError
- }
- }
- func songAlreadySearched(songName: String) -> Bool {
- return false
- }
- }
- struct SongDetails: Decodable {
- var songName: String
- var artistName: String
- var lyrics: String
- }
- struct Song: Decodable {
- var lyrics: String
- }
- struct APIResponse: Identifiable {
- var id: String = UUID().uuidString
- var apiValues: String
- }
- enum APIError: Error {
- case sessionError
- case parsingError
- case missingDataError
- case requestError
- case timeoutError
- case offline
- case internalServerError
- case notFound
- case genericError
- }
- enum Status: Int {
- case multipleChoices = 300
- case badRequest = 400
- case forbidden = 403
- case notFound = 404
- case requestTimeout = 408
- case internalServerError = 500
- case notImplemented = 501
- case badGateway = 502
- case serviceUnavailabe = 503
- case gatewayTimeout = 504
- }
Advertisement
Add Comment
Please, Sign In to add comment