私は最初のビューから2番目のビューにセグメンテーションしています。最初のビューは、ユーザーが検索語(アカウント名)を入力するためのテキストフィールドで構成されています。その名前はセカンドビューに繋がっています。変数初期化の前にデータを返さない同期APIコール
私はこの名前をとり、自分のアカウントの詳細(名前、ID、アカウントID、レベルなど)を返すためにRiot APIを呼び出します。
次に、資格情報(名前、ID、レベル)を使用してGUIラベルを更新します。
ここで、このプロセスが分断されます。プログラムはAPI呼び出しが完了するのを待ってから前方に移動します。
は、私がしたいステップの内訳は、この順に本質的である:
1)暴動のAPI
2を呼び出すためにセグエから検索用語を使用します)資格情報を使用してGUIを更新し
3 SEは使用)
1:)これが起こっている、
代わりに暴動のAPIから返された資格情報を使用して、いくつかの変数を初期化資格情報を使用してGUIを更新します)(彼らはまだ返されていませんが、それカントので(APIから資格情報を持つ)
3)いくつかの変数を初期化)暴動のAPI
2を呼び出すためのセグエからアーチ用語
プログラムは転送をスキップし、データが返されるのを待っていません。 APIを呼び出すこの方法が「非同期」であり、データが引き続き取得されるのを待つことなく、DispatchQueue.main.async {}はすべてのそれ以外の場合は、中括弧内で次のコードを記述する必要があります。
task.resume()の後にコードを追加すると、まだ返されていないため、呼び出しから取得したデータは使用されません。
質問:私は 'let task = UrlSession.shared ... task.resume()をユーザー資格情報を待つようにして、残りのコードを順番に進めることができますこのビューの残りの部分をDispatchQueue.main.async {}の中に埋め込むよりも、私はそれが(task.resumeまで()...タスク= URLSession.shared.dataTaskを聞かせて)進む前に完了するの上記のコードを待ちたい
task.resume(後import UIKit
class ViewControllerProfile: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//test to see if we got the name from the segue:
print("from Segue: " + summonerName)
//execute on view load:
let theUser = Summoner(name: summonerName)
print(theUser.name!)
//API - Summoners Details By Summoner Name:
//Construct request for name in secondViewController(PROFILE)
let root:String = "https://euw1.api.riotgames.com"
let entryPoint:String = "/lol/summoner/v3/summoners/by-name/"
let key:String = "?api_key=RGAPI-728b9775-cfdf-4065-acca-70cb732aed0d"
//theUser.name! is a search term (players name)
let completeURL = root + entryPoint + theUser.name! + key
let urlRecieved = URL(string: completeURL.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!)
let task = URLSession.shared.dataTask(with: urlRecieved!){ (data, response, error) in
if error != nil{
print("ERROR")
}
else{
if let content = data{
do{
//Array:
let myJson = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:Any]
//We now extract the required information from the JSON output with keys:
//Class generics for future parsing:
let summonerID = myJson["id"] as? UInt64
let usersSummonerID:Int = Int(summonerID!)
print(usersSummonerID)
let accountID = myJson["accountId"] as? UInt64
let usersAccountID = Int(accountID!)
print(usersAccountID)
//Required elements for Profile Labels:
let extractName = myJson["name"] as? String
let extractLevel = myJson["summonerLevel"] as? UInt64
//We need to convert the extractLevel variable from UInt64 to String to update a label without an optional:
let usersLevel:String = "\(extractLevel!)"
//We update the gui now using the data we got from the API call:
DispatchQueue.main.async {
//We dispatch the user interface updates to the main thread here:
self.summonerLevelLbl.text = ("Level: " + "\(usersLevel)")
self.summonerNameLbl.text = extractName
//We dispatch the api-returned userObject's attributes to the main thread for assignment here:
self.summonerNameMain = extractName!
self.summonerIDMain = usersSummonerID
self.accountIDMain = usersAccountID
print("dispatch completed\n\n")
//all future code goes here?
}
}
catch{
print("SOMETHING WENT WRONG WITH SERIALIZATION OF NAME X")
}
}
}
}
task.resume()
theUser.name = summonerNameMain
theUser.accountID = accountIDMain
theUser.summonerID = summonerIDMain
print("ASSIGNMENT TEST")
print(theUser.name!)
print(theUser.summonerID!)
print(theUser.accountID!)
}
@IBOutlet weak var summonerNameLbl: UILabel!
@IBOutlet weak var summonerRankLbl: UILabel!
@IBOutlet weak var summonerLevelLbl: UILabel!
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//For Segue:
var summonerName = String()
//For Parsing:
var accountIDMain = Int()
var summonerIDMain = Int()
var summonerNameMain = String()
}
class Summoner:NSObject{
var name:String?
var summonerID:Int?
var accountID:Int?
var matchID:Int?
init(name: String){
self.name = name
}
}
) さらにAPI以前の呼び出しからのデータを必要とする呼び出しが必要になります。非同期にコードを埋め込むことを避けることをお勧めします。
あなたは待っていません。あなたはあなたが言ったことをする - 非同期の内部にコードを移動する(しかし、メインキュー上のすべてのUIアップデートを行う)。 – rmaddy
@rmaddy次のビューの残りの部分を非同期の内部でロードするよりも、これを処理するクリーナーの方法はありませんか? – Artemis
@rmaddy私は非同期の最後にコメント付きの質問のコードを更新しました。「今後のすべてのコードはここに入りますか?」このポイントの後に、このビューコントローラの将来のコードをすべて記述するとしますか? task.resume()の下に進む前にこのコードを終了させるだけでいいですか? – Artemis