{"id":40703,"date":"2023-10-02T09:42:58","date_gmt":"2023-10-02T13:42:58","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=40703"},"modified":"2023-10-11T16:43:41","modified_gmt":"2023-10-11T20:43:41","slug":"model-for-coredata","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2023\/10\/02\/model-for-coredata\/","title":{"rendered":"@Model for CoreData"},"content":{"rendered":"<p><a href=\"https:\/\/www.alwaysrightinstitute.com\/managedmodels\/\">Helge He&szlig;<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.alwaysrightinstitute.com\/managedmodels\/\"><p><a href=\"https:\/\/github.com\/Data-swift\/ManagedModels\/\">ManagedModels<\/a> is a package\nthat provides a\n<a href=\"https:\/\/www.swift.org\/blog\/swift-5.9-released\/\">Swift 5.9<\/a> \nmacro similar to the\nSwiftData\n<a href=\"https:\/\/developer.apple.com\/documentation\/SwiftData\/Model()\">@Model<\/a>.\nIt can generate CoreData\n<a href=\"https:\/\/developer.apple.com\/library\/archive\/documentation\/DataManagement\/Devpedia-CoreData\/managedObjectModel.html\">ManagedObjectModel<\/a>&rsquo;s\ndeclaratively from Swift classes, \nw\/o having to use the Xcode &ldquo;CoreData Modeler&rdquo;.<\/p><p>Unlike SwiftData it doesn&rsquo;t require iOS 17+ and works directly w\/\n<a href=\"https:\/\/developer.apple.com\/documentation\/coredata\">CoreData<\/a>.\nIt is <strong>not<\/strong> a direct API replacement, but a look-a-like.<\/p><p>[&#8230;]<\/p><p>A CoreData object has to be initialized through some \n<a href=\"https:\/\/developer.apple.com\/documentation\/coredata\/nsmanagedobject\/1506357-init\">very specific initializer<\/a>,\nwhile a SwiftData model class <em>must have<\/em> an explicit <code>init<\/code>, \nbut is otherwise pretty regular.<\/p><p>The ManagedModels <code>@Model<\/code> macro generates a set of helper inits to deal with\nthat.\nBut the general recommendation is to use a <code>convenience init<\/code> like so[&#8230;]<\/p><\/blockquote>\n<p>I like this general approach, but my experience is that it&rsquo;s not good to cache the <code>NSEntityDescription<\/code>. If you return it from a class method, there can be problems if you use the same managed object class with multiple managed object models or multiple instances of the same model when testing. (I avoid the similar convenience methods that are built into Core Data, too.) Maybe this has since been fixed, but I found that it worked better to specify the entity by name in the fetch request so that it gets looked up in the proper managed object model.<\/p>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2023\/07\/17\/macros-in-swift-5-9\/\">Macros in Swift 5.9<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2023\/06\/12\/swiftdata\/\">SwiftData<\/a><\/li>\n<\/ul>\n\n<p id=\"model-for-coredata-update-2023-10-09\">Update (2023-10-09): <a href=\"https:\/\/mastodon.social\/@helge\/111193776319389798\">Helge He&szlig;<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@helge\/111193776319389798\">\n<p>Frohlocket, a new release of my #SwiftLang Model macro for #CoreData is out. As suggested by @mjtsai entities are not cached in the type anymore and multiple MOMs can be built from them (MOMs themselves are still cached for other methods that take PersistentModel types, like <code>.modelContainer(for: Todo.self)<\/code>). And a few more bugfixes related to optionals.<\/p>\n<\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Helge He&szlig;: ManagedModels is a package that provides a Swift 5.9 macro similar to the SwiftData @Model. It can generate CoreData ManagedObjectModel&rsquo;s declaratively from Swift classes, w\/o having to use the Xcode &ldquo;CoreData Modeler&rdquo;.Unlike SwiftData it doesn&rsquo;t require iOS 17+ and works directly w\/ CoreData. It is not a direct API replacement, but a look-a-like.[&#8230;]A [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2023-10-02T13:43:01Z","apple_news_api_id":"1e249827-0205-4fee-a6a4-689381079f7e","apple_news_api_modified_at":"2023-10-09T13:13:09Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAAAA==","apple_news_api_share_url":"https:\/\/apple.news\/AHiSYJwIFT-6mpGiTgQeffg","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[109,31,2321,30,2385,941,74,71,901,2404],"class_list":["post-40703","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-coredata","tag-ios","tag-ios-17","tag-mac","tag-macos-14-sonoma","tag-macros","tag-opensource","tag-programming","tag-swift-programming-language","tag-swiftdata"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/40703","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=40703"}],"version-history":[{"count":2,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/40703\/revisions"}],"predecessor-version":[{"id":40744,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/40703\/revisions\/40744"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=40703"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=40703"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=40703"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}