【问题标题】:Manage data downloaded from url - swift管理从 url 下载的数据 - swift
【发布时间】:2019-04-11 17:09:32
【问题描述】:

我有两个下载数据的 URL,它们给了我这种类型的 json:

1) http://192.168.178.77/MyWebService/api/getteams.php

R ->

{"teams":
[{"id":1,"name":"Avengers","member":7},{"id":2,"name":"Fantastics4","member":4},{"id":3,"name":"test","member":6},{"id":4,"name":"teamtest","member":33},{"id":5,"name":"inserisco","member":33},{"id":6,"name":"sarto","member":33},
{"id":7,"name":"name","member":22},
{"id":8,"name":"test","member":999}]
}

2)http://127.0.0.1/MyWebService/api/fetch_image.php?id_team=1 //其中id_team param是从第一个网址下载的id

R -> {"image_team":[{"id":4,"img_path":"http:\/\/localhost\/MyWebService\/images\/imgTest.png","id_team":1}]}

现在,为了下载这些数据,我迅速创建了类和函数来包含和下载数据。

位于各自 file.swift 中的 2 个类是:

1)在 TeamJson.swift 中:

import Foundation

class ClassJsonTeam: Codable {

    private var teams: [JsonTeam]

    init(teams: [JsonTeam]) {
        self.teams = teams
    }

    func getTeams()-> [JsonTeam]{
        return(self.teams);
    }

    func setTeams(teams:[JsonTeam]){
        self.teams = teams;
    }

}

class JsonTeam: Codable {
    private let id: Int
    private var name: String
    private var member: Int

    init(id: Int, name: String, member: Int) {
        self.id = id
        self.name = name
        self.member = member
    }

    func getId()->Int{
        return(self.id);
    }

    func setId(id:Int){
        self.member = id;
    }

    func getName()->String{
        return(self.name);
    }

    func setName(name:String){
        self.name = name;
    }

    func getMembers()->Int{
        return(self.member);
    }

    func setMembers(members:Int){
        self.member = members;
    }
}

2) 在 ImageJsonTeam.swift 中

import Foundation

class ClassJsonTeamImage : Codable {
    private var teams : [JsonTeamImg]

    init(teams: [JsonTeamImg]) {
        self.teams = teams
    }

    func getTeamsImg()-> [JsonTeamImg]{
        return(self.teams);
    }

    func setTeamsImg(teams:[JsonTeamImg]){
        self.teams = teams;
    }
}

class JsonTeamImg : Codable{
    private var id : Int
    private var imagePath: URL
    private var teamId : Int

    init(id : Int, imagePath : URL , teamId : Int) {
        self.id = id
        self.imagePath = imagePath
        self.teamId = teamId
    }

    func getId() -> Int{
        return(self.id)
    }

    func setId(id : Int){
        self.id = id
    }

    func  getImagePath() -> URL {
        return(self.imagePath)
    }

    func setImagePath(imagePath : URL){
        self.imagePath = imagePath
    }

    func getTeamId()-> Int{
        return(self.teamId)
    }

    func setTeamId(teamId : Int){
        self.teamId = teamId
    }
}

另外,由于我需要合并两个json中的信息,所以我创建了这个类型的第三个类:

3)CompleteTeamJson.swift

import Foundation

public class ClassJsonCompleteTeam{
    private var team : [JsonCompleteTeam]

    init(team : [JsonCompleteTeam]){
        self.team = team
    }
}

public class JsonCompleteTeam{
    private var id : Int
    private var name : String
    private var member : Int
    private var imgUrl : URL

    init(id: Int, name: String, member: Int, imgUrl: URL) {
        self.id = id
        self.name = name
        self.member = member
        self.imgUrl = imgUrl
    }

    func getId()->Int{
        return(self.id);
    }

    func setId(id:Int){
        self.member = id;
    }

    func getName()->String{
        return(self.name);
    }

    func setName(name:String){
        self.name = name;
    }

    func getMembers()->Int{
        return(self.member);
    }

    func setMembers(members:Int){
        self.member = members;
    }

    func  getImageUrl() -> URL {
        return(self.imgUrl)
    }

    func setImagePath(imgUrl : URL){
        self.imgUrl = imgUrl
    }

}

现在,我的 viewController 中的情况是这样的:

import UIKit

//var teamCollection  : ClassJsonTeam!
//
class ViewController: UIViewController {

    @IBAction func InsertNewTeamButton(_ sender: Any) {
        performSegue(withIdentifier: "NewTeamSegue", sender: self)
    }

    var teams: [JsonTeam]?
    var teamsImg : [JsonTeamImg]?
    var teamsComplete : [JsonCompleteTeam]?

    override func viewDidLoad() {
        super.viewDidLoad()

        downloadTeams(completion: { (teams) in

            self.teams = teams

            for index in (0...(self.teams!.count - 1)){

                self.downloadTeamsImage(idTeam: teams[index].getId(), completion:
                    {(teamsImg) in self.teamsImg = teamsImg
                })
                let finalId : Int = teams[index].getId()
                let finalName : String = teams[index].getName()
                let finalMember : Int = teams[index].getMembers()
                var finalURL : URL = URL(string : "http://localhost/MyWebService/images/EmptyImg.png")!

                for index2 in (0...(self.teamsImg!.count - 1)){
                    if (finalId == self.teamsImg![index2].getId()){
                        finalURL = self.teamsImg![index2].getImagePath()
                    }
                }

                let tempCompleteTeam = JsonCompleteTeam(id: finalId, name: finalName, member: finalMember, imgUrl: finalURL)
                self.teamsComplete?.append(tempCompleteTeam)


            }

            //self.InsertNewTeamButton((Any).self)
            self.showTeamButton((Any).self)

        })
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // somethings in new wc //
    }


