Core Data MVVM Example - ios

Is this good or bad code for MVVM pattern with Core Data. For example i have Category+CoreDataClass.swift and CategoryDataProperties.swift; thats my
public class Account: NSManagedObject {
//what should i write here; any clue
}
extension Account {
#nonobjc public class func fetchRequest() -> NSFetchRequest<Category> {
return NSFetchRequest< Category >(entityName: "Category")
}
#NSManaged public var categoryId: Int64
#NSManaged public var categoryTitle: String
}
Model = Category
class CategoryViewModel{
var category:Category() //
var categories: [Category]()
func AddCategory(category) {
//pass category to CoreData save method in CoreDataService.swift
}
}
and ViewModel is used in Single Screen with two textField named categoryId,categoryName(UIView)
class CategoryVC: UITableViewController {
var vm: CategoryViewModel!
}

Related

How to handle optional/missing attributes of related Core Data objects in NDPredicate

I've recently ran into an issue with core data that I'm unable to solve.
I have the following object and relationships Recommendation <---> Item
extension Recommendation {
#nonobjc public class func fetchRequest() -> NSFetchRequest<Recommendation> {
return NSFetchRequest<Recommendation>(entityName: "Recommendation")
}
#NSManaged public var age: Int?
#NSManaged public var tags: Array<String>?
#NSManaged public var object: Item?
}
extension Item {
#nonobjc public class func fetchRequest() -> NSFetchRequest<Item> {
return NSFetchRequest<Recommendation>(entityName: "Item")
}
#NSManaged public var id: String?
#NSManaged public var name: String?
#NSManaged public var recommendation: Recommendation?
}
I want to fetch all Items based on attributes in their related Recommendation.
Some of these attributes could be missing.
How would I create a NSPredicate to fetch objects where the Recommendation.age or Recommendation.tags could be non-existent (applicable to all ages/tags) or should be compared against a provided value?
Should I always provide a Default Value?

How to save one-many relationship data into core data using Objective-C

