iOS 8 Expected a type - objective-c

I have the UIScrollViewSlidingPages and the SSPullToRefresh libraries in a lot of projects, but suddenly, I'm getting this weird errors in this new iOS 8 project.
#import <Foundation/Foundation.h>
#interface TTSlidingPageTitle : NSObject
-(id)initWithHeaderText:(NSString*)headerText;
-(id)initWithHeaderImage:(UIImage*)headerImage;
//The title text to go in the nav bar
#property(strong, nonatomic) NSString *headerText;
//An image to use in the nav bar (if you set this, the title text will not be used)
#property(strong, nonatomic) UIImage *headerImage;
#end
This line is getting the "Expected a Type" error:
-(id)initWithHeaderImage:(UIImage*)headerImage;
And this line is getting the "Unknown type name UIImage" error:
#property(strong, nonatomic) UIImage *headerImage;

If you check the docs for UIImage you'll see it's in UIKit, not Foundation. The docs are now all targeted at Swift, which is somewhat annoying, but you'll see the import statement in the docs is specified as
#import UIKit;
which you need at the top of your file (no need for the Foundation import either).
Sometimes projects include this import statement in a precompiled header file (pch). This should be referenced in Build Settings->Prefix Header, or it won't be used in compilation.

Related

Objective-C header file not recognizing custom object as a type

