0

The following functions makes an API call which downloads JSON data and passes it into an another function imp, which in turn creates the arrays!

func previewer(var spotify_id : [String])
{
    var serial_number = 0

    for var x in spotify_id
    {
        let spotify_url = "https://api.spotify.com/v1/tracks/"
        let url_with_pars = spotify_url + x
        let myurl_1 = NSURL(string: url_with_pars)
        let timeout = 15
        let request_1 = NSMutableURLRequest(URL: myurl_1!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData,
                                            timeoutInterval: 15.0)
        let queue = NSOperationQueue()
        request_1.HTTPMethod = "GET"

        let task = NSURLSession.sharedSession().dataTaskWithRequest(request_1, completionHandler: { (data, response, error) in
            //NSURLConnection.sendAsynchronousRequest(request_1, queue: queue, completionHandler: { (reponse, data, error) in

            if error != nil
            {
                print("Error!")
            }
            else
            {
                do
                {
                    if let data_1 = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary
                    {
                        self.imp(data_1)
                    }
                    else
                    {
                        print("error!")
                    }
                }
                catch
                {
                    print("error")
                }
            }
        })
        //task.resume()
    }
    print(artist.count)
    do_table_refresh()
}

func do_table_refresh()
{
    dispatch_async(dispatch_get_main_queue(), {
        self.tableView.reloadData()
        return
    })
}

//FUNCTION WHICH CREATES ARRAY
func imp(var data_1:NSDictionary)
{
    if let artist_name = data_1["artists"]![0]["name"] as? String
    {
        artist.append(artist_name)
    }
    else
    {
        print("artist error")
    }

    if let song_name = data_1["name"] as? String
    {
        print(song_name)
        songs.append(song_name)
    }
    else
    {
        print("song error")
    }

    if let url = data_1["preview_url"] as? String
    {
        if let url_1 =  data_1["id"] as? String
        {
            url_list.append([url, url_1])
        }
        else
        {
            print("url error")
        }
    }
    else
    {
        var url_2 =  data_1["id"] as? String
        url_list.append(["null", url_2!])
    }
}

Where exactly would you deal with the asynchronous problem any suggestion?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Put the `do_table_refresh()` after the `self.imp(data_1)` – dan Apr 28 '16 at 18:55
  • I recommend you isolate the problem further and post a more succinct example before posting it here. Stack Overflow isn't about getting others to debug and review your code, but rather about getting answers to specific technical problems. – Mark Apr 28 '16 at 18:55
  • Sorry about that its the first time i've posted a question, I shall keep your suggestions in mind. – Aditya Maru Apr 28 '16 at 19:53

1 Answers1

1

You should note that all the API calls are asynchronous. You are doing a loop of these so, according to your code, you could have several API calls all happening simultaneously.

// Put this outside the loop
let spotify_url = "https://api.spotify.com/v1/tracks/"

for x in spotify_id {
    let url_with_pars = spotify_url + x
    // Be careful. The following could be nil
    let myurl_1 = NSURL(string: url_with_pars)

    // Watch out for ! in the following statement.
    let request_1 = NSMutableURLRequest(URL: myurl_1!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData,
                                        timeoutInterval: 15.0)

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request_1, completionHandler: { (data, response, error) in

        // handle data here
        // refresh table here.

    })
    task.resume()
}
// When your code gets here, the data may not have come back yet.
// The following WILL NOT WORK
print(artist.count) // Remove me
do_table_refresh() // Remove me

Here's the problem with this approach. The table will be refreshed each time one of the API calls comes back. If you had 10 API calls, that would be 10 refreshes.

Is there a reason you use NSDictionary? Parsing JSON returns [AnyObject] which you can cast as needed.

ryantxr
  • 4,119
  • 1
  • 11
  • 25
  • This is my first attempt at using my self taught swift skills to make a full blown application so Im still a little shaky with the intricacies. The reason I used NSDictionary was because I found a similar approach in a video tutorial. What would you suggest to avoid refreshing the table 10 times over? – Aditya Maru Apr 28 '16 at 19:55