Xcode Don't recognize Object anymore - ios

I have an object named friend (I know, first letter should be uppercase). I use this class in many other classes and view controller.
All of a sudden, without changing ANY CODE, every custom object I have, stopped recognize each other. I always get the error Unknown type name "friend".
I already tried to clear the project and restart the mac.
WTF is wrong with this Xcode? All of a sudden my whole project stops working.
Here is my class currentUser.h
#import <Foundation/Foundation.h>
#import "friend.h"
#interface currentUser : NSObject<NSCoding>
{
BOOL fromfacebook;
#private
NSMutableArray *upLoadStack;
}
#property (nonatomic,strong)NSString *token;
#property (nonatomic,strong)NSString *email;
#property (nonatomic,strong)NSString *name;
#property (nonatomic,strong)UIImage *userImg;
#property (nonatomic,strong)NSString *username;
#property (nonatomic,strong)NSString *facebookID;
#property (nonatomic,strong)NSString *userPSW;
#property (nonatomic,strong)NSString *userID;
#property (nonatomic,strong)NSMutableArray *friendsList;
#property (nonatomic,strong)NSMutableArray *groups;
#property (nonatomic,strong)NSData *audioMessage;
#property (nonatomic,strong)NSMutableArray *mimosToDownload;
#property (nonatomic,strong)NSMutableArray *mimosDownloaded;
#property (nonatomic,strong)friend *friendToSend; //Here is where a I get the error of unknown type name
#end
this is the friend.h
#import <Foundation/Foundation.h>
#import "currentUser.h"
#import "Imager.h"
#interface friend : NSObject<NSCoding>
#property (nonatomic,strong)NSString *username;
#property (nonatomic,strong)NSString *userID;
#property (nonatomic,strong)UIImage *userImg;
#property(nonatomic,strong)NSMutableData *buffer;
#property(nonatomic)BOOL flagDownloaded;
-(UIImage*)downloadImageBlocked;
-(id)init;
-(UIImage*)getFriendImg;
-(UIImage*)userImg;
-(NSString*)getUserID;
-(NSString*)getUserName;
- (void)encodeWithCoder:(NSCoder *)encoder;
-(bool)isNil;
#end

