swift:用于博客 + 多个实体的带有滑出式导航的核心数据

Posted

技术标签:

【中文标题】swift:用于博客 + 多个实体的带有滑出式导航的核心数据【英文标题】:swift: core data with slideout navigation for a blog + multiple entities 【发布时间】:2015-02-23 06:27:24 【问题描述】:

我正在制作一个博客阅读器应用程序,其中博客的类别列在滑出导航中,每个类别都获取唯一的 JSON 结果并显示在 CenterViewController 中

现在,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?()


注意:代码中animal.url!是获取到的分类的url

所以每次我从滑出导航中选择一个新类别时,核心数据都会被新类别的内容覆盖,加载时间太长。

关于我的问题,是否可以在每个类别的 coredata 中拥有一个唯一实体,以便结果不会被覆盖?是否建议实施这样的事情?

我不知道如果我获取它们各自实体中的所有类别,我将如何在我的同一个 UITableview 中为 CenterViewController 显示它们?

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!

在我的智慧尽头..请请帮助

【问题讨论】:

【参考方案1】:

是的,这是可能的,也是可取的。在 Category 实体和 MIBlog 实体之间创建关系。将每个 MIBlog 对象保存到 Core Data 时,您应该检查该名称/id 的类别是否存在,如果存在,则使用它,如果不存在,则创建该类别。我使用这些函数来做到这一点:

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")
        
    

然后,您可以使用对类别实体的获取请求轻松检索数组中的所有类别,甚至可以检查以确保该类别中确实包含博客文章。

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]

【讨论】:

听起来不错......但我没有得到实际要做的事情......我创建了一个名为Category的实体??它将如何为每个类别唯一地存储内容?我已经在 que 中更新了我的 fetchResultController 代码。如果 m 听起来很愚蠢,我很抱歉..bt m 是 ios 新手 shd 类别实体具有与 MIBlog 相同的属性?? 是的。一个新的类别实体。每当您存储新的博客文章时,都将其“类别”属性设置为类别对象。你可以使用fetchOrCreateCategory(name) 我认为这里的问题是不同的。对于导航菜单中的每个项目,我都有一个单独的 URL,如下所示:http://www.domain.com/api/get_recent_posts/?json=get_category_posts&amp;slug=news 其中 slug 是类别。我正在考虑为每个类别创建一个新实体。这不可以吗?? 您不会为每个类别创建单独的实体。您创建一个 Category 实体,然后为每个类别创建一个 Category 对象。

以上是关于swift:用于博客 + 多个实体的带有滑出式导航的核心数据的主要内容,如果未能解决你的问题,请参考以下文章

实现滑出式导航IOS的最佳方式

css 滑出式导航抽屉

滑出式菜单不显示网页第 2 部分中的导航链接

滑出保持突出显示的导航项

快速滑出菜单而不滑动导航栏(以编程方式)

UISplitViewController - 用作滑出式菜单