Code Monkey home page Code Monkey logo

spartan's People

Contributors

daltron avatar gustavo-carvalho avatar mindaugasjucius avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spartan's Issues

Suddenly Spartan started crashing my app

I'm not sure if something changed in Spotify API, but performing some requests causes bad crashes. For example, requesting a track with func getTrack(id: String returns invalid object with missing values, for example durationMs is nil, but it never should be. A lot of users are reporting that app started crashing.

Zrzut ekranu 2020-04-12 o 10 38 30

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

I am executing the following code and I am getting a Fatal error: Unexpectedly found nil while unwrapping an Optional value that references line 57 of SpartanError. Please see the following screenshot for more detailed thread information. This is the only function that does this. It appears that the SpartanError is trying to map a status code and that it is actually nil. Any help on this would be great.

determineErrorType(statusCode: statusCode)

Code

_ = Spartan.getAudioFeatures(trackIds: tracksIDs, success: { (audioFeatures) in
       print(audioFeatures.first?.tempo)
}, failure: { (error) in
	Logger.error(error)
})

Console Output

🔵 [AlamoRecordLogger] GET https://api.spotify.com/v1/audio-features?ids=7sO5G9EABYOXQKNPNiE9NR%2C0NKh1STZG1VgnVwntJF3ze%2C4dVpf9jZjcORqGTLUaeYj9%2C2Xqd0wUttjueBfdcltADOv%2C0Gux2yTMWYOlcBUNjGJu5p%2C2vjmyyAnDUzilFYxOlTdO1%2C1OmcAT5Y8eg5bUPv9qJT4R%2C6foxplXS0YEq8cO374Lty4%2C5u6vkDnOyaf8LsteDAj2ub%2C1XRgIKC5TPwo7nWGyKqgG0%2C7zLGHiDWd9T1Rxw4PQCb13%2C1YZfcVLbbJwfizR5cDOp3q%2C7r6LNJT2LqpLpEyZQJPygt%2C57IRaiAB4hBZu3gnNVZC0v%2C6GNifiuBPrKFpwNBYnooFm%2C3ncgNpxLoBQ65ABk4djDyd%2C2vaMWMPMgsWX4fwJiKmdWm%2C0taOCiup4HNG9LmbduVlJj%2C59J5nzL1KniFHnU120dQzt%2C4EsYkJjHKMejYLp54woB9c
⚪️ [AlamoRecordLogger] GET https://api.spotify.com/v1/audio-features?ids=7sO5G9EABYOXQKNPNiE9NR%2C0NKh1STZG1VgnVwntJF3ze%2C4dVpf9jZjcORqGTLUaeYj9%2C2Xqd0wUttjueBfdcltADOv%2C0Gux2yTMWYOlcBUNjGJu5p%2C2vjmyyAnDUzilFYxOlTdO1%2C1OmcAT5Y8eg5bUPv9qJT4R%2C6foxplXS0YEq8cO374Lty4%2C5u6vkDnOyaf8LsteDAj2ub%2C1XRgIKC5TPwo7nWGyKqgG0%2C7zLGHiDWd9T1Rxw4PQCb13%2C1YZfcVLbbJwfizR5cDOp3q%2C7r6LNJT2LqpLpEyZQJPygt%2C57IRaiAB4hBZu3gnNVZC0v%2C6GNifiuBPrKFpwNBYnooFm%2C3ncgNpxLoBQ65ABk4djDyd%2C2vaMWMPMgsWX4fwJiKmdWm%2C0taOCiup4HNG9LmbduVlJj%2C59J5nzL1KniFHnU120dQzt%2C4EsYkJjHKMejYLp54woB9c (200 OK) 16.6 seconds
(lldb) 

Edited 11/15/17

Request Output
I ran the request in a Paw and I got the following output. As you can see the second element is null. The Spotify API documentation states, "If an object is not found, a null value is returned in the appropriate position. " The track exists in the Spotify library, however audio features for it do not exist. It is possible that Spartan is not properly handling this null value and is searching for an error code that does not exist (because the request was successful) hence the unexpected nil value. Is there a way to get the output of all non null values?

