我试图在后台更新我的UITableView。虽然我当前的代码正在运行,但我遇到了两个主要错误。
更详细。我使用coreData来填充单元格。但是我还需要连接2个API。
目前。我有两个功能:
loadSuggestions()
和updateSuggestions()
loadSuggestions
填充获取正确的信息,显示正常。
updateSuggestions
删除所有当前数据,获取新数据,将其保存到CoreData中,然后重新加载UITableView
。 (这个函数作为loadSuggestions()
函数中的最后一个函数,在后台运行)
所以我的主要问题。是我加载建议的时候。如果我在UITableView完成更新之前尝试与UITableView进行交互,我会收到错误:fatal error: Array index out of range
原因很简单。我在我的函数开头删除了CoreData。在此期间,它期望我的数组为0,但向下滚动显然会尝试在数组索引之外加载数据。
但我不知道如何解决上述问题。
我的第二个不太重要的问题在于/ performance /? updateSuggestions()完成运行后。它实际上并没有使用更改的数据更新我的UITableView
,直到几秒钟后,或者我与UITableView
进行交互。它当然应该更新它完成更新的那一刻?
我不清楚如何解决这两个问题中的任何一个问题。因此,为什么我在这里。
这是我的2个函数的代码:
loadSuggestions()
func loadSuggestions() {
println("----- Loading Data -----")
// Set the managedContext again.
managedContext = appDelegate.managedObjectContext!
// Check what API to get the data from
if Formula == 0 {
formulaEntity = "TrialFormulaStock"
println("Setting Entity: \(formulaEntity)")
formulaAPI = NSURL(string: "http://api.com/json/entry_weekly.json")
} else if Formula == 1 {
formulaEntity = "ProFormulaStock"
println("Setting Entity: \(formulaEntity)")
formulaAPI = NSURL(string: "http://api.com/json/entry_weekly.json")
} else if Formula == 2 {
formulaEntity = "PremiumFormulaStock"
formulaAPI = NSURL(string: "http://api.com/json/proff_weekly.json")
println("Setting Entity: \(formulaEntity)")
} else if Formula == 3 {
formulaEntity = "PlatinumFormulaStock"
println("Setting Entity: \(formulaEntity)")
formulaAPI = NSURL(string: "http://api.com/json/fund_weekly.json")
}
// Delete all the current objects in the dataset
let fetchRequest = NSFetchRequest(entityName: formulaEntity)
let a = managedContext.executeFetchRequest(fetchRequest, error: nil) as! [NSManagedObject]
stocks.removeAll(keepCapacity: false)
for mo in a {
stocks.append(mo)
}
// Removing them from the array
// Saving the now empty context.
managedContext.save(nil)
// Reload the tableview with the new data.
self.tableView.reloadData()
self.view.hideLoading()
self.refreshControl.endRefreshing()
dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.value), 0)) {
self.updateSuggestions()
}
}
和updateSuggestions:
func updateSuggestions() {
println("Updating Suggestions")
if Reachability.isConnectedToNetwork() == false {
println("ERROR: -> No Internet Connection <-")
} else {
// Delete all the current objects in the dataset
let fetchRequest = NSFetchRequest(entityName: formulaEntity)
let a = managedContext.executeFetchRequest(fetchRequest, error: nil) as! [NSManagedObject]
for mo in a {
managedContext.deleteObject(mo)
}
// Removing them from the array
stocks.removeAll(keepCapacity: false)
// Saving the now empty context.
managedContext.save(nil)
// Set up a fetch request for the API data
let entity = NSEntityDescription.entityForName(formulaEntity, inManagedObjectContext:managedContext)
var request = NSURLRequest(URL: formulaAPI!)
var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)
var formula = JSON(data: data!)
// Loop through the api data.
for (index: String, actionable: JSON) in formula["actionable"] {
// Save the data into temporary variables
stockName = actionable["name"].stringValue
ticker = actionable["ticker"].stringValue
action = actionable["action"].stringValue
suggestedPrice = actionable["suggested_price"].floatValue
weight = actionable["percentage_weight"].floatValue
// Set up CoreData for inserting a new object.
let stock = NSManagedObject(entity: entity!,insertIntoManagedObjectContext:managedContext)
// Save the temporary variables into coreData
stock.setValue(stockName, forKey: "name")
stock.setValue(ticker, forKey: "ticker")
stock.setValue(action, forKey: "action")
stock.setValue(suggestedPrice, forKey: "suggestedPrice")
stock.setValue(weight, forKey: "weight")
// Get ready for second API call.
var quoteAPI = NSURL(string: "http://dev.markitondemand.com/Api/v2/Quote/json?symbol=\(ticker)")
// Second API fetch.
var quoteRequest = NSURLRequest(URL: quoteAPI!)
var quoteData = NSURLConnection.sendSynchronousRequest(quoteRequest, returningResponse: nil, error: nil)
if quoteData != nil {
// Save the data from second API call to temporary variables
var quote = JSON(data: quoteData!)
betterStockName = quote["Name"].stringValue
lastPrice = quote["LastPrice"].floatValue
println("Updated lastPrice for \(betterStockName)")
// The second API call doesn't always find something, so checking if it exists is important.
if betterStockName != "" {
stock.setValue(betterStockName, forKey: "name")
}
// This can simply be set, because it will be 0 if not found.
stock.setValue(lastPrice, forKey: "lastPrice")
} else {
println("ERROR ----------------- NO DATA for \(ticker) --------------")
}
// Error handling
var error: NSError?
if !managedContext.save(&error) {
println("Could not save \(error), \(error?.userInfo)")
}
// Append the object to the array. Which fills the UITableView
stocks.append(stock)
}
self.tableView.reloadData()
println("Finished Updating Suggestions")
}
}
我在后台运行updateSuggestions()的原因是因为它需要很长时间才能进行所有API调用。并且用户需要能够在加载时进行交互并查看当前数据。
/可能/不相关,我也收到了一些内存警告。
非常感谢任何帮助!