How to convert NSObject model class to a sub-class of NSManagedObject? - ios

I have this simple model class that represent rss article called RSSEntry.
Now I want to start working wit core data with this model class, but I didn't create the project with the 'use core data' checkbox checked.
this is the class:
#import <Foundation/Foundation.h>
#interface FRSSEntry : NSObject{
NSString *_blogTitle;
NSString *_articleTitle;
NSString *_articleUrl;
NSDate *_articleDate;
NSString *_articleImageUrl;
NSString *_content;
}
#property (copy) NSString *blogTitle;
#property (copy) NSString *articleTitle;
#property (copy) NSString *articleUrl;
#property (copy) NSDate *articleDate;
#property (copy) NSString *articleImageUrl;
#property (copy) NSString *content;
- (id)initWithBlogTitle:(NSString*)blogTitle articleTitle:(NSString*)articleTitle articleUrl:(NSString*)articleUrl articleDate:(NSDate*)articleDate articleImageUrl:(NSString *)imageUrl andContent:(NSString *)content;
#end
the implementations is:
#import "FRSSEntry.h"
#implementation FRSSEntry
#synthesize blogTitle = _blogTitle;
#synthesize articleTitle = _articleTitle;
#synthesize articleUrl = _articleUrl;
#synthesize articleDate = _articleDate;
#synthesize articleImageUrl = _articleImageUrl;
#synthesize content = _content;
- (id)initWithBlogTitle:(NSString*)blogTitle articleTitle:(NSString*)articleTitle articleUrl:(NSString*)articleUrl articleDate:(NSDate*)articleDate articleImageUrl:(NSString *)imageUrl andContent:(NSString *)content
{
if ((self = [super init])) {
_blogTitle = [blogTitle copy];
_articleTitle = [articleTitle copy];
_articleUrl = [articleUrl copy];
_articleDate = [articleDate copy];
_articleImageUrl = [imageUrl copy];
_content = [content copy];
}
return self;
}
#end
very simple. Now how do I convert it so I can use it as a core data entity?

