我只是用Alamofire和SwiftyJSON编写了一些Swift代码来访问Riot API。
我写了一个函数func getIDbyName(SummName: String) -> String
来获取召唤者ID。
从下面的代码中可以看到,我将ID分配给self.SummID
。
执行完函数后,我能够println
正确的ID,例如"1234567"
。但是,return self.SummID
返回"0"
,与开头分配的相同。
我试图弄乱代码,但是我根本无法在self.SummID
闭包之外获得Alamofire.request
的正确值。它始终在外部任何地方保持"0"
。
我认为这与变量的范围有关。有人知道这是怎么回事吗?
import Foundation
import Alamofire
import SwiftyJSON
class SummInfo {
var SummName = "ThreeSmokingGuns"
var SummID = "0"
var SummChamp = "akali"
var SummS1 = "flash"
var SummS2 = "ignite"
var SummRank = "Unranked"
var SummWR = "-" //summoner's winrate
let api_key = "key"
let URLinsert = "?api_key="
init(SummName: String, SummChamp: String, SummS1: String, SummS2: String, SummRank: String, SummWR: String) {
self.SummName = SummName
self.SummChamp = SummChamp
self.SummS1 = SummS1
self.SummS2 = SummS2
self.SummRank = SummRank
self.SummWR = SummWR
}
init(SummName: String) {
self.SummName = SummName
}
func getIDbyName(SummName: String) -> String
{
let SummURL = "https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/"
var fullURL = "\(SummURL)\(SummName)\(URLinsert)\(api_key)"
Alamofire.request(.GET, fullURL)
.responseJSON { (request, response, data, error) in
if let anError = error
{
// got an error in getting the data, need to handle it
println("error calling GET on /posts/1")
println(error)
}
else if let data: AnyObject = data // hate this but responseJSON gives us AnyObject? while JSON() expects AnyObject
// JSON(data!) will crash if we get back empty data, so we keep the one ugly unwrapping line
{
// handle the results as JSON, without a bunch of nested if loops
let post = JSON(data)
self.tempJ = post
var key = post.dictionaryValue.keys.array //not necessary
var key2 = post[SummName.lowercaseString].dictionaryValue.keys.array
self.SummID = post[key[0],key2[2]].stringValue //[profileIconId, revisionDate, id, summonerLevel, name]
//test console output
println("The post is: \(post.description)")
println(SummName.lowercaseString)
println(key)
println(key2)
println(self.SummID)
}
}
return self.SummID
}
}
最佳答案
原因是
Alamofire.request(.GET, fullURL)
.responseJSON
是一个异步调用。这意味着对getIDbyName的调用将立即返回,而无需等待responseJSON完成。这就是为什么您获得的ID最初设置为“ 0”的确切原因。
话虽如此,解决方案是在getIDbyName方法中有一个回调闭包:
func getIDbyName(SummName: String, callback: (id:String?) ->() ) -> ()
{
let SummURL = "https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/"
var fullURL = "\(SummURL)\(SummName)\(URLinsert)\(api_key)"
Alamofire.request(.GET, fullURL)
.responseJSON { (request, response, data, error) in
if let anError = error
{
// got an error in getting the data, need to handle it
println("error calling GET on /posts/1")
println(error)
//Call back closure with nil value
callback(nil) //Can additionally think of passing actual error also here
}
else if let data: AnyObject = data // hate this but responseJSON gives us AnyObject? while JSON() expects AnyObject
// JSON(data!) will crash if we get back empty data, so we keep the one ugly unwrapping line
{
// handle the results as JSON, without a bunch of nested if loops
let post = JSON(data)
self.tempJ = post
var key = post.dictionaryValue.keys.array //not necessary
var key2 = post[SummName.lowercaseString].dictionaryValue.keys.array
self.SummID = post[key[0],key2[2]].stringValue //[profileIconId, revisionDate, id, summonerLevel, name]
//test console output
println("The post is: \(post.description)")
println(SummName.lowercaseString)
println(key)
println(key2)
println(self.SummID)
//Pass the actual ID got.
callback(self.SummID)
}
}
return self.SummID
}
客户应该始终使用此API来获取最新的ID,并且可以直接引用该属性以获取到目前为止SummID成员中缓存的所有内容。
这是如何调用此方法的-
object.getIDbyName(sumName){ (idString :String) in
//Do whatever with the idString
}
关于ios - 无法更改全局变量的值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30721679/