Is Cocoa Programming for Mac OS X (3rd edition) outdated? [closed] - objective-c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
got a quick question for you (pretty much the title): is the book Cocoa Programming for Mac OS X (3rd Edition) outdated?
It's just that I read a little in it, until page 36 (in a .PDF ebook version) where I came across a problem. The chapter introduces you to Objective-C and Cocoa, and you already have to write a program by yourself. Exciting. But when he makes a class called Foo.h and Foo.m, my Xcode doesn't follow the guide.
His Interface Builder is different from my Interface Builder.
When he is about to make outlets and actions, I can't do it. They just won't show up.
I am sure I entered the correct info in my Foo.h file:
#import <Cocoa/Cocoa.h>
#interface Foo : NSObject {
IBOutlet NSTextField *textField;
}
-(IBAction)seed:(id)sender;
-(IBAction)generate:(id)sender;
#end
the Foo.m file:
#import "Foo.h"
#implementation Foo
#end
and I dragged them both to the "Class" folder,
but it still won't show them in IB.
Besides that, Xcode shows three warnings:
Incomplete implementation of class 'Foo'
Method definition for '-generate:' not found
Method definition for '-seed:' not found
This is why I think the book is outdated, but these are not errors, just warnings.
Here's some screenies:
This just made me think that the book might be outdated, and if I can use it all (if there are mistakes in every chapters).
Is it me that made a stupid mistake, or is the book really outdated?
Please help me out on this one, as I really want to learn Objective-C and Cocoa :)
Thank you.

No it's not outdated, you should just keep on reading and a few pages later you will find the instructions to write the definition of the generate: and seed: methods. The lack of that definition is what the compiler is complaining about.
From the "How to read this book" section: "Usually the help you seek will be only a paragraph or two away". ;-)

The book worked fine when I started building apps on Snow Leopard. A few things like "NIB" vs. "XIB" crop up, but the concepts are the same. Now on to your problem.
You won't see any connections in the Identity tab for your class when using a version of Interface Builder that is later than was used in the book. You want the connections tab for that.
Best I can tell from your screenshots, your class is in IB but the connections aren't listed. Are you actually referencing the correct class? Perhaps you have a few "foo.h" files floating around and grabbed the wrong one. Here's how to tell. Open the Library window in IB if it's not already open. In the search box at the bottom, type "foo".
In the pulldown that says "Inheritance", change it to "Definitions". You'll see something similar to this:
If it doesn't say "2 actions, and 1 outlet", you've got the wrong file (I know your file works because I pasted it in to write this up). Confirm the contents of the file that IB is using by clicking "foo.h". That will open the file in Xcode. Make sure it contains what you think it contains.

Yeah, I haven't read that book but Fernando offers sound advice. Read on, you haven't implemented the methods. If you just want to make the compiler happy, you could change the code to:
#import "Foo.h"
#implementation Foo
-(IBAction)seed:(id)sender {
}
-(IBAction)generate:(id)sender {
}
#end
But that doesn't do anything yet. :)

Related

Lexical or preprocessor error: file not found using box2d & cocos2d

