追加到类内部的数组实际上未追加到调用对象吗?

时间:2019-07-09 03:04:41

标签: swift xcode

我在ViewController.swift中实例化一个对象,然后调用该对象的方法,以便可以将值附加到其成员之一。但是,当我尝试访问新附加的值时,我收到“索引超出范围错误”。更具体地说,我正在尝试将newProduct : Product附加到方法products : [Product]getAllProducts()中的类成员populateProducts上。不过,在我追加之后,ViewController中的初始调用对象client : ThreeDCartAPIClient实际上并未保留内部类方法中的任何信息。为什么会这样?

我尝试在类方法中的几乎所有地方使用“自我”并从初始化程序中调用这些方法,但我一直得到相同的结果。

// ViewController.swift

import UIKit
import Alamofire
import SwiftyJSON

class ViewController: UIViewController {

    @IBOutlet weak var featuredButton1Image: UIImageView!

    let head : HTTPHeaders = [
        "SecureUrl"  : "https://someURL.3dcartstores.com/",
        "PrivateKey" : "99999999999999999999999999999999",
        "Token"      : "11111111111111111111111111111111",
        "ContentType": "application/json"
    ]
    let ENDPOINT_URL = "https://apirest.3dcart.com/3dCartWebAPI/v1/"

    var client = ThreeDCartAPIClient()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Hide the navigation bar on main screen
        viewWillAppear(true)

        // Make API request and load content
        loadInitialUI()
    }


    func loadInitialUI() {

        client.getAllProducts(url: ENDPOINT_URL, header: head)

       // ******* Here I get an "index out of range" *********** //
       featuredButton1Image.image = client.products[0].mainImage

    }
}
// ThreeDCartAPIClient.swift
import Foundation
import Alamofire
import SwiftyJSON

class ThreeDCartAPIClient {

    var products : [Product]

    init() {
        products = [Product]()
    }

    func getAllProducts(url: String, header: [String : String]) {
        Alamofire.request(url + "Products", method: .get, headers: header).responseJSON {
            response in // Start of a closure inside of Alamofire method
            if response.result.isSuccess {

                // Force unwrap the result value
                let jsonResponse = JSON(response.result.value!)

                // Populate each product field now
                self.populateProducts(json: jsonResponse)
            } else {
                print("Failure")
            }
        }
    }

    func populateProducts(json : JSON) {
        for (_, product) in json {
            let newProduct = Product()
            newProduct.sku.setSKU(json: product["SKUInfo"])
            newProduct.shortDescription = product["ShortDescription"].stringValue
            newProduct.mainImageFile = product["MainImageFile"].stringValue
            Alamofire.request("https://SomeURL.3dcartstores.com/"
                + newProduct.mainImageFile).responseData { (response) in
                if response.error == nil {

                        if let data = response.data {
                            newProduct.mainImage = UIImage(data: data)!
                        }
                }
            }

            products.append(newProduct)
        }
    }
}

1 个答案:

答案 0 :(得分:0)

完成异步任务后,您将在产品数组中获取数据。由于执行异步任务,您无法立即获取数据。 您可以在任务完成时使用委派通知。 在ThreeDCartAPIClient.swift文件中写一个协议:

protocol JsonResponseProtocol: class {
    func asyncTaskCompleted()
}

在ThreeDCartAPIClient类内部写入:

weak var jsonResponseDelegate: JsonResponseProtocol?

完成所有数据填充后(在您的情况下,将其写到populateProducts()中的for循环之外):

self.jsonResponseDelegate?.asyncTaskCompleted()

在声明var client = ThreeDCartAPIClient()后在viewController中添加此代码(在viewDidLoad()内部):

client.jsonResponseDelegate = self

然后在您的viewController.swift中编写以下代码:

extension ViewController: JsonResponseProtocol{
 func asyncTaskCompleted(){

    // if data populated successfully you can access from here 
}
}

为了更好的实践,您可以从ThreeDCartAPIClient类的asyncTaskCompleted()中发送数据数组。