    @IBAction func showTeamButton(_ sender: Any) {
        performSegue(withIdentifier: "TeamListSegue", sender: self)
    }

    func downloadTeams(completion: @escaping (([JsonTeam]) -> Void)) {
        //get teams with classes
        let getTeamUrl = "http://192.168.178.77/MyWebService/api/getteams.php"

        guard let urlTeam = URL(string: getTeamUrl) else { return }
        URLSession.shared.dataTask(with: urlTeam) { (data,response,err) in
            guard let data = data else {return}
            do {
                let team = try JSONDecoder().decode(ClassJsonTeam.self, from: data)
                var tempArrayTeam = [JsonTeam]()
                for index in 0...(team.getTeams().count - 1) {

                    let tempTeam = JsonTeam(id: team.getTeams()[index].getId(),
                                            name: team.getTeams()[index].getName(),
                                            member: team.getTeams()[index].getMembers())

                    print(team.getTeams()[index].getId())
                    print(team.getTeams()[index].getName())
                    print(team.getTeams()[index].getMembers())

                    tempArrayTeam.append(tempTeam)
                }
                completion(tempArrayTeam)
            } catch let jsonErr{
                print("Error serializing json: \(jsonErr.localizedDescription)")
            }
            }.resume()
    }

    func downloadTeamsImage(idTeam: Int,completion: @escaping (([JsonTeamImg]) -> Void)) {
        //get teams with classes
        let getTeamUrl = "http://127.0.0.1/MyWebService/api/fetch_image.php?id_team=\(idTeam)"

        guard let urlTeam = URL(string: getTeamUrl) else { return }
        URLSession.shared.dataTask(with: urlTeam) { (data,response,err) in
            guard let data = data else {return}
            do {
                let team = try JSONDecoder().decode(ClassJsonTeamImage.self, from: data)
                var tempArrayTeamImg = [JsonTeamImg]()
                for index in 0...(team.getTeamsImg().count - 1) {

                    let tempTeamImg = JsonTeamImg(id: team.getTeamsImg()[index].getId(),
                                               imagePath: team.getTeamsImg()[index].getImagePath(),
                                               teamId: team.getTeamsImg()[index].getTeamId())

                    print(tempTeamImg.getId())
                    print(tempTeamImg.getImagePath())
                    print(tempTeamImg.getTeamId())

                    tempArrayTeamImg.append(tempTeamImg)
                }
                completion(tempArrayTeamImg)
            } catch let jsonErr{
                print("Error serializing json: \(jsonErr.localizedDescription)")
            }
            }.resume()
    }

}

让我们切入正题:如果我单独调用这两个函数,它们当然可以工作,但我不知道如何将下载的数据合并到除此之外的 do-catch 中(例如在两个变量中,团队和在 teamsImg 中),以便我们可以贡献变量 teamsComplete 并在另一个视图控制器中传输数据。

提前致谢:D

【问题讨论】:

  • 您已将所有数据设置在所需的变量中,您可以对这些数据做任何您想做的事情,并且可以在任何地方访问它们,您的问题是什么?
  • @RaziTiwana 问题是 datatask 在另一个线程上工作,因此,在 viewDidLoad 中,我应该在函数完成下载数据之前等待,然后才能对这些数据进行操作。事实上,应用程序在这条线上迷恋:for index2 in (0...(self.teamsImg!.count - 1)){ 错误是:线程 5:致命错误:在展开可选值时意外发现 nil
  • 首先,它应该在那里崩溃,因为此时您的self.teamsImg 为零。其次,您应该在问题中提到这一点。现在您只需在完成中移动此代码。假设这是这里唯一的问题。
  • 这里指的是操作依赖吗?比如,当您的数据从两个操作中准备好时,您想收到通知吗?

标签: swift xcode parsing url swift4


【解决方案1】:

更新你viewDidLoad

 override func viewDidLoad() {
        super.viewDidLoad()

        downloadTeams(completion: { (teams) in

            self.teams = teams

            for index in (0...(self.teams!.count - 1)){
                self.downloadTeamsImage(idTeam: teams[index].getId(), completion:
                    {(teamsImg) in self.teamsImg = teamsImg

                let finalId : Int = teams[index].getId()
                let finalName : String = teams[index].getName()
                let finalMember : Int = teams[index].getMembers()
                var finalURL : URL = URL(string : "http://localhost/MyWebService/images/EmptyImg.png")!

                for index2 in (0...(self.teamsImg!.count - 1)){
                    if (finalId == self.teamsImg![index2].getId()){
                        finalURL = self.teamsImg![index2].getImagePath()
                    }
                }

                let tempCompleteTeam = JsonCompleteTeam(id: finalId, name: finalName, member: finalMember, imgUrl: finalURL)
                self.teamsComplete?.append(tempCompleteTeam)

                // YOU CAN MOVE FORWARD NOW AS ALL THE DATA IS LOADED 
                if index == self.teams!.count - 1 {
                   self.showTeamButton((Any).self)
                }

             }
           })

        })
    }

这将消除您的崩溃并在加载所有数据后调用showTeamButton

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-18
    • 1970-01-01
    相关资源
    最近更新 更多