{
  "audio_features": [
    {
      "danceability": 0.880,
      "energy": 0.428,
      "key": 9,
      "loudness": -8.280,
      "mode": 1,
      "speechiness": 0.206,
      "acousticness": 0.149,
      "instrumentalness": 0.0000507,
      "liveness": 0.114,
      "valence": 0.333,
      "tempo": 100.007,
      "type": "audio_features",
      "id": "7sO5G9EABYOXQKNPNiE9NR",
      "uri": "spotify:track:7sO5G9EABYOXQKNPNiE9NR",
      "track_href": "https://api.spotify.com/v1/tracks/7sO5G9EABYOXQKNPNiE9NR",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/7sO5G9EABYOXQKNPNiE9NR",
      "duration_ms": 172800,
      "time_signature": 4
    },
    null,
    {
      "danceability": 0.797,
      "energy": 0.844,
      "key": 11,
      "loudness": -5.482,
      "mode": 1,
      "speechiness": 0.275,
      "acousticness": 0.0651,
      "instrumentalness": 0,
      "liveness": 0.0870,
      "valence": 0.520,
      "tempo": 170.142,
      "type": "audio_features",
      "id": "4dVpf9jZjcORqGTLUaeYj9",
      "uri": "spotify:track:4dVpf9jZjcORqGTLUaeYj9",
      "track_href": "https://api.spotify.com/v1/tracks/4dVpf9jZjcORqGTLUaeYj9",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/4dVpf9jZjcORqGTLUaeYj9",
      "duration_ms": 173600,
      "time_signature": 4
    },
    {
      "danceability": 0.837,
      "energy": 0.791,
      "key": 1,
      "loudness": -3.824,
      "mode": 1,
      "speechiness": 0.251,
      "acousticness": 0.0199,
      "instrumentalness": 0,
      "liveness": 0.0836,
      "valence": 0.379,
      "tempo": 176.003,
      "type": "audio_features",
      "id": "2Xqd0wUttjueBfdcltADOv",
      "uri": "spotify:track:2Xqd0wUttjueBfdcltADOv",
      "track_href": "https://api.spotify.com/v1/tracks/2Xqd0wUttjueBfdcltADOv",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/2Xqd0wUttjueBfdcltADOv",
      "duration_ms": 211006,
      "time_signature": 4
    },
    {
      "danceability": 0.595,
      "energy": 0.431,
      "key": 10,
      "loudness": -7.282,
      "mode": 1,
      "speechiness": 0.486,
      "acousticness": 0.0101,
      "instrumentalness": 0.0000703,
      "liveness": 0.164,
      "valence": 0.107,
      "tempo": 125.200,
      "type": "audio_features",
      "id": "0Gux2yTMWYOlcBUNjGJu5p",
      "uri": "spotify:track:0Gux2yTMWYOlcBUNjGJu5p",
      "track_href": "https://api.spotify.com/v1/tracks/0Gux2yTMWYOlcBUNjGJu5p",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/0Gux2yTMWYOlcBUNjGJu5p",
      "duration_ms": 227707,
      "time_signature": 3
    },
    {
      "danceability": 0.689,
      "energy": 0.761,
      "key": 1,
      "loudness": -4.939,
      "mode": 1,
      "speechiness": 0.130,
      "acousticness": 0.0485,
      "instrumentalness": 0,
      "liveness": 0.136,
      "valence": 0.698,
      "tempo": 78.514,
      "type": "audio_features",
      "id": "2vjmyyAnDUzilFYxOlTdO1",
      "uri": "spotify:track:2vjmyyAnDUzilFYxOlTdO1",
      "track_href": "https://api.spotify.com/v1/tracks/2vjmyyAnDUzilFYxOlTdO1",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/2vjmyyAnDUzilFYxOlTdO1",
      "duration_ms": 157643,
      "time_signature": 4
    },
    {
      "danceability": 0.580,
      "energy": 0.531,
      "key": 5,
      "loudness": -6.631,
      "mode": 0,
      "speechiness": 0.0776,
      "acousticness": 0.128,
      "instrumentalness": 0.000127,
      "liveness": 0.143,
      "valence": 0.141,
      "tempo": 159.786,
      "type": "audio_features",
      "id": "1OmcAT5Y8eg5bUPv9qJT4R",
      "uri": "spotify:track:1OmcAT5Y8eg5bUPv9qJT4R",
      "track_href": "https://api.spotify.com/v1/tracks/1OmcAT5Y8eg5bUPv9qJT4R",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/1OmcAT5Y8eg5bUPv9qJT4R",
      "duration_ms": 218320,
      "time_signature": 4
    },
    {
      "danceability": 0.950,
      "energy": 0.533,
      "key": 5,
      "loudness": -7.022,
      "mode": 1,
      "speechiness": 0.148,
      "acousticness": 0.247,
      "instrumentalness": 0,
      "liveness": 0.114,
      "valence": 0.675,
      "tempo": 119.869,
      "type": "audio_features",
      "id": "6foxplXS0YEq8cO374Lty4",
      "uri": "spotify:track:6foxplXS0YEq8cO374Lty4",
      "track_href": "https://api.spotify.com/v1/tracks/6foxplXS0YEq8cO374Lty4",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/6foxplXS0YEq8cO374Lty4",
      "duration_ms": 124056,
      "time_signature": 4
    },
    {
      "danceability": 0.782,
      "energy": 0.436,
      "key": 2,
      "loudness": -7.033,
      "mode": 1,
      "speechiness": 0.155,
      "acousticness": 0.331,
      "instrumentalness": 0.0000130,
      "liveness": 0.342,
      "valence": 0.243,
      "tempo": 82.994,
      "type": "audio_features",
      "id": "5u6vkDnOyaf8LsteDAj2ub",
      "uri": "spotify:track:5u6vkDnOyaf8LsteDAj2ub",
      "track_href": "https://api.spotify.com/v1/tracks/5u6vkDnOyaf8LsteDAj2ub",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/5u6vkDnOyaf8LsteDAj2ub",
      "duration_ms": 268933,
      "time_signature": 4
    },
    {
      "danceability": 0.890,
      "energy": 0.633,
      "key": 11,
      "loudness": -5.475,
      "mode": 1,
      "speechiness": 0.168,
      "acousticness": 0.0232,
      "instrumentalness": 0.000343,
      "liveness": 0.0993,
      "valence": 0.425,
      "tempo": 139.948,
      "type": "audio_features",
      "id": "1XRgIKC5TPwo7nWGyKqgG0",
      "uri": "spotify:track:1XRgIKC5TPwo7nWGyKqgG0",
      "track_href": "https://api.spotify.com/v1/tracks/1XRgIKC5TPwo7nWGyKqgG0",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/1XRgIKC5TPwo7nWGyKqgG0",
      "duration_ms": 233087,
      "time_signature": 4
    },
    {
      "danceability": 0.577,
      "energy": 0.593,
      "key": 9,
      "loudness": -4.816,
      "mode": 0,
      "speechiness": 0.137,
      "acousticness": 0.800,
      "instrumentalness": 0,
      "liveness": 0.623,
      "valence": 0.575,
      "tempo": 120.611,
      "type": "audio_features",
      "id": "7zLGHiDWd9T1Rxw4PQCb13",
      "uri": "spotify:track:7zLGHiDWd9T1Rxw4PQCb13",
      "track_href": "https://api.spotify.com/v1/tracks/7zLGHiDWd9T1Rxw4PQCb13",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/7zLGHiDWd9T1Rxw4PQCb13",
      "duration_ms": 303781,
      "time_signature": 5
    },
    {
      "danceability": 0.901,
      "energy": 0.529,
      "key": 2,
      "loudness": -4.443,
      "mode": 1,
      "speechiness": 0.191,
      "acousticness": 0.0519,
      "instrumentalness": 0,
      "liveness": 0.179,
      "valence": 0.146,
      "tempo": 138.003,
      "type": "audio_features",
      "id": "1YZfcVLbbJwfizR5cDOp3q",
      "uri": "spotify:track:1YZfcVLbbJwfizR5cDOp3q",
      "track_href": "https://api.spotify.com/v1/tracks/1YZfcVLbbJwfizR5cDOp3q",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/1YZfcVLbbJwfizR5cDOp3q",
      "duration_ms": 307660,
      "time_signature": 4
    },
    {
      "danceability": 0.860,
      "energy": 0.561,
      "key": 6,
      "loudness": -5.757,
      "mode": 0,
      "speechiness": 0.185,
      "acousticness": 0.274,
      "instrumentalness": 0,
      "liveness": 0.108,
      "valence": 0.354,
      "tempo": 152.984,
      "type": "audio_features",
      "id": "7r6LNJT2LqpLpEyZQJPygt",
      "uri": "spotify:track:7r6LNJT2LqpLpEyZQJPygt",
      "track_href": "https://api.spotify.com/v1/tracks/7r6LNJT2LqpLpEyZQJPygt",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/7r6LNJT2LqpLpEyZQJPygt",
      "duration_ms": 189480,
      "time_signature": 4
    },
    {
      "danceability": 0.658,
      "energy": 0.736,
      "key": 9,
      "loudness": -6.097,
      "mode": 0,
      "speechiness": 0.308,
      "acousticness": 0.113,
      "instrumentalness": 0,
      "liveness": 0.0978,
      "valence": 0.804,
      "tempo": 143.966,
      "type": "audio_features",
      "id": "57IRaiAB4hBZu3gnNVZC0v",
      "uri": "spotify:track:57IRaiAB4hBZu3gnNVZC0v",
      "track_href": "https://api.spotify.com/v1/tracks/57IRaiAB4hBZu3gnNVZC0v",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/57IRaiAB4hBZu3gnNVZC0v",
      "duration_ms": 160000,
      "time_signature": 4
    },
    {
      "danceability": 0.749,
      "energy": 0.671,
      "key": 6,
      "loudness": -5.151,
      "mode": 1,
      "speechiness": 0.0599,
      "acousticness": 0.680,
      "instrumentalness": 0,
      "liveness": 0.167,
      "valence": 0.756,
      "tempo": 81.994,
      "type": "audio_features",
      "id": "6GNifiuBPrKFpwNBYnooFm",
      "uri": "spotify:track:6GNifiuBPrKFpwNBYnooFm",
      "track_href": "https://api.spotify.com/v1/tracks/6GNifiuBPrKFpwNBYnooFm",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/6GNifiuBPrKFpwNBYnooFm",
      "duration_ms": 268864,
      "time_signature": 4
    },
    {
      "danceability": 0.921,
      "energy": 0.467,
      "key": 1,
      "loudness": -8.443,
      "mode": 1,
      "speechiness": 0.119,
      "acousticness": 0.0149,
      "instrumentalness": 0.000238,
      "liveness": 0.334,
      "valence": 0.287,
      "tempo": 135.995,
      "type": "audio_features",
      "id": "3ncgNpxLoBQ65ABk4djDyd",
      "uri": "spotify:track:3ncgNpxLoBQ65ABk4djDyd",
      "track_href": "https://api.spotify.com/v1/tracks/3ncgNpxLoBQ65ABk4djDyd",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/3ncgNpxLoBQ65ABk4djDyd",
      "duration_ms": 191252,
      "time_signature": 4
    },
    {
      "danceability": 0.717,
      "energy": 0.753,
      "key": 7,
      "loudness": -4.609,
      "mode": 0,
      "speechiness": 0.311,
      "acousticness": 0.293,
      "instrumentalness": 0,
      "liveness": 0.158,
      "valence": 0.631,
      "tempo": 169.857,
      "type": "audio_features",
      "id": "2vaMWMPMgsWX4fwJiKmdWm",
      "uri": "spotify:track:2vaMWMPMgsWX4fwJiKmdWm",
      "track_href": "https://api.spotify.com/v1/tracks/2vaMWMPMgsWX4fwJiKmdWm",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/2vaMWMPMgsWX4fwJiKmdWm",
      "duration_ms": 174012,
      "time_signature": 4
    },
    {
      "danceability": 0.721,
      "energy": 0.710,
      "key": 7,
      "loudness": -9.294,
      "mode": 1,
      "speechiness": 0.295,
      "acousticness": 0.000655,
      "instrumentalness": 0,
      "liveness": 0.359,
      "valence": 0.509,
      "tempo": 108.024,
      "type": "audio_features",
      "id": "0taOCiup4HNG9LmbduVlJj",
      "uri": "spotify:track:0taOCiup4HNG9LmbduVlJj",
      "track_href": "https://api.spotify.com/v1/tracks/0taOCiup4HNG9LmbduVlJj",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/0taOCiup4HNG9LmbduVlJj",
      "duration_ms": 156057,
      "time_signature": 5
    },
    {
      "danceability": 0.785,
      "energy": 0.622,
      "key": 8,
      "loudness": -6.741,
      "mode": 1,
      "speechiness": 0.254,
      "acousticness": 0.0133,
      "instrumentalness": 0,
      "liveness": 0.154,
      "valence": 0.466,
      "tempo": 78.475,
      "type": "audio_features",
      "id": "59J5nzL1KniFHnU120dQzt",
      "uri": "spotify:track:59J5nzL1KniFHnU120dQzt",
      "track_href": "https://api.spotify.com/v1/tracks/59J5nzL1KniFHnU120dQzt",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/59J5nzL1KniFHnU120dQzt",
      "duration_ms": 235535,
      "time_signature": 4
    },
    {
      "danceability": 0.930,
      "energy": 0.673,
      "key": 10,
      "loudness": -7.314,
      "mode": 0,
      "speechiness": 0.0733,
      "acousticness": 0.0112,
      "instrumentalness": 0,
      "liveness": 0.138,
      "valence": 0.219,
      "tempo": 134.984,
      "type": "audio_features",
      "id": "4EsYkJjHKMejYLp54woB9c",
      "uri": "spotify:track:4EsYkJjHKMejYLp54woB9c",
      "track_href": "https://api.spotify.com/v1/tracks/4EsYkJjHKMejYLp54woB9c",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/4EsYkJjHKMejYLp54woB9c",
      "duration_ms": 188563,
      "time_signature": 4
    }
  ]
}

