Adding a class in objective-c - objective-c

I'm new to Xcode and I'm trying to understand how things work, studying from books, reading tutorials etc.. and I got a minor problem
when I create a new project using " Command Line Tool" if I manually create the class interface, implementation and then write the codes to the main it works perfectly
however, as you know when a project is created through CommandLineTool it only provides main.m
I click on the file -> add new file and select objective-c class, name the class and then it provides me classname.m and classname.h and when I write the codes they don't work, the main somehow doesn't see the other files I mean main and class.h and class.m are not connected I think because when I start writing
classname *newclassname= [[classname alloc] init];
the classname doesn't show up so any suggestions what am I doing wrong?
I am sorry for my bad english and thanks in advance

Objective-C is case sensitive so take care when writing classname or Classname, check that for all the code. Also the convention is to use Uppercase for class names and lowercase for variables and instances. Variables are usually written with camelCase so newclassname will be newClassname:
Classname *newClassname= [[Classname alloc] init];

Seems like you need this one:
#import "classname.h"

Related

Compile time check for valid file references in Xcode

Is it possible to force the Xcode complier to verify that files referenced in code are valid?
There are multiple points in Cocoa development when you naturally reference a file programmatically via an NSString:
[UINib nibWithNibName:#"MyNib" bundle:nil];
[UIImage imageNamed:#"MyImage"];
[[UIViewController alloc] initWithNibName:#"MyNib" bundle:nil];
Is there any way at compile time to check is these file references are valid?
Often times after using above methods, I end up changing the name of the referenced file but forget to change the name in code. Everything complies without a problem and it is only when you happen to go to the portion of the app that accesses this file that the bug will reveal itself.
Is there another approach or technique that people use to avoid this sort of error?
Referencing a file name via a string feels very fragile.
Warning: This answer is mostly outdated. The general idea is fine but better solutions exist now (e.g. Image assets with a SwiftGen script to generate an enum).
Nibs usually have a class with the same name as the file, e.g.
[[MyViewController alloc] initWithNibName:NSStringFromClassName([MyViewController class]) bundle:nil];
I usually hide it into the controller's init method as [self class].
For image loading, compile-time checks are difficult. Help yourself with macros, first replace the loading method by a simple macro, e.g.
#define LOAD_IMAGE(__IMAGE_NAME__) [UIImage imageNamed:__IMAGE_NAME__]
First thing you should do is to put an assert into this macro and always check that the image was successfully loaded. It's not a compile-time check but it helps to find missing resources.
The second thing is to write a ruby/python/shell/(any scripting language) script that will search your source files for LOAD_IMAGE and check if the file (between parenthesis) exists. As a shell script, it will be very simple (e.g. using grep). You can add this script into your xcode project to be run when compiling.
Don't forget to check images referenced by xibs.
However, often you have to create the image name dynamically, e.g. NSString* imageName = [NSString stringWithFormat:#"image_%i", index]. There's no way how you can check this at compile time.
Also don't forget to do the reverse check - don't include image files which are not used anywhere.
AutoComplete for [UIImage imageNamed:] by Kent Sutherland.
This provides code completion support within Xcode - a brilliant piece of code. This is working for me in Xcode 4.6:
Currently this project does not have support for strings other than imageNamed:. To support those, I will try to write a compile time script. Or maybe I will become bold and try to extend Mr. Sutherland's spectacular work.
Xcode doesn't support this, but if this problem is really biting you then you could use the following hack:
Give every in-bundle file a unique prefix (e.g. app__)
When you add a file to your project, make sure you first rename it to add this prefix.
Your compile time (pre-distribution) check then has two parts: 1) Search through all .m files and enumerate strings that begin with the prefix. You shouldn't have to check if the string is quoted since your prefix is unique. 2) grep project.pbxproj for each string to check if it is included in the bundle.
With some effort, this process can be mostly automated and also optimized, but the above recipe ought to work.
here is a bash script that we use that lists all images on disk but NOT referenced in code.
https://gist.github.com/3750087
it would likely be easy to reverse this to check for non-exting images and xibs.
Anyways, the script should be a good starting point

Customize static libraries

I've created a XCode projet that contains 2 targets and static library that I implement in both targets. Some of the classes of my static library needs to be slightly different depending on the target I compile.
I do not have any idea how to do it properly.
Any idea?
Thanks
In what way to they need to be different?
(I am basing my answer on a guess that it can be handled by setting some sort of state-variable in the classes or by a custom init method)
I would suggest you create some form of custom init methods or instance variables that you set for the classes that need to have different behaviors. You can then use User defined setting in your build settings for each target.
Check this question & answer for more information: iphone: get User Defined variable in Target's setting by code?
Basicly you could have a setting that would be a string like so: "Standard", you fetch it from the
FooBarClass.h
typedef enum { FooBarSettingNormal, FooBarSettingFast } FooBarSetting;
-(id)initWithSetting:(FooBarSetting)setting;
And then fetch the variable set in buildsetting from the code and init the FooBar object like so:
SomeViewController.m
NSNumber* fooBarSetting = [[[NSBundle mainBundle] infoDictionary] valueForKey:#"FooBarSetting"];
FooBar * baz = [[FooBar alloc] initWithSetting:[fooBarSetting intValue]];
This enables you to have different behavior in your classes and keeping the static library separate and stand alone from the project you are using.
I hope you find this somewhat helpful :)

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

Xcode can't find headers in given framework

Messing round a little in Xcode, and I was trying to get my app to look at the users music library with the use of MPMediaPickerController.
Following Apples documentation, I added the MediaPlayer.framework to the project, and in my header I've imported , giving me something like this:
#import <GameKit/GameKit.h>
#import <MediaPlayer/MediaPlayer.h>
#interface HelloMusic : UIViewController
{
}
So far so simple. Now, as far as I'm aware I should be able to do
MPMediaPickerController *mp = [[MPMediaPickerController alloc] init];
in my main file and set about launching my picker. Unfortunately XCode stubbronly refuses to admit that there is such a thing as an MPMediaPickerController - if I type MP and hit escape to get code complations I am without any of the MPMedia family. Annoyingly Xcode does recognise any MPMovie... class (from the same framework!). If I try and run the app it compiles fine so it must at least recognise the header from the framework, then chunters along until I get to the assignment of MPMediaPickerController, at which point I get an EXC_BAD_ACCESS, with a console output of
Detected an attempt to call a symbol in system libraries that is not present on the iPhone:
pthread_mutexattr_destroy$UNIX2003 called from function _ZN4llvm3sys5MutexC2Eb in image
libLLVMContainer.dylib.
I'm... certain I'm doing something beyond stupid, but I'm stuck nevertheless.
As the class reference states, it's declared in MPMediaPickerController.h. As such, simply adding...
#import <MediaPlayer/MPMediaPickerController.h>
...should solve your problems. :-)