fix the stuff that you know is wrong first...
change
#interface currentUser : NSObject<NSCoding>
{
BOOL fromfacebook;
#private
NSMutableArray *upLoadStack;
}
to
#interface User : NSObject<NSCoding>
{
BOOL fromfacebook;
#private
NSMutableArray *upLoadStack;
}
you don't need to know if the user is current or not for the user to have properties of a user, think of them as actually representing objects.
change:
#interface friend : NSObject<NSCoding>
to
#interface Friend : NSObject<NSCoding>
you know it is wrong, fix it now before you have to fix it in 1000 places instead of 100 places.
Convention is very important in Objective-C.
also don't import everything into your header if you don't need to...
#class Friend; //forward class declaration
#interface currentUser : NSObject<NSCoding>
...
#property (nonatomic,strong)Friend *friendToSend; //Here is where a I get the error of unknown type name
and as for your ivar's in currentUser you don't need those in the interface (they can go in a block after the #implimentation line), unless you need them for backwards compatibility...

Related

Xcode: declaring private #property it complain (Objective-C)

I'm trying to declare a private property but I'm getting this error:
Unexpected '#' in program
Here is my implementation
#implementation MyClassImplementation
#property (nonatomic,strong) NSArray *new;
#end
Here is where I get the error #property (nonatomic,strong) NSArray *new; any of you knows why I'm getting this error or if there is a work around this?
I'll really appreciate your help
Private properties usually are declared in .m file in class unnamed category and for following Cocoa naming convention shouldn't use new keyword:
#interface MyClassImplementation ()
#property (nonatomic, strong) NSArray *array;
#end
#implementation MyClassImplementation
....
#end

Best practices for JSONModel and polymorphism

How do you deal with subclassing collection attributes in JSONModel?
Let's say I have these two endpoints with different responses of the same "product object".
domain.com/api/1.0/getProductList
domain.com/api/1.0/getProductDetails/productId
I wrote some example code below to show you my issue:
// ProductListModel
#interface ProductListModel : JSONModel
#property (nonatomic, strong) NSNumber *productId;
#property (nonatomic, strong) NSNumber *userId;
#property (nonatomic, strong) NSArray<OrderListModel> *orders;
#end
// ProductDetailModel
#interface ProductDetailModel : ProductListModel
#property (nonatomic, strong) NSURL *productImageUrl;
#property (nonatomic, strong) NSArray<OrderDetailModel> *orders;
#end
// OrderListModel
#protocol OrderListModel <NSObject>
#end
#interface OrderListModel : JSONModel
#property (nonatomic, strong) NSNumber *orderId;
#property (nonatomic, strong) NSNumber *price;
#end
// OrderDetailModel
#protocol OrderDetailModel <NSObject>
#end
#interface OrderDetailModel : OrderListModel
#property (nonatomic, strong) NSURL *orderImageUrl;
#end
The ProductDetailModel wants the same inherited attributes as ProductListModel, but it wants the orders array in the subclassed type.
However this leads to a compiler warning:
Property type 'NSArray<OrderDetailModel> *' is incompatible with type
'NSArray<OrderListModel> *' inherited from 'ProductListModel'
I found this related SO post but I'd rather not monkey patch the JSONModel library.
Edit #1:
This has been discussed in the #574, and #229 github issues before but requires a "type" string to determine what class to instantiate. This requires a change on the backend API.
Is there a way to do this without changing the backend API?
You can't override the property in the subclass to have a different type as it will violate the Liskov substitution principle - #Paulw11
For future readers, here's how the updated example code would look like:
// ProductBaseModel
#interface ProductBaseModel : JSONModel
#property (nonatomic, strong) NSNumber *productId;
#property (nonatomic, strong) NSNumber *userId;
#end
// ProductListModel
#interface ProductListModel : ProductBaseModel
#property (nonatomic, strong) NSArray<OrderListModel> *orders;
#end
// ProductDetailModel
#interface ProductDetailModel : ProductBaseModel
#property (nonatomic, strong) NSURL *productImageUrl;
#property (nonatomic, strong) NSArray<OrderDetailModel> *orders;
#end
// OrderListModel
#protocol OrderListModel <NSObject>
#end
#interface OrderListModel : JSONModel
#property (nonatomic, strong) NSNumber *orderId;
#property (nonatomic, strong) NSNumber *price;
#end
// OrderDetailModel
#protocol OrderDetailModel <NSObject>
#end
#interface OrderDetailModel : OrderListModel
#property (nonatomic, strong) NSURL *orderImageUrl;
#end

What will happen if my class conforms to two protocols having same property?

Let's say I have two protocols
#protocol Playlist<NSObject>
#property(nonatomic, copy) NSString *title;
#property(nonatomic, assign) NSUInteger trackCount;
#end
and another as
#protocol Album<NSObject>
#property(nonatomic, copy) NSString *name;
#property(nonatomic, assign) NSUInteger trackCount;
#end
and there is a class which conforms to these protocols
.h file
#interface MusicLibrary <Playlist, Album>
#end
.m file
#implementation MusicLibrary
#synthesize title;
#synthesize name;
#synthesize trackCount;
#end
Which trackCount property will it refer to? Can I use trackCount twice?
It surely do not give any compile time error.
It looks to me that you are modeling your data wrong. The way you have it setup a musicLibrary is BOTH a playlist and an album. I think a more correct model would have a MusicLibrary containing many playlist and many albums. Something like:
#property (nonatomic, strong) NSArray<Album>* albums;
#property (nonatomic, strong) NSArray<Playlist>* playlists;

Objective C - Avoid Import Loop

I want to connect two classes of mine and link each other with a property of each class. I broke down the main aspects to this example:
Ocean.h file:
#import <Foundation/Foundation.h>
#import "Fish.h"
#interface Ocean : NSObject
#property (nonatomic) NSArray *listOfFishesInOcean;
#end
Fish.h file:
#import <Foundation/Foundation.h>
#import "Ocean.h"
#interface Fish : NSObject
#property (nonatomic) Ocean *homeOcean; // Compiler: "Unknown type name Ocean"
#property (nonatomic) int age;
#end
What I wanna do in the end, is to manipulate the age property of an Fish object and be able to save it (listOfFishesInOcean, NSUserDefaults), as well as call a function in the Ocean object, when saving is completed. This way I'd always have the latest list of Fish-objects in my list of the Ocean-object.
My two problems here are:
How to avoid the import-loop, which causes the complier error, I think?
How should I implement the save & action workflow in the end?
I thought about solving this issue with notifications and observer but this way I'd still need to filter the notifications in any way, due to the fact that I've multiple Oceans with more Fishes.
Another idea to solve it, would be to give each Ocean object and Fish object an ID, which I would use as a key in NSUserDefaults again.
If anyone has some thoughts about it or other ideas, you are very welcome!
Import ".h" files only in ".m" file, like:
Ocean.h file:
#import <Foundation/Foundation.h>
#class Fish;
#interface Ocean : NSObject
#property (nonatomic) NSArray *listOfFishesInOcean;
#end
Ocean.m file:
#import "Ocean.h"
#import "Fish.h"
#implementation Ocean
#end
Fish.h file:
#import <Foundation/Foundation.h>
#class Ocean;
#interface Fish : NSObject
#property (nonatomic) Ocean *homeOcean;
#property (nonatomic) int age;
#end
Fish.m file:
#import "Fish.h"
#import "Ocean.h"
#implementation Fish
#end
I think one of the best approaches could be using the identifiers so you improve the performance.
#interface Ocean : NSObject
#property (nonatomic) int identifier;
#property (nonatomic) NSArray *listOfFishesInOcean;
#end
#interface Fish : NSObject
#property (nonatomic) int age;
#property (nonatomic) int parent_identifier;
#end
if you want to keep your approach:
#import <Foundation/Foundation.h>
#class Ocean;
#interface Fish : NSObject
#property (nonatomic) Ocean *homeOcean; // Compiler: "Unknown type name Ocean"
#property (nonatomic) int age;
#end
Fish.m
#import "Ocean.h"

Access private interface property by public method

I would like to ask you some opinion about what I'm doing. I know it works, but I'm not sure is proper to do what I'm doing.
I have a superclass Building that need to expose two NSString, name and description. No one should be able to modify those variables apart their subclasses.
To get this result I have created two public method on the base class:
#interface Building : NSObject
- (NSString *)name;
- (NSString *)description;
#end
Then on each subclass I'm creating a private interface with name and description properties and let the magic happen.
#interface Barrack()
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *description;
#end
#implementation Barrack
#synthesize name, description;
...
#end
What you guys think about this?Is this a proper way to get this kind of result, anyone have better ideas about this topic?
Thanks for your opinion.
Best,
Enrico
Declare readonly properties in the interface, readwrite in the implementation class extension. No need for #synthesize. This is one of the main reason class extensions were added to Objective-C.
in Building.h
#interface Building : NSObject
#property (nonatomic, strong, readonly) NSString *name;
#property (nonatomic, strong, readonly) NSString *description;
#end
In Barrack.m
#interface Barrack ()
#property (nonatomic, strong, readwrite) NSString *name;
#property (nonatomic, strong, readwrite) NSString *description;
#end
#implementation Barrack
...
#end

Resources