2
#import "MPOContactAuthorizationManager.h"

@protocol MPOContactAuthorizationManagerDelegate <NSObject>

- (void)authorizationManger:(MPOContactAuthorizationManager *)manager
      didUpdateContactState:(ContactsState)contactState;

@end

MPOContactAuthorizationManager and ContactState are not resolving to types even though they are declared in MPOContactAuthorizationManager:

#import "MPOContactAuthorizationManagerDelegate.h"

typedef enum _contactsState {
    kContactsStateUnknown,
    kContactsStateAllowed,
    kContactsStateDisallowed
} ContactsState;

@interface MPOContactAuthorizationManager : NSObject <UIAlertViewDelegate> {
    ContactsState _contactsAuthorizationState;;
}

@property (strong, nonatomic) NSObject<MPOContactAuthorizationManagerDelegate> *delegate;
@property (nonatomic) ContactsState contactsAuthorizationState;

Any ideas as to why these are not resolving? Both are getting the error "Expected a type"

Thanks Mike

mverderese
  • 5,314
  • 6
  • 27
  • 36

2 Answers2

3

You have a circular dependency. Update the MPOContactAuthorizationManagerDelegate.h header by getting rid of the #import line and adding the following:

@class MPOContactAuthorizationManager;

just before the @protocol line.

Just put both in one .h file (you still need the forward declaration for MPOContactAuthorizationManager):

typedef enum _contactsState {
    kContactsStateUnknown,
    kContactsStateAllowed,
    kContactsStateDisallowed
} ContactsState;

@class MPOContactAuthorizationManager;

@protocol MPOContactAuthorizationManagerDelegate <NSObject>

- (void)authorizationManger:(MPOContactAuthorizationManager *)manager
      didUpdateContactState:(ContactsState)contactState;

@end

@interface MPOContactAuthorizationManager : NSObject <UIAlertViewDelegate> {
    ContactsState _contactsAuthorizationState;;
}

@property (strong, nonatomic) NSObject<MPOContactAuthorizationManagerDelegate> *delegate;
@property (nonatomic) ContactsState contactsAuthorizationState;
rmaddy
  • 314,917
  • 42
  • 532
  • 579
1

Replace the import of "MPOContactAuthorizationManagerDelegate.h" from MPContactAuthorizationManager.h by using a forward declaration of the protocol:

@protocol MPOContactAuthorizationManagerDelegate;

typedef enum _contactsState {
    kContactsStateUnknown,
    kContactsStateAllowed,
    kContactsStateDisallowed
} ContactsState;

@interface MPOContactAuthorizationManager : NSObject <UIAlertViewDelegate> {
    ContactsState _contactsAuthorizationState;;
}
........

You need to choose this import scheme as you are referring to a user defined type (the ContactsState type) in the protocol's header - so this header needs to import the manager's header. In the manager's header, however, you only refer to the protocol as the types of the method parameters, so you can legally forward-declare here.

In general, you should only import one header from another in a few cases:

  • Declaring a class in your header that's a subclass of a class defined in the other header
  • Referring to user defined types (e.g. via a typedef) in your header that are defined in the other header
  • Declaring a class in your header as conforming to a protocol declared in another header
  • Declaring a category in your header for a class defined in another header
  • I think I'm forgetting one, so saving this space for that one.

Also - read this enlightening answer.

The more common case of needing protocol and class names in public method parameters and properties can be accomplished using forward declarations with @class and @protocol. Although, if it were me, I'd keep the protocol declaration in the same header as the authorization manager - seems more convenient that way. Note that you will need to do a forward-declaration within the file for this. For example:

typedef enum _contactsState {
    kContactsStateUnknown,
    kContactsStateAllowed,
    kContactsStateDisallowed
} ContactsState;

    //forward-declare the protocol before referencing it in the file
@protocol MPOContactAuthorizationManager;

@interface MPOContactAuthorizationManager : NSObject <UIAlertViewDelegate> {
    ContactsState _contactsAuthorizationState;;
}

@property (strong, nonatomic) NSObject<MPOContactAuthorizationManagerDelegate> *delegate;
@property (nonatomic) ContactsState contactsAuthorizationState;

........

@end

    // Provide the real protocol declaration.
@protocol MPOContactAuthorizationManagerDelegate <NSObject>

- (void)authorizationManger:(MPOContactAuthorizationManager *)manager
      didUpdateContactState:(ContactsState)contactState;

@end
Community
  • 1
  • 1
Carl Veazey
  • 18,392
  • 8
  • 66
  • 81
  • I copy-pasted The whole protocol declaration to between `ContactsState` and `@interface MPOContactAuthorizationManager` but now `MPOContactAuthorizationManager` in the protocol declaration won't resolve to at type. `ContactState` int he same declaration does – mverderese Sep 04 '13 at 00:29
  • It's a bit weird, you need to do a forward-declaration within the file. I'll edit my answer to reflect that. – Carl Veazey Sep 04 '13 at 00:31
  • Wow that makes so much sense. The forward declaration is to resolve the property. And then once the Interface has been defined, you use that to resolve the type in the protocol delcaration. Thanks a lot! – mverderese Sep 04 '13 at 00:35