Entry point of an app in Objective-C - 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).

Related

Detect Xcode project development language

We can create a new Xcode project using Objective-C or Swift.
I want to detect, which language was selected when a project was created?
Projects can be a mix of Objective-C and Swift, but I am concerned about the language, selected during project creation.
May be it can be through pbxproj file or other better way.
Thanks.
ObjC project always contains the entry point that is main function.
Usually it is inside main.m file but it is not necessary. Developer can replace it to any name.
I tried 2 simple projects. One is in ObjC and second one is in Swift.
When I was tried to add new file the Xcode offered Swift language for Swift project and Obj-C for Obj-C project file.
Next I removed in Swift project AppDelegate.swift file and added AppDelegate.h and AppDelegate.m and (sic!) main.m files. of course I had to create bridging file for obj-c.
Which contains
#import "AppDelegate.h"
I was able to compile this project but when I tried to add new file Xcode offered me to add Objective-C file. But initially the project was created as Swift project.
I did similar manipulation for Obj-C project.
I removed AppDelegate.h and .m file as well as main.m and added AppDelegate.swift
I was asked to create bridge file and did empty file.
Next I went to «Build Settings» and switched Define Module parameter to YES value. (Without this I got linker error).
After it I was able to build and run this initially obj-c project which has AppDelegate in Swift now.
When I tried to add a new file the Xcode offered me to add new Obj-C file too.
So. It looks like you cannot detect initial language based on a parameter in Xcode because project can be always corrected. I think that rarely the developer will try to replace AppDelegate in a project and add\remove main entry point.
Hope this helps you.

What is the entry point of swift code execution?

There is no main() method in swift. The program must start the execution from somewhere. So what is the entry point of swift code execution and how is it decided?
The entry point in a plain Swift module is the file in the module called main.swift. main.swift is the only file which is allowed to have expressions and statements at the top level (all other Swift files in the module can only contain declarations).
Cocoa Touch uses the #UIApplicationMain attribute on an implementation of UIApplicationDelegate instead of a main.swift file to mark the entry point. Cocoa used to use a minimal main.swift file which simply called NSApplicationMain, but as of Xcode 6.1 uses the #NSApplicationMain attribute on an implementation of NSApplicationDelegate.
In the AppDelegate.swift file you can see #UIApplicationMain.
The AppDelegate is the initial entry file.
Basically: main.m and AppDelegate.m are kinda merged in Swift to just AppDelegate.swift
You may want to read Files and Initialization
The exception is a special file named “main.swift”, which behaves much
like a playground file, but is built with your app’s source code. The
“main.swift” file can contain top-level code, and the order-dependent
rules apply as well. In effect, the first line of code to run in
“main.swift” is implicitly defined as the main entrypoint for the
program. This allows the minimal Swift program to be a single line —
as long as that line is in “main.swift”.
In Xcode, Mac templates default to including a “main.swift” file, but
for iOS apps the default for new iOS project templates is to add
#UIApplicationMain to a regular Swift file. This causes the compiler
to synthesize a main entry point for your iOS app, and eliminates the
need for a “main.swift” file.
Alternatively, you can link in an implementation of main written in
Objective-C, common when incrementally migrating projects from
Objective-C to Swift.
In Swift 5.3 there is a new #main attribute which lets you control where your entry point is in your project rather than just main.swift. There can only be one main entry and you can't have a main.swift file and a an attribute #main. See https://github.com/apple/swift-evolution/blob/master/proposals/0281-main-attribute.md for more details.
#main
struct App {
static func main() {
print("Starting.")
}
}
In Swift apps there are attributes:
#UIApplicationMain (Cocoa Touch)
#NSApplicationMain (Cocoa)
that tell the swift compiler where is the entry point of the application.
What swift compiler does under the hood is that it creates a main function, which basically looks the same as in Objective-C apps and treats this method as the app's entry point (a first method that is called when the application process is started).
If you want to read more about what swift compiler does with Main attributes, how the OS knows where is the entry point of the application, I encourage you to read this article: Understanding iOS app entry point
The entry point in a plain Swift module is the file in the module called.

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.

Why do I get the error "error: unknown type name 'virtual'" when trying to compile this code?

Code:
struct IRenderingEngine {
virtual void Initialize(int width, int height) = 0;
virtual void Render() const = 0;
virtual void UpdateAnimation(float timeStep) = 0;
virtual void OnRotate(DeviceOrientation newOrientation) = 0;
virtual ~IRenderingEngine() {}
};
Learning opengles from a book for 3d iphone programming and it uses this example code but the book is targeted for xcode 3.x
Somehow I feel like its something with xcode 4....
EDIT:
Heres the actual error:
/Users/Dan/Documents/opengles/Hello Arrow/Hello Arrow/IRenderingEngine.hpp:27:2: error: unknown type name 'virtual' [1]
And that legitamtely is all that it takes to fail to compile, absolutely no other files. (Yes I've tried compiling with literally a main.m and this hpp file)
It is recognizing the hpp file as a cpp header file though, if I try to add it to the compiled files it says that "no rule to process file '$(PROJECT_DIR)/Hello Arrow/IRenderingEngine.hpp' of type sourcecode.cpp.h for architecture i386" so I really have no idea what is going on
Note that I compiled with main.m meaning I compiled another Cocoa/Foundation based application
I tried compiling for a c++ application and everything worked out just fine....
Similarly compiling with a main.mm test file worked fine too
heres the actual project, lemme know how insane I really am:
[Removed considering I lost the file]
Please rename the main.m to main.mm. This worked for me.
If you're using Xcode 4, try changing the name of file "AppDelegate.m" to "AppDelegate.mm". It works for me.
Changing the name of file "AppDelegate.m" to "AppDelegate.mm". It's correct!
I moved the #import "IRenderingEngine.hpp" line from the GLView.h file to the GLView.mm - this prevented it from being imported into the main.m and HelloArrowAppDelegate.m files when they were compiled - and restricted the import into the .mm file, that could handle the C++.
I also had to make a couple of other fixes for bugs I'd introduced when typing in the code - so apologies if that wasn't the only thing that needed to be done, but it might help those with similar problems!
if you call C++ files ( even if you only import them ) you need to change the .m file that call's it to .mm
This is just a stupid guess since I've never tried compiling something with the word virtual in a C compiler... but is there any chance that you were trying to compile this C++ code as C code? That's the only reason I can think of that a compiler wouldn't understand the keyword virtual.
The header <stdlib.h> is not the right one to use in a C++ program. When I replaced it with the c++ version of C's stdio library <cstdlib> then your code compiled for me.

XCode: Two targets, two main files?

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.