I have a newsfeeditem and many users have shared this newsfeeditem.I need to save many users for one newsfeedItem.I had a one-many relationship from newsFeedItem to SlickUser.
but i don't know how I can save or relate SlickUser data to newsFeedItem. sorry im new to core data and im not able to save data using one to many relationship. if anyone can guide me how i can use SlickOwner to save data in newsFeedItem
for(int i =0 ; i < posts.user.count ; i++)
{
SlickUser * user = posts.user[i];
if (self.contactdb) {
[self.contactdb setValue:user.Aprovider forKey:#"Aprovider"];
[self.contactdb setValue:user.name forKey:#"name"];
[self.contactdb setValue:user.userid forKey:#"userid"];
}
else{
NSManagedObject *newdevice = [NSEntityDescription insertNewObjectForEntityForName:#"SlickUser" inManagedObjectContext:context];
[newdevice setValue:user.Aprovider forKey:#"Aprovider"];
[newdevice setValue:user.name forKey:#"name"];
[newdevice setValue:user.userid forKey:#"userid"];
NSError *error = nil;
if (![context sa[here is the image for newsFeedItem ][1]ve:&error])
{
NSLog(#"can't save %# %#", error, [error localizedDescription]);
}
}
}
here is newsFeedItem Entity :
extension NewsFeedDataItem {
#nonobjc public class func fetchRequest() -> NSFetchRequest<NewsFeedDataItem> {
return NSFetchRequest<NewsFeedDataItem>(entityName: "NewsFeedDataItem")
}
#NSManaged public var aprovider: String?
#NSManaged public var lid: String?
#NSManaged public var owner: NSSet?
}
xtension NewsFeedDataItem {
#objc(addOwnerObject:)
#NSManaged public func addToOwner(_ value: SlickUser)
#objc(removeOwnerObject:)
#NSManaged public func removeFromOwner(_ value: SlickUser)
#objc(addOwner:)
#NSManaged public func addToOwner(_ values: NSSet)
#objc(removeOwner:)
#NSManaged public func removeFromOwner(_ values: NSSet)
}
and this is UserSlick entity:
extension SlickUser {
#nonobjc public class func fetchRequest() -> NSFetchRequest<SlickUser> {
return NSFetchRequest<SlickUser>(entityName: "SlickUser")
}
#NSManaged public var aprovider: Int64
#NSManaged public var userid: String?
#NSManaged public var userPic: String?
#NSManaged public var newsFeedPost: NewsFeedDataItem?
}
this is the screenshort for slickUser
What you are missing is additional relationships between your SlickUser and NewsFeedDataItem. You have a single one-to-many relationship defined between your user and item - NewsFeedDataItem.owner -> SlickUser - and the inverse of that relationship SlickUser.newsFeedPost -> NewsFeedDataItem.
Here's the assumptions I'm making about what you are trying to achieve:
An Item is owned by a User [one-to-one]
An Item can can shared by many User [one-to-many]
A User can be the owner a many Item [one-to-many]
A User can share many Item [one-to-many]
What is defined here represents four (4) relationships between your User and Item.
Here's how I've configured everything:
NewsFeedDataItem
import Foundation
import CoreData
#objc(NewsFeedDataItem)
public class NewsFeedDataItem: NSManagedObject {
}
extension NewsFeedDataItem {
#nonobjc public class func fetchRequest() -> NSFetchRequest<NewsFeedDataItem> {
return NSFetchRequest<NewsFeedDataItem>(entityName: "NewsFeedDataItem")
}
#NSManaged public var aprovider: String?
#NSManaged public var lid: String?
#NSManaged public var owner: SlickUser?
#NSManaged public var sharedBy: NSSet?
}
// MARK: Generated accessors for sharedBy
extension NewsFeedDataItem {
#objc(addSharedByObject:)
#NSManaged public func addToSharedBy(_ value: SlickUser)
#objc(removeSharedByObject:)
#NSManaged public func removeFromSharedBy(_ value: SlickUser)
#objc(addSharedBy:)
#NSManaged public func addToSharedBy(_ values: NSSet)
#objc(removeSharedBy:)
#NSManaged public func removeFromSharedBy(_ values: NSSet)
}
SlickUser
import Foundation
import CoreData
#objc(SlickUser)
public class SlickUser: NSManagedObject {
}
extension SlickUser {
#nonobjc public class func fetchRequest() -> NSFetchRequest<SlickUser> {
return NSFetchRequest<SlickUser>(entityName: "SlickUser")
}
#NSManaged public var aprovider: Int64
#NSManaged public var userid: String?
#NSManaged public var userPic: String?
#NSManaged public var userPosts: NSSet?
#NSManaged public var sharedPosts: NSSet?
}
// MARK: Generated accessors for userPosts
extension SlickUser {
#objc(addUserPostsObject:)
#NSManaged public func addToUserPosts(_ value: NewsFeedDataItem)
#objc(removeUserPostsObject:)
#NSManaged public func removeFromUserPosts(_ value: NewsFeedDataItem)
#objc(addUserPosts:)
#NSManaged public func addToUserPosts(_ values: NSSet)
#objc(removeUserPosts:)
#NSManaged public func removeFromUserPosts(_ values: NSSet)
}
// MARK: Generated accessors for sharedPosts
extension SlickUser {
#objc(addSharedPostsObject:)
#NSManaged public func addToSharedPosts(_ value: NewsFeedDataItem)
#objc(removeSharedPostsObject:)
#NSManaged public func removeFromSharedPosts(_ value: NewsFeedDataItem)
#objc(addSharedPosts:)
#NSManaged public func addToSharedPosts(_ values: NSSet)
#objc(removeSharedPosts:)
#NSManaged public func removeFromSharedPosts(_ values: NSSet)
}
The SlickUser.userPosts is a set of Items that are owned by the User.
The SlickUser.sharedPosts is a set of Items that the User has shared.
The NewsFeedDataItem.owner is the owner of the Item.
The NewsFeedDataItem.sharedBy is a set of User that have shared the Item.
For each of the relationship pairs owner <> userPosts and sharedBy <> sharedPosts, you will need to set at least one side of the relationship on your managed object. CoreData will manage the rest.
Does this solution address the needs of your project?

Add function to NSManagedObject class

I' ve a Size class generated from Xcode for my size model, here it is:
#objc(Size)
public class Size: NSManagedObject {
override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) {
super.init(entity: entity, insertInto: context)
}
}
extension Size {
#nonobjc public class func fetchRequest() -> NSFetchRequest<Size> {
return NSFetchRequest<Size>(entityName: "Size")
}
#NSManaged public var id: Int16
#NSManaged public var name: String?
var quantity: Int
func setQuantity() {}
}
Quantity var and setQuantity method are not accessible from my ViewController though I put public before their declaration, some suggestion?
You will be getting the compiler error: Extensions must not contain stored properties
You should update it and put the variable to your class instead of to extension.
public class Size: NSManagedObject {
var quantity: Int
// Same for other variables.
// Your existing code goes here.
}
Try and share your results.

How to create an interface for a CoreData model (NSManagedObject)?

I'm trying to migrate from CoreData to FireBase. Hence the need for a shared interface across the app for my model.
I have a FTEvent class...
#objc(FTEvent)
public class FTEvent: FTEventBase {
}
that inherits from FTEventBase
#objc(FTEventBase)
public class FTEventBase: NSManagedObject {
}
Now I have a new class called FTRecord, which should share an interface with FTEvent above.
class FTRecord {
let key: String
var notes: String
var rating: Int
var time: String
var timestamp: Double
}
This is now where the problem begins. I could obviously create a protocol as interface for both FTRecord and FTEvent.
protocol IEvent {
var is_deleted: Bool? { get set }
var notes: String? { get set }
var date: Date? { get set }
var timestamp: Double? { get set }
var rating: Int? { get set }
}
But this becomes very hard since Bool in CoreData is actually a NSNumber. The Date is NSDate. Because of these type differences, I have no way to create a common interface.
Is there any advice, how I could achieve that?

XCode 8 CoreData auto generated Base classes

I use Xcode 8 CoreData with auto generated Base classes.
When I try
let fetchRequest: NSFetchRequest<Event> = Event.fetchRequest()
fetchRequest variable correctly gets type of NSFetchRequest<Event>
When I try
let fetchRequest = Event.fetchRequest()
Xcode tells that fetchRequest has undefined type, as I understand Swift must determine type automatically by making assignment
Here is the auto generated class extension generated by Xcode
extension Event {
#nonobjc public class func fetchRequest() -> NSFetchRequest<Event> {
return NSFetchRequest<Event>(entityName: "Event");
}
#NSManaged public var ffff: String?
#NSManaged public var timestamp: NSDate?
}
As an example this code works correctly (logic is the same)
struct MyStruct<T> {
let myVar: T
}
class MyClass {
}
extension MyClass {
class func test() -> MyStruct<Int> {
return MyStruct<Int>(myVar: 5)
}
}
let b = MyClass.test()
let b has a correct type of MyStruct<Int>
CoreDate automatically generated
#objc(Event)
public class Event: NSManagedObject {
}
extension Event {
#nonobjc public class func fetchRequest() -> NSFetchRequest<Event> {
return NSFetchRequest<Event>(entityName: "Event");
}
#NSManaged public var timestamp: NSDate?
}
NSManagedObject protocol is in Objective-C and it has class method
+ (NSFetchRequest*)fetchRequest
When i try to use let fetchRequest = Event.fetchRequest() it thinks that i call Objective-C + (NSFetchRequest*)fetchRequest and it has no generics
Why doesn't it use an overridden #nonobjc public class func fetchRequest() -> NSFetchRequest<Event> from an Event class extension?

Resources