So to transform your model class into an NSManagedObject subclass you have to remove the instance variable declarations. Then replace all your #synthesize statements with #dynamic. This tells the compiler that CoreData will provide the implementation for those properties so it can do it's magic there. The custom initializer you have then also needs to be removed because NSManagedObject objects are initialized in a different way.
The code would look something like
#import <Foundation/Foundation.h>
#interface FRSSEntry : NSManagedObject
#property (copy) NSString *blogTitle;
#property (copy) NSString *articleTitle;
#property (copy) NSString *articleUrl;
#property (copy) NSDate *articleDate;
#property (copy) NSString *articleImageUrl;
#property (copy) NSString *content;
#end
-
#import "FRSSEntry.h"
#implementation FRSSEntry
#dynamic blogTitle;
#dynamic articleTitle;
#dynamic articleUrl;
#dynamic articleDate;
#dynamic articleImageUrl;
#dynamic content;
#end
You usually initialize them with something like
// Get the entity description
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"FRSSEntry" inManagedObjectContext:context];
// Insert a new YourModelObject into the context
ReceivedMessage *newMessage = [[FRSSEntry alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:context];
You could have a custom initializer but you would have to call [super initWithEntity:entityDescription insertIntoManagedObjectContext:context]. The initializer would get really long with all this parameters so I suggest you just set each property once you have the object initialized.
Judging from your response, you have just begun CoreData integration. Creating an NSManagedObject subclass is just a tip of the iceberg when working with core data. CoreData is a big an complex framework so I suggest you start by reading https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html. Stack Overflow is also full of questions and great answers on this topic.
Another thing I suggest you look into is MagicalRecord. It's a great library that makes some of the tedious tasks very simple: https://github.com/magicalpanda/MagicalRecord

Related

how to use realm to save an array of NSURL?

Now, I have a realm model , including images, audios and others. So I have to get the URLs of the media files and give the model value of the URLs. But I meet a problem that I cannot save them into the realm. Because I can not save NSArray , also when I use the RLMArray to contain them ,it also don't be solved. So how can I give my model the URLs?
Its not possilbe to directly add the NSURL type in Realm but you can use workaround on your own like :-
#interface MyModel : JOBIBaseModel
#property (nonatomic, strong) NSString * urlString;
-(NSURL *)getUrl;
#end
#implementation MyModel
-(NSURL *)getUrl{
return [NSURL URLWithString:self.urlString];
}
#end
Then access it from your object like:-
NSURL *url=Obj.getUrl;
Update for array
RLM_ARRAY_TYPE(MyArrayModel);
#interface MyArrayModel : JOBIBaseModel
#property (nonatomic, strong) NSString * urlString;
-(NSURL *)getUrl;
#end
#implementation MyArrayModel
-(NSURL *)getUrl{
return [NSURL URLWithString:self.urlString];
}
#end
#interface MyModel : JOBIBaseModel
#property (nonatomic, strong) RLMArray <MyArrayModel> * strings;
#end
#implementation MyModel
#end
And use it like:-
NSURL *url=Obj.strings[0].getUrl;

JSONModel used with Objects/Dictionaries

Ive been working with JSONModel, the tutorials are making sense. They are parsing JSON contain an array with multiple indexes.
I wanted to make sure JSONModel allowed to be used with say this dataset: https://gist.github.com/ryancoughlin/8043604
tide is not an array correct? But there is tide.tideSummary - which contains array of tide data across multiple days.
AllTide.h
#import "JSONModelLib.h"
#import "Tide.h"
#interface AllTide : JSONModel
#property (strong,nonatomic) NSDictionary<Tide> *tide;
#end
Tide.h
#import "JSONModelLib.h"
#import "TideSummaryStats.h"
#protocol Tide #end
#interface Tide : JSONModel
#property (nonatomic, strong) NSArray<TideSummaryStats> *tideSummaryStats;
#end
TideSummaryStats.h
#import "JSONModelLib.h"
#protocol TideSummaryStats #end
#interface TideSummaryStats : JSONModel
#property (nonatomic, strong) NSString *maxheight;
#property (nonatomic, strong) NSString *minheight;
#end
TideDetailViewController - Displays a single location (detail view) vs a list of multiple locations
#interface TideDetailViewController () {
AllTide *_objTide;
}
#end
#implementation TideDetailViewController
- (void)viewDidAppear:(BOOL)animated {
NSString *locationQueryURL = #"http://api.wunderground.com/api/xxxxx/tide/geolookup/q/43.5263,-70.4975.json";
//fetch the feed
_objTide = [[AllTide alloc] initFromURLWithString:locationQueryURL completion:^(JSONModel *model, JSONModelError *err) {
NSLog(#"Tides: %#", _objTide.tide);
}];
}
Been going through several JSONModel tutorials and it makes sense, I think I am having trouble where my JSON format differs from the tutorials. Again, where my tide does not return an array.
Would this be a good case to utilize JSONModel keymapper?
Any ideas? Let me know if I can provide anything else. Been diving around for some guidance, but a bit stuck. Thanks in advance!
you don't need AllTide.h
try this:
TideDetailViewController - Displays a single location (detail view) vs a list of multiple locations
#interface TideDetailViewController () {
NSArray *arrTide;
}
#end
#implementation TideDetailViewController
- (void)viewDidAppear:(BOOL)animated {
NSString *locationQueryURL = #"http://api.wunderground.com/api/xxxxx/tide/geolookup/q/43.5263,-70.4975.json";
//fetch the feed
[JSONHTTPClient getJSONFromURLWithString: locationQueryURL
completion:^(NSDictionary *json, JSONModelError *err) {
arrTide = [TideSummaryStats arrayOfModelsFromDictionaries:json[#"tide"][#"tideSummaryStats"] ];
NSLog(#"Tides: %#", arrTide[0]);
}];
}

NSDictionary custom object store and retrieve

Trying to store value in NSDictionary and retrieve it
Objects
#import <Foundation/Foundation.h>
#class ATTTEstOBJ;
#interface ATTTEst : NSObject
#property (nonatomic, retain) NSString *string1;
#property (nonatomic, retain) NSString *string2;
#property (nonatomic, retain) ATTTEstOBJ *obj1;
#end
#interface ATTTEstOBJ : NSObject
#property (nonatomic, retain) NSString *string3;
#property (nonatomic, retain) NSString *string4;
#property (nonatomic, retain) NSString *array1;
#end
I know it needs to be encoded properly to save and retrieve values.but In this case it is a composite object and I have no idea, how to deal it with.
- (void) encodeWithCoder: (NSCoder *)coder
So TLDR , How to save the composite value into dictionary and retrieve it back
I want to store ATTTest into a dictionary and retrieve it back.
EDIT : Detailed explanation
ATTTEst *test=[[ATTTEst alloc]init];
test.string1=#"a";
test.string2=#"b";
ATTTEstOBJ *obj=[[ATTTEstOBJ alloc]init];
obj.string3=#"c";
obj.string4=#"d";
test.obj1=obj;
NSMutableDictionary *dict=[[NSMutableDictionary alloc]initWithCapacity:3];
[dict setObject:test forKey:#"test"];
NSLog(#"%#",dict);
ATTTEst *tester=[dict objectForKey:test];
NSLog(#"%#",tester.obj1.string3);
IT shows null.as output I want to get the value as c for tester.obj1.string3
ATTTEst *tester=[dict objectForKey:test];
should be
ATTTEst *tester=[dict objectForKey:#"test"];
You have used the object test (instead of the string #"test") as key when retrieving the object. I don't think that
was intentionally.
In order to store them into NSDictionary, you don't need to encode them.
Just do:
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:, attestObject,#"attestObject", attest2Object,#"atttest2" nil];
Where attestObject and attest2Object are the objects you want to store, and strings are their keys.
This has nothing to do with encoding...

Initialization of custom object return null [duplicate]

This question already has an answer here:
why is my code outputting *nil description*
(1 answer)
Closed 10 years ago.
Here is my custom class:
ClassA.h
#interface ClassA : NSObject<RKRequestDelegate>{
NSString *uri;
NSString *folderUri;
NSInteger idFolder;
NSString *kind;
bool isMine;
CustomUser *owner;
NSMutableArray *usersAdministrators;
NSMutableArray *usersContributors;
NSMutableArray *usersReaders;
NSString *visibility;
NSString *name;
NSString *description;
NSMutableArray *comments;
}
#property (nonatomic,copy) NSString *uri;
#property (nonatomic,copy) NSString *folderUri;
#property (nonatomic,assign) NSInteger idFolder;
#property (nonatomic,copy) NSString *kind;
#property (nonatomic,assign) bool isMine;
#property (retain) DMIUser *owner;
#property (nonatomic,copy) NSMutableArray *usersAdministrators;
#property (nonatomic,copy) NSMutableArray *usersContributors;
#property (nonatomic,copy) NSMutableArray *usersReaders;
#property (nonatomic,copy) NSString *visibility;
#property (nonatomic,copy) NSString *name;
#property (nonatomic,copy) NSString *description;
#property (nonatomic,copy) NSMutableArray *comments;
#end
ClassA.m
#implementation ClassA
#synthesize uri,folderUri,idFolder,kind,isMine,owner,usersAdministrators,usersContributors,usersReaders,visibility,name,description,comments;
-(NSString*)description {
return #"ClassA";
}
#end
Quite simple. But when i try to create new instance of this, like this:
datas = [NSMutableArray array]; // Tried with [[NSMutableArray alloc] init] => same thing
ClassA *classA = [[ClassA alloc] init];
[datas addObject:classA];
NSLog(#"classA = %#",classA);
NSLog(#"datas = %#",datas);
First NSLog returns "ClassA".
Second NSLog returns "datas = ()"
What's wrong here? I always created class like this and i've never had problem like this.
Thanks!
Ok guyzzz i found the problem. It's my attribute:
NSString *description;
Seems that iOs doesn't love that. It conflict with the -description method in NSObject...
After that, i found a similar question here:
Why can't I use "description" as an attribute name for a Core Data entity?
Cheers
if your want to return some value implement method description in the ClassA
- (NSString *)description {
return #"ClassA";
}
You've got everything you need. Are you sure the variable you're assigning to isn't a weak one? All delegate properties are weak, therefore not retaining the object. My guess is that you're doing something like this
someObject.delegate = [[ClassA alloc] init];
NSLog(#"%#", someObject.delegate);
Because the delegate property is weak it doesn't hold onto the variable.
Edit:
This whole answer assumes you are using ARC. If not, disregard.

Get related / associated entities from NSSet - CoreData

I have 2 autogenerated entities :
#interface ContactEntity : Entity
#property (nonatomic, retain) NSString *caption;
#property (nonatomic, retain) NSString *image;
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSString *text;
#property (nonatomic, retain) NSSet *pointLink;
#end
#interface PointEntity : Entity
#property (nonatomic, retain) NSNumber *latitude;
#property (nonatomic, retain) NSNumber *longitude;
#property (nonatomic, retain) NSSet *entityLink;
#property (nonatomic, retain) EntityEntity *entityTypeLink;
#end
They are linked between each other as ManyToMany, i.e. one contact has many points, one point has many contacts inside.
Then a i get first entity :
ContactModel *contact = [[[ContactModel alloc] init] autorelease];
// this is FetchRequest, returns array of all entities
self.items = [contact list:contact];
// i get only one, all is OK here, this entity has related PointEntity in DB
ContactEntity *contactEntity = [self.items objectAtIndex:self.selection];
And when i try to get related PointEntity using NSSet in selected ContactEntity i always get NULL or empty array. Neither of this works :
NSArray *points = [contactEntity.pointLink allObjects];
PointEntity *pointEntity = [contactEntity.pointLink anyObject];
NSInteger x1 = [points count]; // always 0
id x2 = pointEntity.latitude; // always 0
for (PointEntity *x in contactEntity.pointLink) // isn't enumerated because count = 0
{
id x3 = x.latitude;
}
Any thoughts are appreciated. Did i miss something, maybe i need to use NSPredicate to select entities from PointEntity that are related to ContactEntity?
Thanks.
P.S. My question is similar to this but that suggestion does not work for me, i cannot get loaded associated entities using NSSet of main entity :(
CoreData: many-to-many relationship
Answer is found ... i tried to use property of the autogenerated entities when created new records in CoreData, in the meantime the correct way is to use generated methods like - addPointLinkObject, addEntityLinkObject, etc
Example, i have 3 tables :
Contacts (one person may have many locations)
<< - >>
Points (one location can contain many people)
<< - >
EntityTypes (just a type of a location, in this case type is CONTACT)
One of the entities autogenerated by xCode :
#interface PointEntity : Entity
#property (nonatomic, retain) NSNumber *latitude;
#property (nonatomic, retain) NSNumber *longitude;
#property (nonatomic, retain) NSSet *entityLink; // reference to Contacts table (ManyToMany)
#property (nonatomic, retain) EntityEntity *entityTypeLink; // reference to EntityType table (OneToMany)
#end
#interface PointEntity (CoreDataGeneratedAccessors)
- (void)addEntityLinkObject:(ContactEntity *)value;
- (void)removeEntityLinkObject:(ContactEntity *)value;
- (void)addEntityLink:(NSSet *)values;
- (void)removeEntityLink:(NSSet *)values;
#end
I tried to do the following :
// create 3 new instances - one for each entity
ContactEntity *contactEntity = [model create:model];
PointEntity *pointEntity = [point create:point];
EntityModel *entity = [[[EntityModel alloc] init] autorelease];
entity.name = model.table;
EntityEntity *entityEntity = [[entity list:entity] objectAtIndex:0];
// then i tried to use entity's properties directly to bind entities
// it works, but it works only on DB level when we add new records, but somehow something was missed and thus such selection did not work later - [pointEntity allObjects]
//pointEntity.entityTypeLink = entityEntity; // WRONG !!!
//pointEntity.entityLink = contactEntity.pointLink;
//contactEntity.pointLink = pointEntity.entityLink;
// then i replaced 3 lines above with these ones
[pointEntity addEntityLinkObject:contactEntity]; // CORRECT !!!
[contactEntity addPointLinkObject:pointEntity];
[entityEntity addPointLinkObject:pointEntity];
[context save]; // save changes made with entities in current CoreData context
// now [pointEntity allObjects] and [pointEntity anyObject] work as expected
Useful links -
Coredata and Generated subclass for NSManagedObject with relations
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdAccessorMethods.html#//apple_ref/doc/uid/TP40002154

Resources