1

The code works perfectly. The problem is that, after trying for a while, I cannot figure out how to make my program process a second link of different JSON data.

Here is my viewDidLoad where everything goes on:

override func viewDidLoad() {
    super.viewDidLoad()

        var err: NSError?
        let urlPath: String = "https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/" + searchFieldDataPassed + "?api_key=(removed my private api key for obvious reasons"
        var url: NSURL = NSURL(string: urlPath)!
        let session = NSURLSession.sharedSession()
        let task = session.dataTaskWithURL(url) { data, response, error in

            // cast response as NSHTTPURLResponse and switch on statusCode if you like
            if let httpResponse = response as? NSHTTPURLResponse { switch httpResponse.statusCode { case 200..<300: println("OK") default: println("Not OK") } }

            // parse JSON using NSJSONSerialization if you've got data
            if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary,
            let include = jsonResult.objectForKey(self.searchFieldDataPassed) as? NSDictionary {

                    if let summLevel = include[ "summonerLevel" ] as? NSNumber {

                        dispatch_async(dispatch_get_main_queue()) {

                            self.summonerLevel.text = "\(summLevel.integerValue)"
                            println("summoner level: \(summLevel.integerValue)")

                        }
                    }

                    if let profIconId = include[ "profileIconId" ] as? NSNumber {

                        dispatch_async(dispatch_get_main_queue()) {

                            self.profileIconId.text = "\(profIconId.integerValue)"
                            println("profile icon id: \(profIconId.integerValue)")

                        }
                    }

                    if let idNum = include [ "id" ] as? NSNumber {

                        dispatch_async(dispatch_get_main_queue()) {

                            self.idNumber = idNum
                            println("id number: \(self.idNumber)")

                        }
                }
            }


        // spawn off another network call here if you like
    }
    task.resume()  
}

That is from my secondViewController where all the processing goes on for JSON and then is displayed.

Here is the JSON data that I'm processing (for the first JSON parsing):

{"soon2challenger":{"id":43993167,"name":"soon2challenger","profileIconId":844,"summonerLevel":30,"revisionDate":1435549418000}}

All of that works fine, now, I want to process this JSON data which actually takes the id from the first parsed JSON data and uses it in the link to process more data, which I would like to output, part of it, to the screen.

Second JSON data:

{"summonerId":43993167,"playerStatSummaries":[{"playerStatSummaryType":"AramUnranked5x5","wins":25,"modifyDate":1423007927000,"aggregatedStats":{"totalChampionKills":676,"totalTurretsKilled":20,"totalAssists":991}},{"playerStatSummaryType":"CAP5x5","wins":15,"modifyDate":1429065922000,"aggregatedStats":{"totalChampionKills":312,"totalMinionKills":4885,"totalTurretsKilled":31,"totalNeutralMinionsKilled":511,"totalAssists":216}},{"playerStatSummaryType":"CoopVsAI","wins":28,"modifyDate":1421882181000,"aggregatedStats":{"totalChampionKills":266,"totalMinionKills":2802,"totalTurretsKilled":50,"totalNeutralMinionsKilled":385,"totalAssists":164,"maxChampionsKilled":0,"averageNodeCapture":0,"averageNodeNeutralize":0,"averageTeamObjective":0,"averageTotalPlayerScore":49,"averageCombatPlayerScore":0,"averageObjectivePlayerScore":49,"averageNodeCaptureAssist":0,"averageNodeNeutralizeAssist":0,"maxNodeCapture":0,"maxNodeNeutralize":0,"maxTeamObjective":0,"maxTotalPlayerScore":49,"maxCombatPlayerScore":0,"maxObjectivePlayerScore":49,"maxNodeCaptureAssist":0,"maxNodeNeutralizeAssist":0,"totalNodeNeutralize":0,"totalNodeCapture":0,"averageChampionsKilled":0,"averageNumDeaths":0,"averageAssists":0,"maxAssists":0}},{"playerStatSummaryType":"CoopVsAI3x3","wins":15,"modifyDate":1421882181000,"aggregatedStats":{"totalChampionKills":140,"totalMinionKills":1114,"totalTurretsKilled":9,"totalNeutralMinionsKilled":449,"totalAssists":91}},{"playerStatSummaryType":"OdinUnranked","wins":1,"modifyDate":1421882181000,"aggregatedStats":{"totalChampionKills":31,"totalAssists":45,"maxChampionsKilled":10,"averageNodeCapture":4,"averageNodeNeutralize":4,"averageTeamObjective":0,"averageTotalPlayerScore":843,"averageCombatPlayerScore":268,"averageObjectivePlayerScore":575,"averageNodeCaptureAssist":3,"averageNodeNeutralizeAssist":1,"maxNodeCapture":6,"maxNodeNeutralize":7,"maxTeamObjective":2,"maxTotalPlayerScore":1468,"maxCombatPlayerScore":529,"maxObjectivePlayerScore":939,"maxNodeCaptureAssist":5,"maxNodeNeutralizeAssist":2,"totalNodeNeutralize":22,"totalNodeCapture":25,"averageChampionsKilled":5,"averageNumDeaths":5,"averageAssists":8,"maxAssists":19}},{"playerStatSummaryType":"RankedSolo5x5","wins":116,"losses":120,"modifyDate":1433630047000,"aggregatedStats":{"totalChampionKills":1699,"totalMinionKills":33431,"totalTurretsKilled":219,"totalNeutralMinionsKilled":6501,"totalAssists":1969}},{"playerStatSummaryType":"RankedTeam3x3","wins":0,"losses":0,"modifyDate":1377726216000,"aggregatedStats":{}},{"playerStatSummaryType":"RankedTeam5x5","wins":3,"losses":0,"modifyDate":1383784473000,"aggregatedStats":{"totalChampionKills":28,"totalMinionKills":636,"totalTurretsKilled":6,"totalNeutralMinionsKilled":101,"totalAssists":41}},{"playerStatSummaryType":"Unranked3x3","wins":9,"modifyDate":1421882181000,"aggregatedStats":{"totalChampionKills":90,"totalMinionKills":1427,"totalTurretsKilled":11,"totalNeutralMinionsKilled":428,"totalAssists":105}},{"playerStatSummaryType":"URF","wins":4,"modifyDate":1435024847000,"aggregatedStats":{"totalChampionKills":68,"totalMinionKills":642,"totalTurretsKilled":14,"totalNeutralMinionsKilled":182,"totalAssists":55}},{"playerStatSummaryType":"Unranked","wins":566,"modifyDate":1435549418000,"aggregatedStats":{"totalChampionKills":8419,"totalMinionKills":128213,"totalTurretsKilled":960,"totalNeutralMinionsKilled":26117,"totalAssists":7812}}]}

