简体   繁体   English

核心数据完成后的Swift iOS 9 UITableView reloadData

[英]Swift iOS 9 UITableView reloadData after CoreData finished

I try to update my tableview after my REST-call is finished and all entities are stored in CoreData. 我尝试完成REST调用并将所有实体存储在CoreData中后,尝试更新表视图。 I tried dispatch_asynch but the tableview doesn't reload when expected. 我尝试了dispatch_asynch,但是在期望时不会重新加载tableview。 I am using a UIRefreshControl to trigger refreshing. 我正在使用UIRefreshControl触发刷新。 Usually, the correct tableview data is displayed after 2 refreshes. 通常,刷新2次后将显示正确的tableview数据。 I have no idea why. 我不知道为什么。

I can confirm that my tableview instance IS NOT nil. 我可以确认我的tableview实例不是nil。

@IBAction func refreshTriggered(sender: UIRefreshControl) {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
        self.evMan.retrieveAndSaveEvents(self.pubMan.getAllPublishers())


      dispatch_async(dispatch_get_main_queue()) {
          self.tableView.reloadData()
          self.refreshControl?.endRefreshing()
      }
   }
}

This is my retrieveAndSaveEvents method from my 'EventManager' evMan: 这是我的“ EventManager” evMan中的retrieveAndSaveEvents方法:

func retrieveAndSaveEvents(forPublishers: [PUBLISHERS]) {

    for publisher in forPublishers {

        let pubId = publisher.id as Int
        let str = "/publishers/\(pubId)/events"

        // resty is an instance of my REST-api wrapper
        self.resty.GET(self.server, route: str, onCompletion: {json in

            let result = json.asArray

            for var i = 0; i < result!.count; i++ {

                if !self.isIDAlreadyInDB(json[i]["id"].asInt!) {
                    let newEv = NSEntityDescription.insertNewObjectForEntityForName("EVENTS", inManagedObjectContext: self.context!) as! EVENTS
                    newEv.headline = json[i]["headline"].asString!
                    newEv.id = json[i]["id"].asInt!
                    newEv.content = json[i]["content"].asString!
                    newEv.ofPublisher = publisher

                    do {
                        try self.context!.save()
                    } catch _ {
                    }

                    print("New Event from \(publisher.name): \(newEv.headline)")
                }
            }
        })
    }
}

FYI, here's my cellForRowAtIndexPath: (I am using a Custom UITableViewCell) 仅供参考,这是我的cellForRowAtIndexPath :(我正在使用自定义UITableViewCell)

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = self.tableView.dequeueReusableCellWithIdentifier("eventCell") as? EventCell

    let curEv = evMan.getEvents()[indexPath.row]

    cell?.infoLabel.text = curEv.ofPublisher?.name
    cell?.myImageView.image = UIImage(named: "icon.png")
    cell?.detailLabel.text = curEv.headline
    cell?.timeLabel.attributedText = NSAttributedString(string: self.dateFormatter.stringFromDate(curEv.updatedAt))
    cell?.contentView.backgroundColor = UIColor.clearColor()
    cell?.backgroundColor = UIColor(white: 1.0, alpha: 0.5)

    return cell!
}

Here is my REST-wrapper: 这是我的REST包装器:

class REST: NSObject {

// Basic Auth
let sConfig = ServerConfig()

var username = "rest"
var password = "resttest"

override init() {
    username = sConfig.getUserLogin().user
    password = sConfig.getUserLogin().pass
}

func GET(server: String, route: String, onCompletion: (JSON) -> Void) {
    let route = server+route
    makeHTTPGetRequest(route, onCompletion: { json, err in
        onCompletion(json as JSON)
    })
}

func makeHTTPGetRequest(path: String, onCompletion: ServiceResponse) {
    let request = NSMutableURLRequest(URL: NSURL(string: path)!)

    let loginString = NSString(format: "%@:%@", username, password)
    let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)!
    let base64LoginString = loginData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions())
    let loginvalue = "Basic " + base64LoginString

    // add Headers
    request.addValue(loginvalue, forHTTPHeaderField: "Authorization")
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")

    let session = NSURLSession.sharedSession()

    let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
        let json:JSON = JSON(data: data!)
        onCompletion(json, error)
    })
    task.resume()
}
}
@IBAction func refreshTriggered(sender: UIRefreshControl) {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
        self.evMan.retrieveAndSaveEvents(self.pubMan.getAllPublishers())
    })

    dispatch_async(dispatch_get_main_queue()) {
        self.tableView.reloadData()
        self.refreshControl?.endRefreshing()
    }
}

Now, you cannot guarantee reloadData() happens after self.evMan.retrieveAndSaveEvents(self.pubMan.getAllPublishers()) , because they are not happen in the same queue. 现在,您不能保证reloadData()self.evMan.retrieveAndSaveEvents(self.pubMan.getAllPublishers())之后发生,因为它们不在同一队列中发生。 And probably, reloadData() happens before retrieve. 可能reloadData()发生在检索之前。

Option 1: 选项1:

You should put the block : 你应该把块:

   dispatch_async(dispatch_get_main_queue()) {
        self.tableView.reloadData()
        self.refreshControl?.endRefreshing()
    }

at the end of func retrieveAndSaveEvents(self.pubMan.getAllPublishers()) func retrieveAndSaveEvents(self.pubMan.getAllPublishers())结尾的位置func retrieveAndSaveEvents(self.pubMan.getAllPublishers())

Option 2 : 选项2:

 @IBAction func refreshTriggered(sender: UIRefreshControl) {

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
            self.evMan.retrieveAndSaveEvents(self.pubMan.getAllPublishers())
            dispatch_async(dispatch_get_main_queue()) {
                self.tableView.reloadData()
                self.refreshControl?.endRefreshing()
            }
        })

    }

EDIT: 编辑:

I did not see there is another queue in retrieveAndSaveEvents 我没有在retrieveAndSaveEvents看到另一个队列

So, put the 所以,把

   dispatch_async(dispatch_get_main_queue()) {
        self.tableView.reloadData()
        self.refreshControl?.endRefreshing()
    }

at the end of: 在......的最后:

self.resty.GET(self.server, route: str, onCompletion: {json in
        let result = json.asArray

        for var i = 0; i < result!.count; i++ {

            if !self.isIDAlreadyInDB(json[i]["id"].asInt!) {
                let newEv = NSEntityDescription.insertNewObjectForEntityForName("EVENTS", inManagedObjectContext: self.context!) as! EVENTS
                newEv.headline = json[i]["headline"].asString!
                newEv.id = json[i]["id"].asInt!
                newEv.content = json[i]["content"].asString!
                newEv.ofPublisher = publisher

                do {
                    try self.context!.save()
                } catch _ {
                }

                print("New Event from \(publisher.name): \(newEv.headline)")
            }
        }
    })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM