如何处理 JSON 数据的多个链接?

Posted

技术标签:

【中文标题】如何处理 JSON 数据的多个链接?【英文标题】:How can I process multiple links of JSON data? 【发布时间】:2015-07-02 05:20:55 【问题描述】:

代码完美运行。问题是,尝试了一段时间后,我无法弄清楚如何让我的程序处理不同 JSON 数据的第二个链接。

这是我的 viewDidLoad,一切都在进行:

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()  

这是来自我的 secondViewController,所有处理都针对 JSON 进行,然后显示。

这是我正在处理的 JSON 数据(用于第一次 JSON 解析):

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

所有这些工作正常,现在,我想处理这个 JSON 数据,它实际上从第一个解析的 JSON 数据中获取 id,并在链接中使用它来处理更多数据,我想输出它的一部分, 到屏幕上。

第二个 JSON 数据:

"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]

这是我要解析的第二个 JSON 数据的链接(只是添加它,可能有用,但不确定): 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)

该链接不起作用,因为我必须将我的 api 密钥保密,但它显示的 JSON 数据就在链接的正上方,如果您将链接与api 键。

重申一下,我想处理JSON数据的第二部分(以上),但我不明白如何处理JSON的多个链接。我解析了第一个 JSON 数据,但无法解析第二个 JSON 数据。

【问题讨论】:

【参考方案1】:

我相信 Apple 正在弃用 NSURLConnection。看看 NSURLSession。使用它,您可以传入一个带有三个参数的完成块:NSData?NSURLResponse?NSError?。数据对象包含您可以传递给 JSON 序列化程序的 JSON。之后,如果您需要进行另一个网络调用,只需从完成块内部使用另一个 NSURLSession 数据任务调用它。 Alamofire 是一个很棒的框架,但有时您并不需要它提供的所有东西,并且它会增加您的应用程序的复杂性,如果出现问题或行为不符合您的预期/理解方式,您可能无法完全理解原因。如果你想让它保持简单并由你控制,请使用 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()

【讨论】:

我有点困惑。您能否详细说明一下代码并进行更多解释。 当然,当你说“解析链接”时,我可能没有完全理解你的意思,所以这是我对你的问题的有限理解。第二组 JSON 是从第二个网络调用中获得的,其中的数据是从第一组提供的吗?如果是这样,您可能会发现嵌套 NSURLSession 数据任务更容易。一旦你开始第一个,你会得到一个完成处理程序来自定义(如我的示例所示)。 JSON 可以从 NSData 参数中解析。一旦你解析了你需要的东西,你可以在完成处理程序中创建第二个 NSURLSession 数据任务来进行另一个网络调用,等等。 是的,你的理解是正确的。我对如何将响应转换为 NSHTTURLResponse 感到困惑。我也对如何将 JSON 数据输出到变量或屏幕上感到困惑。我是否可以将当前的 NSJSONSerialization if 语句放在您已注释“//解析 JSON ...”的位置,然后从那里开始? 哇,我在评论中输入代码的能力令人遗憾:-)。 if let httpResponse = response as? NSHTTPURLResponse switch httpResponse.statusCode case 200..&lt;300: print("OK") default: print("Not OK") 由于完成处理程序位于后台队列中,因此您需要分派到主队列以更新屏幕。 dispatch_async(dispatch_get_main_queue()) // update UI here 【参考方案2】:

首先,我更喜欢使用一些通用框架来处理 http 请求 - 特别是如果您是 swift 新手。例如这里的 alamofire。

https://github.com/Alamofire/Alamofire

还有一个集成了 SwiftyJSON 的版本,因此您可以非常轻松地解析 JSON 响应。

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

所以如果你想提出请求,使用这个:

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
         

现在您可以执行第二个请求(使用相同的代码) - 阅读文档,了解如何发出不同的请求(如使用 POST)并添加参数。

如果你想使用 Segues,所以你想从另一个 ViewController 中的 ID 加载更多数据,你可以使用 Segues 将数据推送到第二个 ViewController,并在新 ViewController 初始化时从 JSON 加载新内容.

查看如何通过 segues 发送数据:

Sending data with Segue with Swift

【讨论】:

以上是关于如何处理 JSON 数据的多个链接?的主要内容,如果未能解决你的问题,请参考以下文章

服务器如何处理http请求

如何处理动态创建的 UIButtons

如何处理多个单独的 json 响应?

如何处理更好的链接方式?

如何处理具有多个 tsconfig.json 文件的项目?

智能合约如何处理多个用户和不同的存储?