I am having a bit of a problem with importing custom objects into my viewController.
I have created a Message Object that holds the json response from the server. I then created a MessageManager class, that does all of the network calls to the API.
MessageManager imports Message, to create the message object and pass it off to whatever class is using it.
I now have my viewController class, which #import both MessageManager and Message. so I can create an instance variable of Message. However I run into duplicate symbol errors with the compiler.
How do I get around this issue, and have the correct sequence of imports.
If i remove the Message.h from the viewcontroller, and remove any code referencing Message, it compiles normally.
#import <JSONModel/JSONModel.h>
@protocol Messages;
@interface Messages : JSONModel
@property (nonatomic) NSString<Optional>* id;
@property (nonatomic) NSString<Optional>* sender_id;
@property (nonatomic) NSString<Optional>* receiver_id;
@property (nonatomic) NSString<Optional>* user_user_id;
@property (nonatomic) NSString<Optional>* job_id;
@property (nonatomic) NSString<Optional>* file_id;
@property (nonatomic) NSString<Optional>* title;
@property (nonatomic) NSString<Optional>* replied;
@end
@protocol MessagesModel;
@interface MessagesModel : JSONModel
@property (nonatomic) NSString<Optional>* action;
@property (nonatomic) NSDate<Optional>* dateTime;
@property (nonatomic) NSString<Optional>* result;
@property (nonatomic) NSString<Optional>* numItems;
@property (nonatomic) NSArray <Messages> *items;
@end
@implementation MessagesModel
+ (JSONKeyMapper *)keyMapper
{
return [JSONKeyMapper mapperForSnakeCase];
}
@end
#import <UIKit/UIKit.h>
@interface MessagesViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
@property (strong, nonatomic) UISearchController *searchController;
@end
#import "MessagesViewController.h"
#import "MessageTableViewCell.h"
#import "MessageThreadViewController.h"
#import "Messages.h" <--Need Messages Object to use Object and pass object around
#import "MessageManager.h"
@interface MessagesViewController () <UISearchBarDelegate, UISearchResultsUpdating, UIActionSheetDelegate, UISearchControllerDelegate>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (strong, nonatomic) NSArray *inbox;
@property (strong, nonatomic) NSArray *sent;
@property (strong, nonatomic) NSArray *deleted;
@property (strong, nonatomic) NSArray *temp;
@property (assign, nonatomic) NSInteger selectedBox;
@property (assign, nonatomic) NSInteger selectedMessage;
@property (strong, nonatomic) MessageManager *messageManager;
@property (weak, nonatomic) IBOutlet UISearchBar *searchbar;
@property (strong, nonatomic) Messages *messages;
@end
#import <Foundation/Foundation.h>
@interface MessageManager : NSObject
- (void)getReceivedMessagesListForReceiverID:(NSString*)receiverID success:(void (^)(NSArray *success))success failure:(void (^)(NSError *error))failure;
- (void)getSentMessagesListForSenderID:(NSString*)senderID success:(void (^)(NSArray *success))success failure:(void (^)(NSError *error))failure;
- (void)getDeletedMessagesListForMemberID:(NSString*)memberID success:(void (^)(NSArray *success))success failure:(void (^)(NSError *error))failure;
- (void)searchReceivedMessagesListForReceiverID:(NSString*)receuverID andKeyword:(NSString*)keyword success:(void (^)(NSArray *success))success failure:(void (^)(NSError *error))failure;
- (void)searchDeletedMessagesListForMemberID:(NSString*)memberID andKeyword:(NSString*)keyword success:(void (^)(NSArray *success))success failure:(void (^)(NSError *error))failure;
- (void)unreadMessagesCountForReceiverID:(NSString*)receiverID success:(void (^)(NSArray *success))success failure:(void (^)(NSError *error))failure;
- (void)sendMessageToReceiverID:(NSString*)receieverID ToSenderID:(NSString*)senderID withTitle:(NSString*)title andMessage:(NSString*)message success:(void (^)(NSArray *success))success failure:(void (^)(NSError *error))failure;
- (void)markMessageRead:(NSString*)messageID success:(void (^)(NSArray *success))success failure:(void (^)(NSError *error))failure;
- (void)markMessageUnRead:(NSString*)messageID success:(void (^)(NSArray *success))success failure:(void (^)(NSError *error))failure;
- (void)receivedListCountForReceivedID:(NSString*)receivedID success:(void (^)(NSArray *success))success failure:(void (^)(NSError *error))failure;
- (void)deletedMessagesListCountForMemberID:(NSString*)memberID success:(void (^)(NSArray *success))success failure:(void (^)(NSError *error))failure;
- (void)searchReceivedListCountForReceiverID:(NSString*)receiverID andKeyword:(NSString*)keyword success:(void (^)(NSArray *success))success failure:(void (^)(NSError *error))failure;
- (void)searchSentListCountForSender:(NSString*)senderID andKeyword:(NSString*)keyword success:(void (^)(NSArray *success))success failure:(void (^)(NSError *error))failure;
- (void)searchDeletedListCountForMemberID:(NSString*)memberID andKeyword:(NSString*)keyword success:(void (^)(NSArray *success))success failure:(void (^)(NSError *error))failure;
@end
#import "MessageManager.h"
#import "Constants.h"
#import <AFNetworking/AFNetworking.h>
#import "Messages.h" <--Need Messages Object to create Messages from response
@implementation MessageManager
...
duplicate symbol _OBJC_IVAR_$_MessagesModel._result in:
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessagesViewController.o
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessageManager.o
duplicate symbol _OBJC_IVAR_$_MessagesModel._items in:
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessagesViewController.o
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessageManager.o
duplicate symbol _OBJC_IVAR_$_MessagesModel._numItems in:
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessagesViewController.o
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessageManager.o
duplicate symbol _OBJC_CLASS_$_Messages in:
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessagesViewController.o
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessageManager.o
duplicate symbol _OBJC_METACLASS_$_Messages in:
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessagesViewController.o
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessageManager.o
duplicate symbol _OBJC_IVAR_$_Messages._deleted_by_sender in:
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessagesViewController.o
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessageManager.o
duplicate symbol _OBJC_IVAR_$_MessagesModel._action in:
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessagesViewController.o
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessageManager.o
duplicate symbol _OBJC_IVAR_$_Messages._receiver_login in:
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessagesViewController.o
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessageManager.o
duplicate symbol _OBJC_IVAR_$_Messages._sender_login in:
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessagesViewController.o
/Users/anthonytaylor/Library/Developer/Xcode/DerivedData/Build/Intermediates/Voices.com.build/Debug-iphonesimulator/Voices.com.build/Objects-normal/x86_64/MessageManager.o
...
Based on the files you've mentioned in the question, you only have the Messages.h
file in your project and do not have the Messages.m
file, instead have the implementation declared in the header file, am I right? I was able to replicate your duplicate symbols error on the example project I found here by copying the classes from your question. But when I created a Messages.m file with the implementation of both Messages
and MessageManager
classes, the duplicate symbols compiler error disappeared, and I was able to create an instance of the MessageManager
class.
With that said, I'm not sure what you mean by
The JSONModel tutorials all show doing the @implementation in the header, and not needing the .m files at all.
comment, but according to JSONModel's Github readme page, they say:
There's no need to do anything in the implementation (.m) file.
This probably doesn't mean that you don't need to have the .m file. Its a good practice anyway to have both .h and .m files for a class since the Compile Sources
option under the Build Phases
tab of your Xcode project's target only has the .m files files. This is what tells the compiler which source files should be compiled while building a target. Since you declared the implementation inside the .h file, the compiler can't find it at build time.
Here's a screenshot of the example Xcode project I setup:
MessageManager.h file
#import <Foundation/Foundation.h>
@class MessagesModel;
@interface MessageManager : NSObject
+ (MessagesModel *)getMessages;
@end
MessageManager.m file:
#import "MessageManager.h"
#import "Messages.h" //<-- Imported here
@implementation MessageManager
+ (MessagesModel *)getMessages {
NSError *error = nil;
NSDictionary *dictionary = @{@"action": @"replied",
@"dateTime": @"",
@"result": @"success",
@"numItems": @"1",
@"items": @[@{@"id": @"1",
@"sender_id": @"2",
@"receiver_id": @"3",
@"user_user_id": @"4",
@"job_id": @"5",
@"file_id": @"6",
@"title": @"Hello world",
@"replied" : @"7"}]};
MessagesModel *messages = [[MessagesModel alloc] initWithDictionary:dictionary error:&error];
if (error)
NSLog(@"Oops!");
return messages;
}
@end
Messages.h file:
#import <JSONModel/JSONModel.h>
@protocol Messages;
@interface Messages : JSONModel
@property (nonatomic) NSString<Optional>* id;
@property (nonatomic) NSString<Optional>* sender_id;
@property (nonatomic) NSString<Optional>* receiver_id;
@property (nonatomic) NSString<Optional>* user_user_id;
@property (nonatomic) NSString<Optional>* job_id;
@property (nonatomic) NSString<Optional>* file_id;
@property (nonatomic) NSString<Optional>* title;
@property (nonatomic) NSString<Optional>* replied;
@end
@protocol MessagesModel;
@interface MessagesModel : JSONModel
@property (nonatomic) NSString<Optional>* action;
@property (nonatomic) NSDate<Optional>* dateTime;
@property (nonatomic) NSString<Optional>* result;
@property (nonatomic) NSString<Optional>* numItems;
@property (nonatomic, strong) NSArray <Messages> *items;
@end
Messages.m file:
#import "Messages.h"
@implementation Messages
@end
@implementation MessagesModel
+ (JSONKeyMapper *)keyMapper {
return [JSONKeyMapper mapperForSnakeCase];
}
@end
ViewController.m file:
#import "ViewController.h"
#import "MessageManager.h"
#import "Messages.h" //<-- Imported here
@interface ViewController ()
@property (strong, nonatomic) MessagesModel *messagesModel;
@property (weak, nonatomic) NSArray<Messages *> *messages;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.messagesModel = [MessageManager getMessages];
self.messages = self.messagesModel.items;
NSLog(@"%@", self.messages);
}
@end
Let me know if you want me to upload the Xcode project in case you want to examine the setup.
Hope this helps.