简体   繁体   English

swift:具有博客+多个实体的滑出导航的核心数据

[英]swift: core data with slideout navigation for a blog + multiple entities

I am making a blog reader app in which the categories of the blog are listed in the slide out navigation and each category fetches unique JSON Results and displays in the CenterViewController 我正在制作一个博客阅读器应用程序,其中博客的类别列在滑出导航中,每个类别都会获取独特的JSON结果并显示在CenterViewController中

Now, the CenterViewConroller saves the data into CoreData before displaying it in the UITableView with this code: 现在,CenterViewConroller将数据保存到CoreData中,然后使用以下代码在UITableView中显示它:

func animalSelected(animal: Animal) {

var appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
var context: NSManagedObjectContext = appDel.managedObjectContext!

showProgressHUD()

let session = NSURLSession.sharedSession()
var error : NSError?
 var posts = [[String:String]()]

let task = session.dataTaskWithURL(animal.url!, completionHandler: {data, response, error -> Void in

    if (error != nil){
        println(error)

    }else{

        var request = NSFetchRequest(entityName: "MIBlog")
        request.returnsObjectsAsFaults = false
        var results = context.executeFetchRequest(request, error: nil)

        for result in results!
        {
            context.deleteObject(result as NSManagedObject)
            context.save(nil)

        }


        let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary

        var post:AnyObject

        var authorDictionary:AnyObject
        var newBlogItem:NSManagedObject
        for var i = 0; i < jsonResult["posts"]!.count; i++
        {
            posts.append([String:String]())
            post = jsonResult["posts"]![i] as NSDictionary
            posts[i]["title"] = post["title"] as? NSString
            posts[i]["publishedDate"] = post["date"] as? NSString
            posts[i]["content"] = post["content"] as? NSString
            authorDictionary = post["author"] as NSDictionary
            posts[i]["author"] = post["name"] as? NSString
            posts[i]["thumbnailURL"] = post["thumbnail"] as? NSString
            posts[i]["postURL"] = post["url"] as? NSString


            newBlogItem = NSEntityDescription.insertNewObjectForEntityForName("MIBlog", inManagedObjectContext: context) as NSManagedObject
            newBlogItem.setValue(posts[i]["title"], forKey: "title")
            newBlogItem.setValue(posts[i]["publishedDate"], forKey: "publishedDate")
            newBlogItem.setValue(posts[i]["content"], forKey: "content")
            newBlogItem.setValue(posts[i]["author"], forKey: "author")
            newBlogItem.setValue(posts[i]["thumbnailURL"], forKey: "thumbnailURL")
             newBlogItem.setValue(posts[i]["postURL"], forKey: "postURL")

             context.save(nil)
        }

       request = NSFetchRequest(entityName: "MIBlog")
        request.returnsObjectsAsFaults = false
   results = context.executeFetchRequest(request, error: nil)

    }   
})

task.resume()

delegate?.collapseSidePanels?()

}

Note: In the code animal.url! 注意:在代码animal.url! is the url of the category fetched 是获取类别的网址

So everytime i select a new category from the slideout navigation, the core data is overwritten with the contents of new category and it takes too much time in loading. 因此,每次从滑出导航中选择一个新类别时,核心数据都会被新类别的内容覆盖,并且加载时间过长。

Coming to my question, is it possible to have a unique entity in coredata for each category so that the results dont get overwritten?? 提出我的问题,是否有可能在每个类别的coredata中有一个唯一的实体,以便结果不会被覆盖? Is it advisable to implement something like this?? 是否可以实现这样的事情?

I am not able to figure that if i fetch all categories in their respective entities, how will i display them all in my same UITableview for CenterViewController? 我无法确定如果我获取各自实体中的所有类别,我将如何在我的同一个UITableview中为CenterViewController显示它们?

FetchResultController FetchResultController

// MARK: - Fetched results controller

var fetchedResultsController: NSFetchedResultsController {
    if _fetchedResultsController != nil {
        return _fetchedResultsController!
        }
        var appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
        self.managedObjectContext = appDel.managedObjectContext

        let fetchRequest = NSFetchRequest()
        // Edit the entity name as appropriate.
        let entity = NSEntityDescription.entityForName("MIBlog", inManagedObjectContext: self.managedObjectContext!)
        fetchRequest.entity = entity

        // Set the batch size to a suitable number.
        fetchRequest.fetchBatchSize = 20

        // Edit the sort key as appropriate.
        let sortDescriptor = NSSortDescriptor(key: "publishedDate", ascending: false)
        let sortDescriptors = [sortDescriptor]

        fetchRequest.sortDescriptors = [sortDescriptor]

        // Edit the section name key path and cache name if appropriate.
        // nil for section name key path means "no sections".
        let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: nil, cacheName: "Master")
        aFetchedResultsController.delegate = self
        _fetchedResultsController = aFetchedResultsController

        var error: NSError? = nil
        if !_fetchedResultsController!.performFetch(&error) {
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            //println("Unresolved error \(error), \(error.userInfo)")
            abort()
        }

        return _fetchedResultsController!
}

At my wits end.. plsss pls pls help 在我的智慧结束.. plsss请帮忙

Yes, it is possible and it is advisable. 是的,这是可能的,这是可取的。 Create a relationship between a Category entity and a MIBlog entity. 在Category实体和MIBlog实体之间创建关系。 When saving each MIBlog object to Core Data, you should check to see if a category by that name/id exists, and if it exists, use it, and if not, create that category. 将每个MIBlog对象保存到Core Data时,应检查是否存在该名称/ id的类别,如果存在,则使用它,如果不存在,则创建该类别。 I use these functions to do so: 我使用这些函数来做到这一点:

func fetchCategory(name: String) -> Category? {

    let fetchRequest = NSFetchRequest(entityName: "Category")
    let predicate = NSPredicate(format: "name = %@", name)

    // Assign fetch request properties
    fetchRequest.predicate = predicate
    fetchRequest.fetchBatchSize = 1
    fetchRequest.fetchLimit = 1

    // Handle results
    let fetchedResults = managedObjectContext?.executeFetchRequest(fetchRequest, error: nil)

    if fetchedResults?.count != 0 {

        if let fetchedCategory: Category = fetchedResults![0] as? Category {
            return fetchedCategory
        }
    }
    return nil
}

func fetchOrCreateCategory(name: String) -> Category {
    if let category = fetchCategory(name) {
        return category
    } else {
        if !name.isEmpty {
            createCategory(name)
            return fetchOrCreateCategory(name)
        } else {
            return fetchOrCreateCategory("Other")
        }
    }
}

Then you can easily retrieve all categories in an array using a fetch request for the categories entity and you can even check to make sure the category actually has blog posts in it. 然后,您可以使用类别实体的获取请求轻松检索数组中的所有类别,您甚至可以检查以确保该类别实际上包含博客帖子。

func fetchCategories() -> [Category] {
    let fetchRequest = NSFetchRequest(entityName: "Category")
    let sortDescriptor = NSSortDescriptor(key: "name", ascending: true)
    let predicate = NSPredicate(format: "blogs.@count != 0") // blogs is whatever you relationship attribute is

    fetchRequest.predicate = predicate
    fetchRequest.sortDescriptors = [sortDescriptor]

    return managedObjectContext?.executeFetchRequest(fetchRequest, error: nil) as! [Category]
}

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

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