I'm working on a game for iPad using cocos2d which involves a board filled with different types of tiles. I've created a custom class called Tile as a general template for tiles and a few subclasses of Tile which have different properties and methods. I've also created a class called Board which, among other things, keeps track of the locations of all the tiles using a special coordinate system.
For some reason, in the Board class, the compiler doesn't seem to be recognizing Tile as a type of object, even though I've added #import "Tile.h" at the top of the file.
Here's the relevant code (just ask if there's other parts of the code you want to see):
Tile.h
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "Board.h"
#interface Tile : NSObject
-(void) updateNeighbors;
#property (nonatomic, retain) CCSprite* sprite;
#property (assign) CGPoint coords;
#property (assign) CGPoint positionInPoints;
#property (nonatomic, retain) NSMutableArray *neighbors;
#end
Board.h
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "Tile.h"
#interface Board : NSObject
+(Board*)sharedBoard;
- (void) putTile: (Tile*) tile AtIndex: (CGPoint) index; //<-- error here!
- (void) replaceTileAtIndex: (CGPoint) index1 WithTileAtIndex: (CGPoint) index2;
- (Tile*) tileAtIndex: (CGPoint) index; //<-- error here!
- (void) populate;
#property (nonatomic, retain) NSMutableArray *tiles;
#property (nonatomic, retain) NSString *type;
#property (assign) CGPoint size;
#end
This code will not even build and I'm getting the following error where indicated:
Expected '(' before 'Tile'
If I change the type from (Tile*) to (NSObject*), it fixes the error, which leads me to believe that Tile is not being recognized as a type of object.
I've searched via Google and this site and cannot figure out why this is happening.
Update
Dumb mistake; easy to fix.
As you all have pointed out the problem is that the two header files are importing each other, which is not allowed. For now, I've fixed the problem by moving the #import "Board.h" statement to Tile.m, since it isn't needed in the header file. Later on, if I decide to use Board in the Tile.h file I will use forward referencing (#class Board;), as a few of you suggested.
Thanks again!
This is a classic problem with headers importing headers. You have a circle here: Tile.h is importing Board.h, which imports Tile.h. This confuses the compiler -- it gets stuck in a loop.
You solve this by not importing headers into headers. You still need to let the compiler know about Tile, however. In Board.h, make a "forward declaration" of the class:
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#class Tile; // Dear compiler,
// Tile is a class that I will need to refer
// to in this file. Please consider it to be a
// type; I promise it'll be defined at runtime.
// Sincerely, stephenalexbrowne
#interface Board : NSObject
//etc.
This assures the compiler that there is a class called Tile that will exist at runtime; you can then refer to that name in the remainder of your header. In your implementation for Board, you import Tile.h. That will let the compiler see the methods and properties associated with the Tile class where they are needed.
Likewise, move the #import "Board.h" into Tile.m. Since you aren't referring to the Board class in Tile.h, you don't need to make a forward declaration.
In general, it is best to import your class headers only into the implementation files where they are needed. Framework headers, since they will never cause a cycle with your code, can and -- because you need to refer to many of the classes declared in them -- should be imported into your headers.
Two files cannot import each other. You need to move the import directives to the implementation files, and instead just forward-declare the classes in the headers (e.g. #class Tile; in Board.h).
The reason circular imports don't work is because #import literally includes the text from the imported file in-place. But it also ensures that the text from a file will only be included once, in order to avoid duplicate declarations. So when Tile.h says that the text from Board.h needs to go before it, and Board.h says the text from Tile.h needs to go before it, there's literally nothing the compiler can do — one of them needs to go first, and that file is going to complain because it was expecting the other one to already be there.
This may not be the problem, but what happens if you remove the "#import "Board.h"" from the Tile.h file. You might have a problem with circular referencing

Expected specifier-qualifier-list before error

#import <UIKit/UIKit.h>
#import "NotepadViewController.h"
#import "NotesTableViewController.h"
#import "NoteInformationTransferProtocol.h"
#interface NotesViewController : UIViewController <NoteInformationTransferProtocol>
{
UITextField *_noteTitleTextField;
UIButton *_addButton;
UITextField *_description;
UIView *_notesTableView;
NotepadViewController * _notepadVC;
NotesTableViewController *_noteTableVC;
}
I am getting the error "Expected specifier-qualifier-list before NotepadViewController" on "NotepadViewController * _notepadVC;" I already imported that class' header so it should detect it as a type, right?
That error normally occurs when you haven't added a framework or file to your target, is "NotepadViewController.h" in the target you are building?
In xCode 4 you can check this by expanding the "Compile Sources" section in Build Phases.
In xCode 3 you can use "Get info" to see what targets that file is included (if my memory serves me true)

How does it compile? How can the compiler find the declaration of NSFetchedResultsController, when there is no obvious import statemetn?

I make my first steps in objective-c and cocoa. I typed in the following example class, which compiles well in the iPhone main project. When I use the sample class in an OCUnitTest, the compiler raise an error.
class:
#import <UIKit/UIKit.h>
#interface ProjekteTableViewController : UITableViewController {
NSFetchedResultsController *fetchedResultsController;
}
#property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
#end
Now the question: I see in UIKit.h no direct or indirect #import for the NSFetchedResultsController.h file.
How does the compiler resolve this identifier (NSFetchedResultsController) ?
I expected the compiler error not only in the UnitTest project, but also in the main project.
I suspect you've got a prefix header that's including CoreData.

Error: expected specifier-qualifier-list before 'QTVisualContextRef'

I am currently getting this error message in my header code, and I'm not sure as to why:
"Error: expected specifier-qualifier-list before 'QTVisualContextRef'"
#import <Cocoa/Cocoa.h>
#import <QTKit/QTKit.h>
#import <OpenGL/OpenGL.h>
#import <QuartzCore/QuartzCore.h>
#import <CoreVideo/CoreVideo.h>
#interface MyRecorderController : NSObject {
IBOutlet QTCaptureView *mCaptureView;
IBOutlet NSPopUpButton *videoDevicePopUp;
NSMutableDictionary *namesToDevicesDictionary;
NSString *defaultDeviceMenuTitle;
CVImageBufferRef mCurrentImageBuffer;
QTCaptureDecompressedVideoOutput *mCaptureDecompressedVideoOutput;
QTVisualContextRef qtVisualContext; // the context the movie is playing in
// filters for CI rendering
CIFilter *colorCorrectionFilter; // hue saturation brightness control through one CI filter
CIFilter *effectFilter; // zoom blur filter
CIFilter *compositeFilter; // composites the timecode over the video
CIContext *ciContext;
QTCaptureSession *mCaptureSession;
QTCaptureMovieFileOutput *mCaptureMovieFileOutput;
QTCaptureDeviceInput *mCaptureDeviceInput;
}
#end
In the examples I have seen through other code (e.g. Cocoa Video Tutorial) I have not seen any difference in their code to mine. If anyone would be able to point out as to how this error could have occurred that would be great.
Thanks heaps! :)
If you are compiling as a 64-bit application, QTVisualContextRef is not available to you. You'll need to compile the application as 32-bit.
Apple hasn't fully fleshed out QTKit to be 64-bit quite yet...
That's a GCC error and it means the token QTVisualContextRef is not known to the compiler. It's a rather poor error message indeed. You need to add the correct #import that will teach the compiler about this type. It's part of the QuickTime framework, so you probably want
#import <QuickTime/QuickTime.h>

Objective-C not recognizing .h?

I have the following in a project named testApp: (testAppViewController is the valid name of my view controller in the project)
PrevView.h
#import <UIKit/UIKit.h>
#import "testAppViewController.h"
#interface PrevView : UIView {
testAppViewController *viewController;
}
#property (nonatomic,retain) testAppViewController *viewController;
#end
When I build the project I'm getting the following error:
PrevView.h:13: error: expected specifier-qualifier-list before 'testAppViewController'
Am I missing something here? Any ideas?
Does "testAppViewController.h" import "PrevView.h"?
If so, you may want to delcare a forward class reference:
#class testAppViewController;
that replaces the import you have, and move the import into the .m file.
Usually when I see this type of error, it's a problem in the header file that you're trying to import. Check "testAppViewController.h"