Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
432 views
in Technique[技术] by (71.8m points)

asynchronous - for loop cycle showing always the last array value swift 3 after HTTP request

I already used another post to solver part of the problem,so now I am able to wait the end of the request. I made a http request with Almofire and parse the resulting JSON file. the code inside the myGroup.notify i think is correctly executed ater the request is completed (if I print allCards.count returns the correct value). Why if I put the for loop inside it is always showing the last card?

Thanks for any help

import UIKit
mport SwiftyJSON
import Alamofire

class ViewController: UIViewController {
//variables Declaration
var allCard = [Card]()
let allCardsHTTP: String = "https://omgvamp-hearthstone-v1.p.mashape.com/cards?mashape-key="

override func viewDidLoad() {
    super.viewDidLoad()
    let myGroup = DispatchGroup()

    //get HTTp request with Alamofire

    myGroup.enter()
    Alamofire.request(allCardsHTTP, method: .get).responseJSON {
         response in
         if response.result.isSuccess {
             let jsonCards : JSON = JSON(response.result.value!)
             print("success")
             self.updateJSONCards(json: jsonCards)
          }
        else {
             print("error")
         }
         myGroup.leave()
    }

    myGroup.notify(queue: .main) {
         //Updte UI here
         print(self.allCard[10].name) //This is Working

         for card in self.allCard {
            if card.cardsSet == "Basic" {
                print(card.name)
            }
        } //For loop always showing last card ???


    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


//MARK: - JSON Parsing


//Write the updateJSONCards method here:
func updateJSONCards(json: JSON) {
    //create the cards
     for (set, value) in json {
         var card = Card()
         card.cardsSet = set
         if json[set].count != 0 {
            for i in 0...json[set].count - 1 {
                card.name = json[set][i]["name"].stringValue
                allCard.append(card)
             }
         }
         else {
             print("The set (set) has no cards")
         }
     }
  }

}

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You are creating the Card instance at the wrong place.

Before the inner repeat loop you are creating one instance and appending the same instance to the allCard array. If Card is a class (reference semantics) all occurrences of that instance contain the same data (the last loop item).

Put the two lines in the repeat loop.

//Write the updateJSONCards method here:
func updateJSONCards(json: JSON) {
    //create the cards
     for (set, value) in json {
         if !json[set].isEmpty {
            for i in 0..<json[set].count {
                let card = Card()
                card.cardsSet = set
                card.name = json[set][i]["name"].stringValue
                allCard.append(card)
             }
         }
         else {
             print("The set (set) has no cards")
         }
     }
  }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...