I'm having this weird issue when building my project. The problem is as follows:
My friend and I are working on a project and we're exactly using the same xcode, cocos2d and box2d versions.
His project compiles (builds) fine while mine gives this error when I do:
cassert file not found.
I took a copy of his xcode.project but no problems whatsoever.
I hope this code summarizes better what I'm trying to say:
GameLayer.h
#import bla bla //the usual required files
#class myOwnClass1;
#class myOwnClass2;
myOwnClass1 *test1;
myOwnClass2 *test2;
Now I wanna include the GameLayer.h in either myOwnClass1.h or myOwnClass2.h using #import but it would give me the error!
If I did #class GameLayer; no problems at all.
The thing is in my friend's project he's doing the #import without the error, which is super weird (at least for me)
Advice?
P.S. I know that changing the .m to .mm would solve it but, again, in my friend's project he's using the .m
I guess there is a mismatch of compiler settings between your project and your friend's.
In short: cassert is a C++ header file; you definitely need a C++ compiler to compile it.
Now, my guess is that in your friend's project, the GameLayer.m file is marked as a C++ file, though it has got a .m extension.
To verify that, open your project's (and your friend's) project.pbxproj file in a text editor and look for the GameLayer.m file. You will get this kind of entry:
347F5D94158BA4840058BC21 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
as you see, the lastKnownFileType key says sourcecode.c.objc: this identifies an Objective-C file. If you see sourcecode.cpp.objcpp, that means objective c++.
Hope this helps clarifying it.
For some reason it turned out that creating a new project from scratch solved the problem, I'll mark this as the correct answer for now unless someone else has another opinion.
Here is how I fixed the issue. Cleaning up and recreating the project didn't seem to be a good idea for me.
There are a couple of answers on the web for this issue but they in each didn't help me solve the problem. One is on SO at
cassert file not found but i use Box2d template and the other is on cocos2d-iphone forum,
http://www.cocos2d-iphone.org/forums/topic/cannot-include-box2d-cassert-file-not-found-despite-every-file-being-mm/
Combining the two suggestions kind of worked for me -
Rename all YOUR (not cocos2d or box2d files, just your project files) from .m to .mm
Make sure that on each of the files, on the right pane, “Type” option is set to “Default – Objective C++ Source”
There was another issue for me specifically, may not be an issue for you, I was using the following signature for CCLabelTTF
CCLabelTTF *title = [CCLabelTTF labelWithString:#"Hello" dimensions:CGSizeMake(720.0f, 880.0f) alignment:UITextAlignmentLeft fontName:#"Arial" fontSize:34];
This is deprecated and caused errors all over the place. I am now using the following slightly modified version and the errors fixed -
CCLabelTTF *title = [CCLabelTTF labelWithString:#"Hello" dimensions:CGSizeMake(720.0f, 880.0f) hAlignment:kCCTextAlignmentRight fontName:#"Arial" fontSize:34];
My most recent writeup of this fix can be found at - http://indiangamer.com/how-i-fixed-the-cocos2d-box2d-include-file-not-found-error/

ViewController.h and ViewController.m Prefix

Okay so I have just started programming in Xcode 4.3. All of the books I use to practice coding in Xcode the Examples show the ViewController.h and ViewController.m take the name of the project name as their prefixes. For instance... If the book named the application "Calculator" , in the examples the View Controllers are both named "CalculatorViewController.h" & "CalculatorViewController.m". Am I doing something wrong here??
I apologize if this is a newbie question, but Ive tried doing almost everything to figure this out!
Please help me
When you add files into your project (class .h and .m files) there is not an automatic mechanism that prefixes these files for you, based on your product's name. You have to do it manually.
The reason you see that pattern in the books is because is a common practice to prefix your files with some initials so to namespace them and avoid conflicts when working with someone else's code (that's why Apple's classes are prefixed with an 'NS').
Xcode 4 even lets you choose that prefix when you create a new project, so if you type in your application name there (for example 'Calculator') the files that will be created initially for you by Xcode will be prefixed accordingly (so you'll get a CalculatorViewController for example), but for any other files that you add, you have to explicitly prefix them as you like. I hope that this makes sense.
UPDATE:

How do i interface my objc program with an objc++ library?

I have an objc program and i would like to use a widget that is written in objc++ (namely https://launchpad.net/scintilla-cocoa). How do i go about this? Basically i want a new window controller object to interface with this objc++ library to define a scintilla text editor widget. Simply creating a new 'objc class' and accessing the library from there generates a bunch of errors related to the C++ class keyword and so on.
Thanks in advance
Since I'm the one who put you into the (hopefully rewarding :-)) trouble of using Scintilla, here I am.
Let's say we create a ScintillaView subclass, named ppScintillaEditor.
The file should have an .mm extension (e.g. ppScintillaEditor.mm)
The code would be roughly like this...
Interface
#import "Scintilla/ScintillaView.h"
#interface ppScintillaEditor : ScintillaView
{
// your iVars
}
// your properties / methods / whatever
Now, as for the implementation part, remember to put some initialization method to set up the view properly (as in the example accompanying Scintilla-cocoa; I mean the Test project)
Sidenote : Of course, you can create subclasses, categories or whatever on top the ScintillaView class, pretty much based on what you need - I, for example, have create a separate Category just in order to group there some ScintillaView specific commands (sooner or later, you'll notice that for some more advanced Scintilla manipulations, although it's there, it may need some polishing to be a bit more cocoa-friendly, so here you go...)
Now, last but not least...
To resolve the "bunch of errors related to the C++ class keyword and so on", as I've shown in my other video-response to your comment, all you have to do is :
Go to your project's Build Settings
Under Apple LLVM Compiler 3.0 - Preprocessing
Option Preprocessor Macros
Add to both Debug and Release :
SCI_NAMESPACE SCI_LEXER
And that's it. :-)
Hint : The above are defined by Scintilla to avoid clashes between C and non-C elements, like above... so, all it takes is to notify the preprocessor and the rest is taken care of....
you would create an objc class which has the interface your app needs, then implement and add the ivars and implement -- all behind a compilation firewall so the objc++ sources are not included in the header. your implementation would provide any necessary conversions.
it is like you have already done, but you remove the scintilla headers from the header for your wrapper -- they are visible only to your wrapper's implementation.
Update
To illustrate one possible approach:
MONScintillaWrapper.h
// no c++/scintilla sources should be included in this header
#import <Foundation/Foundation.h>
#interface MONScintillaWrapper : NSObject
- (void)setBackgroundColor:(NSColor *)pColor;
#end
MONScintillaWrapper.mm
#import "MONScintillaWrapper.h"
#implementation MONScintillaWrapper
{
scintilla::t_thing scintillaThing;
}
- (void)setBackgroundColor:(NSColor *)pColor
{
...convert pColor to a scintilla color and pass that to scintillaThing...
}
#end

Doxygen and Objective-C Protocols

I'm using the Doxygen Wizard on the Mac (GUI for Doxygen 1.7.3).
I found out that If, in the header for my class, I #import a header file in which a protocol is defined, the first member of my class appears in the docs as pre-appended with the path to the class' header file, something like this:
(Doxygen HTML Output)
Protected Attributes:
Users [username] Desktop DirectoryName ClassName h NSString* myStringMember
(Further attributes display OK)
If I remove the #import, the problem goes away (But I need the protocol).
I read somewhere that Doxygen used to 'choke' on Obj-C protocols in the past, but that bug should be fixed by now. Anyone else experiencing something similar?
You may want to consider appledoc, its targeted at Cocoa developers and produces really good output.

Is there a key combination in Xcode to implement a Protocol?

In Visual Studio if I define a class to implement an interface e.g.
class MyObject : ISerializable {}
I am able to right click on ISerializable, select "Implement Interface" from the context menu and see the appropriate methods appear in my class definition.
class MyObject : ISerializable {
#region ISerializable Members
public void GetObjectData(SerializationInfo info,
StreamingContext context)
{
throw new NotImplementedException();
}
#endregion
}
Is there anything anything like this functionality available in Xcode on the Mac? I would like to be able to automatically implement Protocols in this way. Maybe with the optional methods generated but commented out.
XCode currently does not support that kind of automation. But: an easy way to get your code bootstrapped with a protocol is to option-click the protocol name in your class declaration
#interface FooAppDelegate : NSObject <NSApplicationDelegate,
NSTableViewDelegate> {
to quickly open the .h file defining the protocol. From there, copy and paste the methods you're interested in. Those headers tend to be well-commented, which helps in determining which methods you can safely ignore.
I have not seen that feature in Xcode.
But it seems like someone could write a new user script called "Place Implementor Defs on Clipboard" that sits inside of Scripts > Code.
You did not find this useful.
There is not currently such a refactoring in Xcode.
If you'd like it, please file an enhancement request.
I know this thread s a bit old, but I wondered the same thing and found this question.
In my case, I'm defining a property in the interface (.h) and I want to synthesize it in the implementation (.m). I also need to implement methods defined in the interface. Yes, Xcode helps as others have mentioned, but modern IDEs offer these productivity enhancements for things we do frequently. It appears that this is still not a feature in Xcode 4.3.3. However, the feature is available in JetBrains' AppCode. I'm only dabbling with the trial, but it appears to only be possible one property or method at a time, not the whole interface like Visual Studio.
Xcode can help you per protocol method, lets say you have a protocol like this:
#protocol PosterousWebsitesDelegate <NSObject>
- (void)PosterousWebsitesLoadSuccess:(PosterousWebsites*)websites;
#end
in the #implementation section of your .m file you can start writing the name of the method and pressing ESC key to autocomplete the signature of the method/selector:
-(void)Poste (...press ESC...)
Xcode will autocomplete a full signature of the #protocol method, pres TAB to confirm the code.
If you are really committing to learn OSX/iOS Development, I would recommend you to read "XCode 3 Unleashed", a book that really helped me to know Xcode as deep as I know VS :)
check this plugin
https://github.com/music4kid/FastStub-Xcode
it does the thing that you are asking for and more.
Macrumors had a discussion on this too. There is a link to some apple scripts. I haven't actually tried these.