SpartanError: Insufficient client scope

I'm trying to create a playlist for the current user and received the error "SpartanError: Insufficient client scope". I have a valid auth token that I refresh and can get the current user's info fine. The scopes I have selected are:
static let SCOPE = ["user-read-email", "user-top-read", "playlist-modify-public", "playlist-modify-private"]

My Code for token request:

static func accessCodeToAccessToken(code: String, completion: @escaping (Result<Tokens, Error>) -> Void) -> Request {
        
        Request.buildRequest(method: .post,
                             header: Header.POSTHeader.buildHeader(),
                             baseURL: SpotifyBaseURL.authBaseURL.rawValue,
                             path: EndingPath.token.buildPath(),
                             params: Parameters.codeForToken(accessCode: code).buildParameters()) { (result) in
            
            result.decoding(Tokens.self, completion: completion)
        }
    }

My code calling request in view controller:

private func getSpotifyAccessCode() {

        let urlRequest = client.getSpotifyAccessCodeURL()
        print(urlRequest)
        let scheme = "auth"
        let session = ASWebAuthenticationSession(url: urlRequest, callbackURLScheme: scheme) { (callbackURL, error) in
            guard error == nil, let callbackURL = callbackURL else { return }

            let queryItems = URLComponents(string: callbackURL.absoluteString)?.queryItems
            guard let requestAccessCode = queryItems?.first(where: { $0.name == "code" })?.value else { return }
            print(" Code \(requestAccessCode)")
            // exchanges access code to get access token and refresh token
            self.client.call(request: .accessCodeToAccessToken(code: requestAccessCode, completion: { (token) in
                switch token {

                case .failure(let error):
                    print("ERROR: ", error)
                case .success(let token):
                    UserDefaults.standard.set(token.accessToken, forKey: "token")
                    UserDefaults.standard.set(token.refreshToken, forKey: "refresh_token")
                    print("SUCCESS")
                    
                    DispatchQueue.main.async {
                        self.goToApp()
                    }
                }
            }))

        }

        session.presentationContextProvider = self
        session.start()

    }

