我在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)
}
}
}
答案 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()中发送数据数组。