Я загружаю основные данные из онлайн-базы данных, а затем заполняю свое табличное представление из основных данных (чтобы они также были доступны в автономном режиме). Все работает нормально, за исключением того, что я не могу понять, как заставить работать обработчик завершения, чтобы выборка завершалась до загрузки. Я следил за этот пример, но не могу понять что он не вызывает мою функцию (CloudUpdate).
func CloudUpdate(completionHandler: () -> Void) {
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext!
// Clear the table before reloading to avoid duplicates
let request = NSFetchRequest(entityName: "News")
let managedObjectContext: NSManagedObjectContext? = (UIApplication.sharedApplication().delegate as? AppDelegate)?.managedObjectContext
var fetchedResultsController: NSFetchedResultsController?
var results:NSArray = context.executeFetchRequest(request, error: nil)!
var bas: NSManagedObject!
for bas: AnyObject in results
{
context.deleteObject(bas as NSManagedObject)
}
context.save(nil)
let url = NSURL(string: "http://www.appsforteacher.com/news.php")
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
var d = NSString(data: data, encoding: NSUTF8StringEncoding)
var arr = d!.componentsSeparatedByString("<")
var dataweneed:NSString = arr[0] as NSString
if let data = NSJSONSerialization.JSONObjectWithData(dataweneed.dataUsingEncoding(NSUTF8StringEncoding)!, options: NSJSONReadingOptions.MutableContainers, error: nil) as? NSArray
{
for dd in data{
//time is set to UTC. See if you can fix it.
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
var courseID : Int = (dd["courseID"]! as String).toInt()!
var timeStamp = dateFormatter.dateFromString(dd["timeStamp"]! as String)
var heading : String = dd["heading"]! as String
var detail : String = dd["detail"]! as String
var newNews = NSEntityDescription.insertNewObjectForEntityForName("News", inManagedObjectContext: context) as NSManagedObject
newNews.setValue(heading, forKey: "heading")
newNews.setValue(detail, forKey: "detail")
newNews.setValue(timeStamp, forKey: "timeStamp")
newNews.setValue(courseID, forKey: "courseID")
context.save(nil)
}
}
}
task.resume()
completionHandler()
}
func application(application: UIApplication!, performFetchWithCompletionHandler completionHandler: ((UIBackgroundFetchResult) -> Void)!) {
CloudUpdate() {
completionHandler(UIBackgroundFetchResult.NewData)
}
}
completionHandler
, пока ваша задача с данными не будет выполнена? Если это так, переместите линиюcompletionHandler()
внутрь замыканияdataTaskWithURL
. И помните, если вы хотите, чтобы это вызывалось в основном потоке, вам придется вручную отправить его обратно в основной поток (поскольку это закрытие происходит в фоновом потоке). - person Rob   schedule 10.04.2015performFetchWithCompletionHandler
никогда не вызывается? Или что он вызывается, а CloudUpdate не вызывается? Это не кажется возможным. Теперь возможные проблемы включают в себя то, что вы недостаточно быстро вызываетеcompletionHandler
(не должно быть более 30 секунд, IIRC ... если это дольше, вы должны использовать фонNSURLSession
). Или, может быть, вы поместили обработчик завершения не в то место (он находится в блокеdataTaskWithURL
, а не в блокеif let data =...
). Трудно сказать на основании предоставленной ограниченной информации. - person Rob   schedule 10.04.2015.NewData
вне зависимости от того, были реальные данные или нет. Если вы собираетесь быть хорошим гражданином, вы должны сделать вызов, чтобы узнать, есть ли новые данные, вернуть.NewData
, если да, и использовать.NoData
, если нет. Кроме того, похоже, что сигнатура этой функции (по крайней мере, в последней версии) заключается в том, чтоapplication
иcompletionHandler
изperformFetchWithCompletionHandler
не являются необязательными, поэтому вы также можете проверить это. - person Rob   schedule 10.04.2015