Create playlist code:

 func createPlaylist(user: UserModel) {
        
        let name = "Test"
        
        let createPlaylist = Spartan.createPlaylist(userId: user.id, name: name, isPublic: true) { (playlist) in
            print("PLAYLIST CREATED")
            
        } failure: { (error) in
            print("Error creating playlist: ", error)
        }

    }

Sorry if this isn't enough information please let me know.

Playlist Image Issue

Hi Daltron,

I found an issue with playlist images. After getting root user's playlists using Spartan.getMyPlaylists(), for playlists that don't have an image, I get a random image from one of my other playlists. Moreover, all playlists after that one return random images from other playlists even though they have their own image on Spotify. Any help on this would be much appreciated!

Thanks :)

Using `getArtists` method causes crash

I was using the getArtists(ids: [String]...) method with chunks of artist identifiers, each counting 50, as API states that's the limit and in some cases the app crashes. See attached screenshot.

Zrzut ekranu 2020-04-12 o 10 38 30

The crash is only happening with some artists, as users reported. Not all of them experienced the crash.

Search: pagingObject.canMakeNextRequest condition does not work

Hi,
Yesterday the pagingObject.canMakeNextRequest condition stopped working as expected.

It does end at offset=850 but according to the Spotify Web API Console there should be a total of 95902 results.

