Expected specifier-qualifier-list before '*' token Objective C - objective-c

Would anyone be kind enough to explain to me what I'm doing wrong. I'm giving it :
#import <Foundation/Foundation.h>
#interface Product : NSObject {
NSString *imageAddress;
NSString *name;
NSString *title;
}
#property (nonatomic, retain) *imageAddress;
#property (nonatomic, retain) *name;
#property (nonatomic, retain) *product;
#end
and its giving me:
Expected specifier-qualifier-list
before '*' token
for the property calls.
Thanks

This is gcc's cryptic way of telling you that you need a type for your properties.
#property (nonatomic, retain) NSString *imageAddress;
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSString *product;

Related

Property requires method to be defined in NSManagedObject subclass

I have some protocol like this:
#protocol UserProtocol <NSObject>
#property (nonatomic, strong) NSNumber *uid;
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSNumber *rating;
#end
Then I created some actual class that implements that:
#interface User : NSObject <UserProtocol>
#end
Now I need another implementation that uses CoreData so I created CDUser entity (Xcode also generates category for that):
// CDUser.h
#interface CDUser : NSManagedObject <UserProtocol>
#end
// CDUser+CoreDataProperties.h
#interface CDUser (CoreDataProperties)
#property (nullable, nonatomic, retain) NSNumber *uid;
#property (nullable, nonatomic, retain) NSString *name;
#property (nullable, nonatomic, retain) NSNumber *rating;
#end
// CDUser+CoreDataProperties.m
#implementation CDUser (CoreDataProperties)
#dynamic uid;
#dynamic name;
#dynamic rating;
#end
CDUser actually implements UserProtocol but I have warnings like so for all properties:
Property 'uid' requires method 'uid' to be defined - use #synthesize, #dynamic or provide a method implementation in this class implementation
If I add #dynamic uid; again in CDBook.m then I get the following error:
Property declared in category 'CoreDataProperties' cannot be implemented in class implementation
How can I solve these warnings in a proper way?
Cause CDUser doesn't implement this protocol. Use protocol on category instead.
#interface CDUser : NSManagedObject
#end
// CDUser+CoreDataProperties.h
#interface CDUser (CoreDataProperties) <UserProtocol>
#property (nullable, nonatomic, retain) NSNumber *uid;
#property (nullable, nonatomic, retain) NSString *name;
#property (nullable, nonatomic, retain) NSNumber *rating;
#end

CoreData How to connect with relationship entity to another entity with already preloaded data?

