2017-11-19 3 views
-1

私は最初のビューから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以前の呼び出しからのデータを必要とする呼び出しが必要になります。非同期にコードを埋め込むことを避けることをお勧めします。

+1

あなたは待っていません。あなたはあなたが言ったことをする - 非同期の内部にコードを移動する(しかし、メインキュー上のすべてのUIアップデートを行う)。 – rmaddy

+0

@rmaddy次のビューの残りの部分を非同期の内部でロードするよりも、これを処理するクリーナーの方法はありませんか? – Artemis

+0

@rmaddy私は非同期の最後にコメント付きの質問のコードを更新しました。「今後のすべてのコードはここに入りますか?」このポイントの後に、このビューコントローラの将来のコードをすべて記述するとしますか? task.resume()の下に進む前にこのコードを終了させるだけでいいですか? – Artemis

答えて

1

(あなたがしたい場合やprint文)だけでこれらの行を移動:

theUser.name = summonerNameMain 
theUser.accountID = accountIDMain 
theUser.summonerID = summonerIDMain 

あなたは「将来のすべてのコード」についてコメントを持っている場所に。

完了。

関連する問題