If I remove the canMakeNextRequest condition and call searchNewAlbums regardless of this value, it runs to the 10000 offset limit just fine.

Here is the code snippet:

 _ = Spartan.search(query: "tag:new", type: .album, market: .de, limit: 50, offset: offset, success: { (pagingObject: PagingObject<SimplifiedAlbum>) in
            // temporary workaround for null objects in search results
            if (pagingObject.items != nil){
                for album in pagingObject.items {
                        self.releasesIdSet.insert(album.id as! String)
                }
                
                if pagingObject.canMakeNextRequest {
                    self.searchNewAlbums(offset: (offset+pagingObject.limit))
                }
            } else {
                print("PAGING OBJECT == NIL")
                // TODO do error handling
            }
        }, failure: { (error) in
            print(error)
            // TODO do error handling
        })

The last get request until it finishes and there is no error message:
🔵 [AlamoRecordLogger] GET https://api.spotify.com/v1/search?limit=50&market=DE&offset=850&q=tag%3Anew&type=album

And a screenshot from the Web API Console:
bildschirmfoto 2018-10-20 um 09 40 19

Get track id from Paging Object.

I am wondering if there is a way to get the track id from a Paging Object. Here is the method I am using:

playSpotifyURI("spotify:track:" + track, startingWith: 0, startingWithPosition: 0)