This is my first application in CoreData so I definitely missing something here, but I spend over a week trying to find solution and apparently nobody on Internet had the same problem ;)
I'm creating something like deckbuilder app.:
My model looks like this: coredatamodel
The relationship is to-one and inverse to-many ( every card can be in one set, and in every set can be many cards) from CARD to SET.
For sake of simplicity I want to focus on CARD and SET entities.
I preloaded data into SET from CSV file into 5 atributes - didnt fill relationship "karty" because I didn't know how to do this. There are about 25 records in this entity.
And now, problem is I am trying to fill CARDS Entity which will have over 500 records.
Trying few options I found on SO I end with connection that created 500 records in SET too:/ so it looked like sql "JOIN" command.
What I want is load data to CARDS and connect them somehow to SET not changing number of records in SET.
If i have property (nonatomic, retain) NSSet *karty; what exactly NSSet means? It is s et but set of what? Set of single rows from Card entity? Set of Card objects? Set of NSStrings? Set of NSManagedObjects?
In normal SQL primary key to connect them would be "nazwaszort" so Card.nazwaszort=Set.nazwaszort.
My Set.h
#class Card;
#interface Set : NSManagedObject
#property (nonatomic, retain) NSNumber * cykl;
#property (nonatomic, retain) NSNumber * czymajor;
#property (nonatomic, retain) NSString * nazwa;
#property (nonatomic, retain) NSString * nazwashort;
#property (nonatomic, retain) NSNumber * nrwcyklu;
#property (nonatomic, retain) NSSet *karty;
#end
#interface Set (CoreDataGeneratedAccessors)
- (void)addKartyObject:(Card *)value;
- (void)removeKartyObject:(Card *)value;
- (void)addKarty:(NSSet *)values;
- (void)removeKarty:(NSSet *)values;
#end
My Card.h
#class Frakcja, Kolekcja, Set;
#interface Card : NSManagedObject
#property (nonatomic, retain) NSNumber * czylimit;
#property (nonatomic, retain) NSString * frakcja;
#property (nonatomic, retain) NSString * icesila;
#property (nonatomic, retain) NSNumber * iloscwsecie;
#property (nonatomic, retain) NSNumber * influence;
#property (nonatomic, retain) NSString * kodkarty;
#property (nonatomic, retain) NSNumber * koszt;
#property (nonatomic, retain) NSNumber * minimumdecksize;
#property (nonatomic, retain) NSString * nazwa;
#property (nonatomic, retain) NSString * nazwasetu;
#property (nonatomic, retain) NSString * nazwaszort;
#property (nonatomic, retain) NSNumber * nrcyklu;
#property (nonatomic, retain) NSString * podtyp;
#property (nonatomic, retain) NSString * strona;
#property (nonatomic, retain) NSNumber * trashkoszt;
#property (nonatomic, retain) NSString * typ;
#property (nonatomic, retain) Kolekcja *ilewkolekcja;
#property (nonatomic, retain) Frakcja *nazwafrakcji;
#property (nonatomic, retain) Set *wjakimsecie;
#end
I preloaded cards to SET using method
-(void) preloadDataPackInfoToDatabase {
NSError *error=nil;
NSString *sciezka = [[NSBundle mainBundle]pathForResource:#"nrsets" ofType:#"csv"];
NSArray *rows = [NSArray arrayWithContentsOfCSVFile:sciezka];
for (int i=1; i <=([rows count]-1); i++) {
Set *nowyDataPack = [NSEntityDescription insertNewObjectForEntityForName:[entityset name] inManagedObjectContext:_contextdp];
NSLog(#"tablica wierszy %#",rows[i][2]);
NSString *koddodatku = rows[i][2];
NSLog(#"kod dodatku:%#",koddodatku);
NSString *nrwcyklu = rows[i][4];
NSString *nrcyklu = rows[i][3];
NSString *nazwadatapack =rows[i][3];
NSString *czymajor =rows[i][0];
[nowyDataPack setValue:nazwadatapack forKey:#"nazwa"];
NSNumberFormatter *f = [[NSNumberFormatter alloc]init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *nrwcykluint = [f numberFromString:nrwcyklu];
NSNumber *nrcykluint = [f numberFromString:nrcyklu];
NSNumber *czymajorbool = [f numberFromString:czymajor];
[nowyDataPack setValue:nrwcykluint forKey:#"nrwcyklu"];
[nowyDataPack setValue:nrcykluint forKey:#"cykl"];
[nowyDataPack setValue:koddodatku forKey:#"nazwashort"];
[nowyDataPack setValue:czymajorbool forKey:#"czymajor"];
}
if (![ self.contextdp save:&error]) {
NSLog(#"Nieznany błąd %#,%#",error,[error userInfo]);
}
}
And another method (on pastebin to not flood your screens --> preloadAllCardsToDatabase
Thanks in advance for any help.
OK I finally did it. Had to move some CoreData stuff outside loop.
Still dont understand this whole magic but at least it works.
for those interested this is my preloading function --> here

Unrecognized selector sent to instance: key-value pair

I get
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryM metadata]: unrecognized selector sent to instance 0xd0b6250'
when i reach and execute this part of my code:
IDTherapyMetadata* meta = [self.dataCon getMetaDataFromId:content.metadata];
the method in dataCon looks like this:
-(IDTherapyMetadata*)getMetaDataFromId:(NSString*)metaDataId
{
for (IDTherapyMetadata* metadata in self.parser.metadata)
{
if([metaDataId compare:metadata.objId] == NSOrderedSame)
{
return metadata;
}
}
return nil;
}
The strange thing is, if I write
IDTherapyMetadata* meta = [self.dataCon getMetaDataFromId:[content valueForKey:#"metadata"]];
instead it works just fine.
However I want to be able to use dotnotation and looking through apple's documentation
https://developer.apple.com/library/ios/documentation/cocoa/conceptual/KeyValueCoding/Articles/BasicPrinciples.html
haven't helped me.
Why i'm I getting this behaviour and how do I fix it?
Any help is greatly appreciated
EDIT:
The code for IDTherapyContents.h:
#import <Foundation/Foundation.h>
#interface IDTherapyContents : NSObject
#property (nonatomic, copy)NSString* urlId;
#property (nonatomic, copy)NSString* url;
#property (nonatomic, copy)NSString* type;
#property (nonatomic, copy)NSString* timestamp;
#property (nonatomic, copy)NSString* metadata;
#property (nonatomic, copy)NSString* lang;
#property (nonatomic, copy)NSString* objId;
//methods
-(id)initWithJsonDic:(NSDictionary*)jsonDic;
#end
Code for IDTherpayMetaData.h
#import <Foundation/Foundation.h>
#import "IDTherapyImages.h"
#interface IDTherapyMetadata : NSObject
//Array contains 'String' objects
#property (nonatomic, strong)NSMutableArray* thumbnails;
#property (nonatomic, copy)NSString* title;
#property (nonatomic, copy)NSString* timestamp;
#property (nonatomic, copy)NSString* subCategory;
#property (nonatomic, copy)NSString* lang;
#property (nonatomic, copy)NSString* objId;
#property (nonatomic, copy)NSString* description5;
#property (nonatomic, copy)NSString* description4;
#property (nonatomic, copy)NSString* description3;
#property (nonatomic, copy)NSString* description2;
#property (nonatomic, copy)NSString* description1;
#property (nonatomic, copy)NSString* category;
//Array contains 'IDTherapyImages' objects
#property (nonatomic, strong)NSMutableArray* images;
//methods
-(id)initWithJsonDic:(NSDictionary*)jsonDic;
#end
Code for IDTherapyProducts.h:
#interface IDTherapyProducts : NSObject
//Array contains 'String' objects
#property (nonatomic, strong)NSMutableArray* contents;
#property (nonatomic, copy)NSString* uniqueId;
#property (nonatomic, copy)NSString* timestamp;
#property (nonatomic, copy)NSString* price;
#property (nonatomic, copy)NSString* posted;
#property (nonatomic, copy)NSString* normalPrice;
#property (nonatomic, copy)NSString* metadata;
#property (nonatomic, copy)NSString* lang;
#property (nonatomic, copy)NSString* objId;
#property (nonatomic, copy)NSString* badge;
//methods
-(id)initWithJsonDic:(NSDictionary*)jsonDic;
#end
This is a simple case of confusing properties with KVC. They are different things.
content.metadata is nothing more than syntactic sugar for [content metadata]. So you need a method on content called -metadata and as content is an NSDictionary that method doesn't exist. So that's why the exception is thrown.
On any normal object [content valueForKey: #"metadata"] would also throw an exception because KVC looks for a method with that name. However, on NSDictionary -valueForKey: is overridden to call -objectForKey: unless the key starts with an # in which case the # is stripped and [super valueForKey: ...] is invoked.
However I want to be able to use dotnotation
Then you need a method on NSDictionary called -metadata. You could use a category.
#interface NSDictionary(MyMetadataExtension)
-(id) metadata;
#end
#implementation NSDictionary(MyMetadataExtension)
-(id) metadata
{
return [self objectForKey: #"metadata"];
}
#end

cannot give strong or retain property to protocol object

I've the following line of code
#property (nonatomic, retain) id<MessageItemProtocol> *message;
Here, i am getting an error : "property with 'retain' (or strong) attribute must be of object type "
I know that i am getting an error because it's a protocol. so, then what should be it's property type then ??
Try
#property (nonatomic, retain) id<MessageItemProtocol> message;
or
#property (nonatomic, retain) NSObject<MessageItemProtocol> *message;
id already is a pointer, so you do not need *.
#property (nonatomic, retain) id<MessageItemProtocol> message;

To Many Relationship in Core Data

This is my GeneratedCode for Core data, automatically generated by xCode Editor.
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#class Building, Category, City, District, Image, LatitudeLongitude, OpeningHour, Promotion, Rating, Review, URL;
#interface Business : NSManagedObject {
#private
}
#property (nonatomic, retain) NSString * Website;
#property (nonatomic, retain) NSString * Email;
#property (nonatomic, retain) NSString * Street;
#property (nonatomic, retain) NSString * InBuildingAddress;
#property (nonatomic, retain) NSString * Phone;
#property (nonatomic, retain) NSString * Title;
#property (nonatomic, retain) NSString * Zip;
#property (nonatomic, retain) NSNumber * Price;
#property (nonatomic, retain) NSSet* Promotions;
#property (nonatomic, retain) Building * Building;
#property (nonatomic, retain) NSSet* Categories;
#property (nonatomic, retain) LatitudeLongitude * LatitudeLongitude;
#property (nonatomic, retain) NSSet* Images;
#property (nonatomic, retain) OpeningHour * OpeningHour;
#property (nonatomic, retain) NSSet* Reviews;
#property (nonatomic, retain) NSSet* URLs;
#property (nonatomic, retain) Rating * Rating;
#property (nonatomic, retain) NSSet* Districts;
#property (nonatomic, retain) City * City;
//I added these 3 lines, why not part of automatically generated Code?
- (void)addDistrictsObject:(District *)value;
- (void)addCategoriesObject:(Category *)value;
- (void)addReviewsObject:(Review *)value;
#end
Say I want to "clear" all Reviews and image.
Will doing self.Reviews=nil do the trick?
I know that doing self.LatitudeLongitude=nil will delete the relationship between self and it's LatitutudeLongitude.
EDIT - Not sure if you mean "clear" as in delete. My answer below is assuming that you want the objects gone from the context; not just severing the relationship between the NSManagedObjects
I don't believe
self.Reviews = nil;
will actually delete your Review objects for the Managed Object Context. That would send the release message to each one, but to delete them from the context you have to call
[aContext deleteObject:reviewObj];
on each one in the set. If you were to delete one of your Business objects (using "deleteObject" as shown above) and you had your relationship delete rules set to "Cascade", then I believe that would cause all of the Review, City, etc... objects owned by that Business object to be deleted automatically, but that is the only other way that I know of that will cause NSManagedObjects to be deleted.