Heres the link of the second JSON data I want to parse (just adding it, could be useful, but not sure): https://na.api.pvp.net/api/lol/na/v1.3/stats/by-summoner/43993167/summary?season=SEASON2015&api_key=(took-out-my-private-api-key-for-obvious-reasons)

The link doesn't work because I have to keep my api key private to myself, but the JSON data that it displays is right above the link, which is the what it would result if you were to use the link with the api key.

Just to restate, I would like to process the second part (above of this) of JSON data, but I do not understand how to process multiple links of JSON. I have the first JSON data parsed, but am unable to parse the second JSON data.

2 Answers 2

1

I believe Apple is deprecating NSURLConnection. Take a look at NSURLSession. Using it, you can pass in a completion block that takes three arguments: NSData?, NSURLResponse?, and NSError?. The data object contains the JSON you can pass into the JSON serializer. After that, if you need to make another network call, just call it from inside the completion block with another NSURLSession data task. Alamofire is a great framework, but sometimes you don't need everything it provides, and it adds complexity into your app that if something goes wrong or doesn't behave the way you intend/understand, you may not fully understand why. If you want to keep it simple and under your control, use NSURLSession.

let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url) { data, response, error in
    // cast response as NSHTTPURLResponse and switch on statusCode if you like
    // parse JSON using NSJSONSerialization if you've got data
    // spawn off another network call here if you like
}
task.resume() // or in Swift 2, task?.resume()
Sign up to request clarification or add additional context in comments.

8 Comments

I'm a little confused. Could you elaborate more with the code and a bit more explaining.
Sure, and maybe I'm not fully understanding what you mean when you say "parsing links", so this is coming from my limited understanding of your problem. Is the second set of JSON gotten from a second network call with data provided from the first? If so, you may find it easier to nest NSURLSession data tasks. Once you start the first one, you get a completion handler to customize (as shown in my example). The JSON can be parsed from the NSData param. Once you parse what you need, you can make a second NSURLSession data task inside the completion handler to do another network call, and so on.
Yes, your understanding is correct. I am confused with how to cast a response as NSHTTURLResponse. I'm also confused with how I would output the JSON data to a variable or on the screen. Would I just put the current NSJSONSerialization if statement where you have the commented " // parse JSON ... " and then go from there?
Wow, my ability to enter code in a comment is deplorable :-). if let httpResponse = response as? NSHTTPURLResponse { switch httpResponse.statusCode { case 200..<300: print("OK") default: print("Not OK") } }
Since the completion handler is on a background queue, you'd need to dispatch to the main queue to update the screen. dispatch_async(dispatch_get_main_queue()) { // update UI here }
|
0

First, i would totally prefer using some common frameworks for http requests - expecially if youre new in swift. For example here with alamofire.

https://github.com/Alamofire/Alamofire

There is also a version with integrated SwiftyJSON, so you are able to parse JSON Responses very easily.

https://github.com/SwiftyJSON/Alamofire-SwiftyJSON

So if you want to make a request, use this:

Alamofire.request(.GET, "http://httpbin.org/get")
         .responseJSON { (_, _, json, _) in
                  var json = JSON(json)

                  // get the id out (depends on your structure of JSON):  
                  let id = json["id"].int
         }

Now you are able to perform a second Request (with the same Code) - Read the Documentation, how to make different Requests (like with POST) and add Parameters.

If you want to use Segues, so you want to load more data from the ID in another ViewController, you can use Segues to push the data to a second ViewController, and Load the new Content from JSON when the new ViewController is initialised.

Check out this how to send data through segues:

Sending data with Segue with Swift

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.