This works if track is 58s6EuEYJdlb0kO7awm3Vp

I use this to get an array of tracks:

Spartan.search(query: search, type: .playlist, success:...

This returns a Paging Object which I get the items array from. The items array contains an href which looks like this https://api.spotify.com/v1/users/spotify/playlists/37i9dQZF1DX4y8h9WqDPAE/tracks. Unfortunately this does not contain the exact track id, it only gives the playlist id.

getNext doesn't appear to be working on getMyFollowedArtists

I'm trying to use if object.canMakeNextRequest to get all possible artists returned by getMyFollowedArtists however the second request doesn't appear to be returning an object with any items in it. I've tested my code with the getMyTopArtists method and it works properly. I've also manually changed the limit on getMyFollowedArtists to ensure that the API will return more than the default limit, and it does.

Here's a sample of my code just to see what I am doing.

    var artists: PagingObject<Artist>? {
        didSet {
            print("Added more to artists variable.")
        }
    }

    func grabSpotifyArtists(token: String?) {
        Spartan.authorizationToken = token
        Spartan.loggingEnabled = true
        
        _ = Spartan.getMyFollowedArtists(limit: 10, after: nil, success: { (object) in
            self.artists = object
            self.printArtists()
            self.fetchAllItems()
        }, failure: { (error) in
            print(error)
        })
        

    }
    
    func fetchAllItems() {
        if let artists = self.artists {
            if artists.canMakeNextRequest {
                artists.getNext(success: { (object) in
                    self.artists = object
                    self.printArtists()
                    self.fetchAllItems()
                }) { (error) in
                    print(error)
                }
            }
        }
    }
    
    func printArtists() {
        if let artists = self.artists?.items {
            for artist in artists {
                print(artist.name)
            }
        }
    }

Sample output:

🔵 [AlamoRecordLogger] GET https://api.spotify.com/v1/me/following?type=artist&limit=10
⚪️ [AlamoRecordLogger] GET https://api.spotify.com/v1/me/following?type=artist&limit=10 (200 OK) 0.15 seconds
Added more to artists variable.
Optional("Handsome Furs")
Optional("Nevermen")
Optional("White Denim")
Optional("Quilt")
Optional("The Poison Control Center")
Optional("The Courtneys")
Optional("Meat Wave")
Optional("The Spook School")
Optional("Savages")
Optional("Twin Peaks")
🔵 [AlamoRecordLogger] GET https://api.spotify.com/v1/me/following?type=artist&after=1xD85sp0kecIVuMwUHShxs&limit=10
⚪️ [AlamoRecordLogger] GET https://api.spotify.com/v1/me/following?type=artist&after=1xD85sp0kecIVuMwUHShxs&limit=10 (200 OK) 0.08 seconds
Added more to artists variable.

What I'd expect to happen is the what happens if I use the getMyTopArtists method like so... changed code following way:

    func grabSpotifyArtists(token: String?) {
        Spartan.authorizationToken = token
        Spartan.loggingEnabled = true

        _ = Spartan.getMyTopArtists(limit: 10, offset: 0, timeRange: .longTerm, success: { (object) in
            self.artists = object
            self.printArtists()
            self.fetchAllItems()
        }, failure: { (error) in
            print(error)
        })

    }

Output:

🔵 [AlamoRecordLogger] GET https://api.spotify.com/v1/me/top/artists?limit=10&offset=0&time_range=long_term
⚪️ [AlamoRecordLogger] GET https://api.spotify.com/v1/me/top/artists?limit=10&offset=0&time_range=long_term (200 OK) 0.67 seconds
Added more to artists variable.
Optional("Guided By Voices")
Optional("Lana Del Rey")
Optional("Meat Wave")
Optional("YACHT")
Optional("White Denim")
Optional("Spoon")
Optional("Electric Six")
Optional("Television")
Optional("Quilt")
Optional("Savages")
🔵 [AlamoRecordLogger] GET https://api.spotify.com/v1/me/top/artists?limit=10&offset=10&time_range=long_term
⚪️ [AlamoRecordLogger] GET https://api.spotify.com/v1/me/top/artists?limit=10&offset=10&time_range=long_term (200 OK) 0.19 seconds
Added more to artists variable.
Optional("Sleater-Kinney")
Optional("Queens of the Stone Age")
Optional("Local H")
Optional("Nick Lowe")
Optional("EMA")
Optional("Kishi Bashi")
Optional("Swearin\'")
Optional("BOYTOY")
Optional("Saint Motel")
Optional("Sleigh Bells")
🔵 [AlamoRecordLogger] GET https://api.spotify.com/v1/me/top/artists?limit=10&offset=20&time_range=long_term
⚪️ [AlamoRecordLogger] GET https://api.spotify.com/v1/me/top/artists?limit=10&offset=20&time_range=long_term (200 OK) 0.19 seconds
Added more to artists variable.
Optional("HAIM")
Optional("Wampire")
Optional("White Fence")
Optional("The Spook School")
Optional("Vampire Weekend")
Optional("Wolf Alice")
Optional("Woods")
Optional("Algebra Suicide")
Optional("Foxygen")
Optional("Twin Peaks")
🔵 [AlamoRecordLogger] GET https://api.spotify.com/v1/me/top/artists?limit=10&offset=30&time_range=long_term
⚪️ [AlamoRecordLogger] GET https://api.spotify.com/v1/me/top/artists?limit=10&offset=30&time_range=long_term (200 OK) 0.18 seconds
Added more to artists variable.
Optional("Joanna Gruesome")
Optional("Chastity Belt")
Optional("The High Strung")
Optional("Metz")
Optional("Archie Bronson Outfit")
Optional("Alex Winston")
Optional("Faith No More")
Optional("Posse")
Optional("Todd Terje")
Optional("Museum Mouth")
🔵 [AlamoRecordLogger] GET https://api.spotify.com/v1/me/top/artists?limit=10&offset=40&time_range=long_term
⚪️ [AlamoRecordLogger] GET https://api.spotify.com/v1/me/top/artists?limit=10&offset=40&time_range=long_term (200 OK) 0.18 seconds
Added more to artists variable.
Optional("Andrew Bird")
Optional("Phoenix")
Optional("Evans The Death")
Optional("California X")
Optional("Nine Inch Nails")
Optional("Richard Hell")
Optional("Harry Nilsson")
Optional("FIDLAR")
Optional("Kitten")
Optional("Rockpile")

How to use Spartan

I am creating an app that exports playlists to Spotify. Currently, I have an array of Spotify song URIs. I have no knowledge of how the Spotify SDK works and I was wondering how I would use Spartan to a) set up a connection with the user and 2) create a playlist from the app.

