XCode: Two targets, two main files? - objective-c

I'm working up a game in XCode, and I want to add a helper application that uses the main application's various classes to build the main application's data files.
Specifically:
The main application is a card game.
I want a helper app that uses the classes such as card.m while it creates the deck.xml files for the deck of custom cards the game uses.
My intuition is that the natural way to do this is to add a second compile target to the application, "Card Adder", to build this xml file. Unlike the main app, which is Cocoa Touch, I can make this one as a Shell application, to further make it quick & dirty.
Here's my hang up, and my question:
What kicks off as the main routine for this second target? Looking over my existing main.m file, I see it's only associated with the main game app. So far so good. But of course I can't add a second main.m file for the helper/shell app.
How do I get around this? What do I use in place of a main.m? How do I signal to the compile target "Card Adder" that this new file will contain it's main subroutine?

You may actually be able to have two main.m files. Put them in different folders on the file system. Add one to one target, and another to the other target.

It's not the name of the file, but the name/signature of the function
int main(int argc, char *argv[])
That matters. Just make a file with this function in it. You can have only one main per application.

Related

Entry point of an app in Objective-C

I started a new iOS project in Xcode. File-new-SingleViewApp
Then I selected the following files
and moved to the trash.
Then I removed the following keys from the Info.plist file:
Then I added a C file named main.c
The content of the main.c file is:
int main(int argc, char * argv[]) {
print("hello");
}
And surpirsingly this works, the app compiles and run and writes "hello" to console. My question is: Was not main.m (and not main.c) supossed to be the entry point of an app?
There is no rule about the filename or its suffix: only about the function name main. Your file can be written in C or Objective-C, so its suffix can be .c or .m. An Objective-C program, after all, is a C program; Objective-C is C.
However, notice that your app is now unable to use Cocoa for anything. It is, in effect, not an app. It never calls UIApplicationMain. It just runs its one line and quits. So it's kind of silly.
A more productive way to get started on what you're doing would be to use the macOS Command Line Tool template. Observe that you can choose to write it in C! What you have constructed is very like a C command-line tool (except that there are no iOS command-line tools).

How do I get the XCode Project URL programmatically?

I'm curious if there is a way to programmatically get the location of the .xcodeproj package within an Objective-C (or Swift) class contained within that package. I'd like to make a simple utility that puts files directly into the containing folder based on various app events, but I would rather avoid hard coding the path.
Essentially I want to create a target (and a reusable class) that builds swift files for NSManagedObject subclasses based on the Core Data model present in the app.
I found out the trick here is to add an item to your plist file that contains value ${PROJECT_DIR}, then you can get the location in your code with
var projectPath = NSBundle.mainBundle().infoDictionary.objectForKey("com.myapp.project_dir") as String
This assumes the plist key is "com.myapp.project_dir", of course.

XCode 4 Does not give output

I'm following the book of Programming in Objective-C by Stephen G. Kochan. I was trying the code and to improve the class example by myself. I opened a project in Mac OS X / Applications / Command Line Tool and the program executes successfully.
When I opened the project as IOS / Framework & Library / Cocoa Touch Static Library, XCode separates class and implementation files normally. When I try to compile, XCode says it has built successfully but there is no output in the console.
I just followed the book and I am sure there is nothing wrong about Class or the implementation files. "NSLog(#""); files stays in there". According to the book, files are separated by 3:
Interface Part (class part)
Implementation Part (Which instances located in)
int main (int argc, char *argv[]) part.
But when I open the project as cocoa-static library, I get only 1 *.m file. I cannot add any additional *.m file with add -> new file.
My question is, is there any relative problem with my file structure that I am working on? Should I need also separate implementation part and the main part?
I would really appreciate if someone could help with this probelem. I really got stuck and having struggling to proceed next step of the book because I can not try code examples anymore...
Sounds like you're trying to run a static library project. You can't do this - you need to make an app that uses your static library to be able to run at and see the output.

Unrecognized selector calling category method in static iOS library

I am using some third party software to aid in writing an iPad application using Xcode 4.3.2. The software is open source and is usually set up so its code will be compiled along with whatever code the developer writes for the application. Because I was using the software in numerous places, I decided to build it as a static library for the iOS simulator.
I was able to build the library, and convert one application to link to that library instead of compiling the original source code. However, when I go to run the application on the simulator, I get an error that says, unrecognized selector sent to instance.
I have verified that the program is successfully using portions of the static library. However, there is one piece of code that tries to call a method on an object, and that where the failure occurs. The method being called is not actually defined in the interface of that object. Rather it is provided in an additional module that defines a category for that object's class. The header file for that module is properly included and the compiler should have been able to find the category method and apply it to the object, yet at run time, the error mentioned above occurs.
I used the 'nm' command to verify that the category method exists in the static library. Here is an example of the output:
nm libStaticLibrary.a | grep categoryMethod
00000130 t -[SomeClass(Category) categoryMethod:]
0000354c s -[SomeClass(Category) categoryMethod:].eh
What ideas do people have about how this library can be made to work correctly with the desired application?
Your 3rd party framework is probable using a category on a existing (apple) class. But to load/find the category you need to add the -ObjC flag in the build settings under Other Linker Flags
Pfitz answer is great, but this will cause the compiler to load a bunch of unused binaries to your project which is not what you want. Please refer to this answer to know why https://stackoverflow.com/a/22264650/1363997
Here is the best solution:
1) select your project target from the left panel (the folders navigator)
2) select "Build Phases" tap
3) expand "Compile Sources" cell
4) hit the plus button at the bottom and then add your category's .m file
Done!
Note: you have to search for the file by navigating through the folder by your self, don't type the file's name in the search field

Is there a way to put the .h and .m file in a central location to use in any of my projects?

In one of my projects I have a class that has just some standard code that I use in most off the apps and I thought it would be useful to use this class in some other projects. Is there a way to put the .h and .m file in a central location to use in any of my projects? I could make changes to the class and would not have to worry about having to correct the files in multiple places.
For XCode 4.2 you could use a workspace, which can be comprised of multiple projects. Let's say you want to build a static lib. You can have a dedicated project for a lib, and include this project in multiple workspaces. You will need to properly setup project dependencies, so changes in your lib would be automatically picked up next time you build a product.
I found it was easier to save my .h & .m file in a folder called MyClasses, then drag both files in to the project I want to add them to. Xcode gives you the option to copy the files in to my project or leave them where they are. I left them in my MyClasses folder. I can now edited this class and all my changes show up in all the apps I have this class in.
Yes you can leave the files at a central location and add only refrences of the class to your project by dragging onto xcode into your project. Just do not copy files when xcode asks for it. Like we do for some third party libraries for ex. core-plot,facebook, Three20 etc.