How to get a Playlist object?

I want to access the 'spotifyDescription' of Playlist, however as I searched through the methods, the 'Playlist' class is not even used anywhere.

`getTrack` returns invalid Track object whereas `getTracks` works as expected

When using Spartan method getTrack(id: String...) Track object is received but most of its properties are nil, when I checked the uri of the object it turns out that actually an Album object was received but when Spartan tried to map it to Track most of the properties were nil.

See the Xcode Quicklook of the object
Zrzut ekranu 2020-04-13 o 14 06 43

You can see that the object is in fact an album.
I think I'm calling the method correctly

Zrzut ekranu 2020-04-13 o 14 07 24

Although this method gives wrong results, using getTracks(ids: [String]...) works correctly and I'll be using it to get single tracks from the API

getNext on pagingObject for PlaylistTracks failing

Thank you for creating such an awesome Spotify Client! There's a small issue with getNext being called on a pagingObject dealing with tracks fetched for a playlist. Spartan.getPlaylistTracks() works fine and loads 20 tracks. However after retrieving the pagingObject and calling getNext on it I get fatal error: unexpectedly found nil while unwrapping an Optional value 2017-07-09 19:55:16.220157-0500 Sink[12993:3968613] fatal error: unexpectedly found nil while unwrapping an Optional value. To confirm I called getNext right after fetching the pagingObject as follows ` let _ = Spartan.getPlaylistTracks(userId: userId, playlistId: playlistId, success: { (tracksPage) in

        if tracksPage.canMakeNextRequest {
            tracksPage.getNext(success: { (trackpage) in
                print("successfully fetched \(trackpage)")
            }, failure: { (error) in
                print(error.description)
                print(error.errorMessage)
            })
        }
         //completionHandler(tracksPage)
    }) { (error) in
        print(error.description)
        print(error.errorMessage)
    }

` and I get the error. I've also attached the stack trace below.

I am quite certain you'd be able to recreate the error if you fetch tracks for playlist that has number of songs over the the limit of 1 pagingObject and calling getNext on the pagingObject. Any fix or direction would be greatly appreciated!

screen shot 2017-07-09 at 7 56 24 pm

Swift 4 AlamofireObjectMapper Dependency

Hello,
Just writing to say that the Podfile spec should probably be updated for AlamofireObjectMapper 5 so that users can use swift 4

[!] Unable to satisfy the following requirements:

- `AlamofireObjectMapper (from `https://github.com/tristanhimmelman/AlamofireObjectMapper.git`, branch `swift-4`)` required by `Podfile`
- `AlamofireObjectMapper (= 5.0.0)` required by `Podfile.lock`
- `AlamofireObjectMapper (~> 4.0.1)` required by `Spartan (1.0)`

getTrack() returns a Track only filled with SimplifiedTrack data

Spartan.getTrack(id: "11dFghVXANMlKmJXsNCbNl", success: { (track) in self.currentSong = track // FIXME: gets the album instead of the song self.miniPlayer?.configure(song: self.currentSong) }) { (error) in print("Error while fetching the track: \(error.description)") }
The above code is the one I'm currently using to retrieve a Track, but no album data is filled in it, is this behaviour intentional?

captura de pantalla 2018-11-30 a las 17 44 51

This is the Track returned by Spartan

Using the latest version available in Cocoapods, Swift 4.0 and Xcode 10.1

Example Not working

Kindly share working demo project. This Demo project is completely blank.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.